random tokens

This commit is contained in:
Brandon Thomas committed 2021-05-17 02:00:31 -04:00
1 parent d0a5959e3c
commit 47ead0febf
5 files changed
+105 -53

No files matched your search

+1 -1
View File
@@ -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,
+72 -52
View File
@@ -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,
};
+1
View File
@@ -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;
+1
View File
@@ -0,0 +1 @@
pub mod random;
+30
View File
@@ -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);
}
}