mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-03 00:47:53 +00:00
random tokens
This commit is contained in:
1 parent
d0a5959e3c
commit
47ead0febf
5 files changed
+105
-53
No files matched your search
@@ -56,7 +56,7 @@ CREATE TABLE users (
|
||||
) NOT NULL DEFAULT 'light-mode',
|
||||
|
||||
-- An uploaded avatar. Public hash in our bucket.
|
||||
avatar_public_bucket_hash CHAR(32) NOT NULL UNIQUE,
|
||||
avatar_public_bucket_hash CHAR(32) NOT NULL,
|
||||
|
||||
-- If the user doesn't want to use gravatar and doesn't have an uploaded avatar.
|
||||
disable_gravatar BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
use actix_web::{Responder, web, HttpResponse, error};
|
||||
use derive_more::{Display, Error};
|
||||
use actix_web::dev::HttpResponseBuilder;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_http::http::header;
|
||||
use actix_http::Error;
|
||||
use actix_http::http::header;
|
||||
use actix_web::dev::HttpResponseBuilder;
|
||||
use actix_web::error::ResponseError;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::{Responder, web, HttpResponse, error};
|
||||
use crate::endpoints::users::create_account::CreateAccountError::BadInput;
|
||||
use derive_more::{Display, Error};
|
||||
use log::{info, warn, log};
|
||||
use crate::server_state::ServerState;
|
||||
|
||||
const NEW_USER_ROLE: &'static str = "new-user";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CreateAccountRequest {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
pub password_confirmation: String,
|
||||
pub email_address: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct CreateAccountResponse {
|
||||
pub struct CreateAccountSuccessResponse {
|
||||
pub success: bool,
|
||||
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -26,35 +30,29 @@ pub struct ErrorResponse {
|
||||
pub error_reason: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Display, Error)]
|
||||
pub enum CreateAccountResponseError {
|
||||
#[display(fmt = "internal error")]
|
||||
InternalError,
|
||||
|
||||
#[display(fmt = "bad request")]
|
||||
BadClientData,
|
||||
|
||||
#[display(fmt = "timeout")]
|
||||
Timeout,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Display)]
|
||||
pub enum CreateAccountError {
|
||||
BadInput(String),
|
||||
ServerError,
|
||||
}
|
||||
|
||||
impl ResponseError for CreateAccountError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match *self {
|
||||
CreateAccountError::BadInput(_) => StatusCode::BAD_REQUEST,
|
||||
CreateAccountError::ServerError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
|
||||
fn error_response(&self) -> HttpResponse {
|
||||
let error_reason = match self {
|
||||
BadInput(reason) => reason.to_string(),
|
||||
CreateAccountError::ServerError => "server error".to_string(),
|
||||
};
|
||||
|
||||
let response = ErrorResponse {
|
||||
success: false,
|
||||
error_reason: "there was a problem".to_string()
|
||||
error_reason,
|
||||
};
|
||||
|
||||
let body = match serde_json::to_string(&response) {
|
||||
@@ -68,47 +66,69 @@ impl ResponseError for CreateAccountError {
|
||||
}
|
||||
}
|
||||
|
||||
impl ResponseError for CreateAccountResponseError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match *self {
|
||||
CreateAccountResponseError::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
CreateAccountResponseError::BadClientData => StatusCode::BAD_REQUEST,
|
||||
CreateAccountResponseError::Timeout => StatusCode::GATEWAY_TIMEOUT,
|
||||
}
|
||||
}
|
||||
|
||||
fn error_response(&self) -> HttpResponse {
|
||||
HttpResponseBuilder::new(self.status_code())
|
||||
.set_header(header::CONTENT_TYPE, "text/html; charset=utf-8")
|
||||
.body(self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn create_account_handler(request: web::Json<CreateAccountRequest>)
|
||||
-> Result<HttpResponse, CreateAccountError>
|
||||
pub async fn create_account_handler(
|
||||
request: web::Json<CreateAccountRequest>,
|
||||
server_state: web::Data<ServerState>) -> Result<HttpResponse, CreateAccountError>
|
||||
{
|
||||
if request.username.len() < 3 {
|
||||
return Err(CreateAccountError::BadInput("username is too short".to_string()));
|
||||
}
|
||||
|
||||
/*let record_id = sqlx::query!(
|
||||
if request.password.len() < 6 {
|
||||
return Err(CreateAccountError::BadInput("password is too short".to_string()));
|
||||
}
|
||||
|
||||
if request.password != request.password_confirmation {
|
||||
return Err(CreateAccountError::BadInput("passwords do not match".to_string()));
|
||||
}
|
||||
|
||||
if !request.email_address.contains("@") {
|
||||
return Err(CreateAccountError::BadInput("invalid email address".to_string()));
|
||||
}
|
||||
|
||||
let token = "token";
|
||||
let password_hash = "temp";
|
||||
let profile_markdown = "";
|
||||
let profile_rendered_html = "";
|
||||
let ip_address = "1.1.1.1";
|
||||
|
||||
let record_id = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO badges ( slug, title, description, image_url )
|
||||
VALUES ( ?, ?, ?, ? )
|
||||
INSERT INTO users (
|
||||
token,
|
||||
username,
|
||||
display_name,
|
||||
email_address,
|
||||
profile_markdown,
|
||||
profile_rendered_html,
|
||||
user_role_slug,
|
||||
password_hash,
|
||||
ip_address_creation,
|
||||
ip_address_last_login,
|
||||
ip_address_last_update
|
||||
)
|
||||
VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
|
||||
"#,
|
||||
self.slug,
|
||||
self.title,
|
||||
self.description,
|
||||
self.image_url,
|
||||
token.to_string(),
|
||||
request.username.to_string(),
|
||||
request.username.to_string(),
|
||||
request.email_address.to_string(),
|
||||
profile_markdown,
|
||||
profile_rendered_html,
|
||||
NEW_USER_ROLE,
|
||||
password_hash,
|
||||
ip_address.to_string(),
|
||||
ip_address.to_string(),
|
||||
ip_address.to_string(),
|
||||
)
|
||||
.execute(pool)
|
||||
.await?
|
||||
.execute(&server_state.mysql_pool)
|
||||
.await
|
||||
.map_err(|_| CreateAccountError::ServerError)?
|
||||
.last_insert_id();
|
||||
|
||||
Ok(record_id)*/
|
||||
|
||||
info!("new user id: {}", record_id);
|
||||
|
||||
//Ok(record_id)
|
||||
/*Ok(web::Json())*/
|
||||
|
||||
if true {
|
||||
@@ -118,7 +138,7 @@ VALUES ( ?, ?, ?, ? )
|
||||
|
||||
// .map_err(error::ErrorInternalServerError)?;
|
||||
// error::ErrorBadRequest(msg)
|
||||
let response = CreateAccountResponse {
|
||||
let response = CreateAccountSuccessResponse {
|
||||
success: true,
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
pub mod server_state;
|
||||
pub mod endpoints;
|
||||
pub mod queries;
|
||||
pub mod util;
|
||||
|
||||
use actix_cors::Cors;
|
||||
use actix_http::http;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pub mod random;
|
||||
@@ -0,0 +1,30 @@
|
||||
use rand::Rng;
|
||||
|
||||
// Crockford characters
|
||||
const CROCKFORD_CHARSET: &[u8] = b"0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
||||
|
||||
pub fn random_token(length: usize) -> String {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let token: String = (0..length)
|
||||
.map(|_| {
|
||||
let idx = rng.gen_range(0..CROCKFORD_CHARSET.len());
|
||||
CROCKFORD_CHARSET[idx] as char
|
||||
})
|
||||
.collect();
|
||||
|
||||
token
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::util::random::random_token;
|
||||
|
||||
#[test]
|
||||
fn random_token_length() {
|
||||
assert_eq!(random_token(0), "".to_string());
|
||||
assert_eq!(random_token(1).len(), 1);
|
||||
assert_eq!(random_token(10).len(), 10);
|
||||
assert_eq!(random_token(32).len(), 32);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user