Compare commits

..

No commits in common. "c38093b55bcfac8a89daa75911697d604a89cf55" and "9db5c04cb6eaf58f8aa657ed4e1421dec1cc2ad9" have entirely different histories.

4 changed files with 13 additions and 58 deletions

12
API.md
View File

@ -27,7 +27,7 @@ The verification request was sent.
##### 400 - Error: Bad Request ##### 400 - Error: Bad Request
The request was malformed. The request was malformed.
##### 403 - Error: Forbidden ##### 403 - Error: Forbidden
Blocked for security reasons. The password is not matching the requirements.
##### 409 - Error: Conflict ##### 409 - Error: Conflict
The requested username or email is already taken. The requested username or email is already taken.
@ -58,8 +58,6 @@ The account was verified. You can login now.
##### 400 - Error: Bad Request ##### 400 - Error: Bad Request
The request was malformed. The request was malformed.
##### 403 - Error: Forbidden ##### 403 - Error: Forbidden
Blocked for security reasons.
##### 404 - Error: Forbidden
The provided token is unknown. The provided token is unknown.
### `/account/authenticate` - POST ### `/account/authenticate` - POST
@ -87,10 +85,8 @@ __Content - JSON:__
##### 400 - Error: Bad Request ##### 400 - Error: Bad Request
The request was malformed. The request was malformed.
##### 401 - Error: Unauthorized
The provided password was wrong.
##### 403 - Error: Forbidden ##### 403 - Error: Forbidden
Blocked for security reasons. The provided password was wrong.
##### 404 - Error: Not Found ##### 404 - Error: Not Found
The provided username was not found. The provided username was not found.
@ -106,6 +102,4 @@ Deletes the account.
##### 200 - Success ##### 200 - Success
The account was deleted. The account was deleted.
##### 401 - Error: Unauthorized ##### 401 - Error: Unauthorized
The provided token doesn't allow you to perform this operation. The provided token doesn't allow you to perform this operation.
##### 403 - Error: Forbidden
Blocked for security reasons.

View File

@ -12,9 +12,9 @@ async fn register(
match handlers::register(body.into_inner()).await { match handlers::register(body.into_inner()).await {
Ok(resp) => match resp { Ok(resp) => match resp {
data::RegisterResponse::Success => HttpResponse::Ok().finish(), data::RegisterResponse::Success => HttpResponse::Ok().finish(),
data::RegisterResponse::PasswordTooWeak => HttpResponse::Forbidden().finish(),
data::RegisterResponse::Conflict(b) => HttpResponse::Conflict().json(web::Json(b)), data::RegisterResponse::Conflict(b) => HttpResponse::Conflict().json(web::Json(b)),
data::RegisterResponse::MalformedEmail => HttpResponse::UnprocessableEntity().finish(), data::RegisterResponse::MalformedEmail => HttpResponse::UnprocessableEntity().finish(),
data::RegisterResponse::Blocked => HttpResponse::Forbidden().finish(),
}, },
Err(e) => { Err(e) => {
error!("While handling register request: {e}"); error!("While handling register request: {e}");
@ -28,8 +28,7 @@ async fn verify(data: web::Data<ApiState>, body: web::Json<data::VerifyRequest>)
match handlers::verify(body.into_inner()).await { match handlers::verify(body.into_inner()).await {
Ok(resp) => match resp { Ok(resp) => match resp {
data::VerifyResponse::Success => HttpResponse::Ok().finish(), data::VerifyResponse::Success => HttpResponse::Ok().finish(),
data::VerifyResponse::TokenUnknown => HttpResponse::NotFound().finish(), data::VerifyResponse::TokenUnknown => HttpResponse::Forbidden().finish(),
data::VerifyResponse::Blocked => HttpResponse::Forbidden().finish(),
}, },
Err(e) => { Err(e) => {
error!("While handling verify request: {e}"); error!("While handling verify request: {e}");
@ -46,9 +45,8 @@ async fn authenticate(
match handlers::authenticate(body.into_inner()).await { match handlers::authenticate(body.into_inner()).await {
Ok(resp) => match resp { Ok(resp) => match resp {
data::AuthenticateResponse::Success(b) => HttpResponse::Ok().json(web::Json(b)), data::AuthenticateResponse::Success(b) => HttpResponse::Ok().json(web::Json(b)),
data::AuthenticateResponse::WrongPassword => HttpResponse::Unauthorized().finish(), data::AuthenticateResponse::WrongPassword => HttpResponse::Forbidden().finish(),
data::AuthenticateResponse::UserNotFound => HttpResponse::NotFound().finish(), data::AuthenticateResponse::UserNotFound => HttpResponse::NotFound().finish(),
data::AuthenticateResponse::Blocked => HttpResponse::Forbidden().finish(),
}, },
Err(e) => { Err(e) => {
error!("While handling authenticate request: {e}"); error!("While handling authenticate request: {e}");
@ -63,7 +61,6 @@ async fn delete(data: web::Data<ApiState>, auth: BearerAuth) -> impl Responder {
Ok(resp) => match resp { Ok(resp) => match resp {
data::DeleteResponse::Success => HttpResponse::Ok().finish(), data::DeleteResponse::Success => HttpResponse::Ok().finish(),
data::DeleteResponse::Unauthorized => HttpResponse::Unauthorized().finish(), data::DeleteResponse::Unauthorized => HttpResponse::Unauthorized().finish(),
data::DeleteResponse::Blocked => HttpResponse::Forbidden().finish(),
}, },
Err(e) => { Err(e) => {
error!("While handling delete request: {e}"); error!("While handling delete request: {e}");

View File

@ -2,9 +2,9 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct RegisterRequest { pub struct RegisterRequest {
pub username: String, username: String,
pub password: String, password: String,
pub email: String, email: String,
} }
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
@ -17,27 +17,26 @@ pub enum RegisterConflict {
#[derive(Debug)] #[derive(Debug)]
pub enum RegisterResponse { pub enum RegisterResponse {
Success, Success,
PasswordTooWeak,
Conflict(RegisterConflict), Conflict(RegisterConflict),
MalformedEmail, MalformedEmail,
Blocked,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct VerifyRequest { pub struct VerifyRequest {
pub token: String, token: String,
} }
#[derive(Debug)] #[derive(Debug)]
pub enum VerifyResponse { pub enum VerifyResponse {
Success, Success,
Blocked,
TokenUnknown, TokenUnknown,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct AuthenticateRequest { pub struct AuthenticateRequest {
pub username: String, username: String,
pub password: String, password: String,
} }
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
@ -50,12 +49,10 @@ pub enum AuthenticateResponse {
Success(AuthenticateSuccess), Success(AuthenticateSuccess),
WrongPassword, WrongPassword,
UserNotFound, UserNotFound,
Blocked,
} }
#[derive(Debug)] #[derive(Debug)]
pub enum DeleteResponse { pub enum DeleteResponse {
Success, Success,
Blocked,
Unauthorized, Unauthorized,
} }

View File

@ -2,46 +2,17 @@ use crate::api::account::data;
use anyhow::Result; use anyhow::Result;
use log::info; use log::info;
fn is_sql_injection(string: &String) -> bool {
match libinjection::sqli(string) {
Some((is_injection, _)) => is_injection,
None => true, // this could be a false positive, but that would be better than an SQLi
}
}
trait AlphaExt {
fn is_alpha(&self) -> bool;
}
impl AlphaExt for String {
fn is_alpha(&self) -> bool {
self.chars().all(|c| c.is_alphanumeric())
}
}
pub async fn register(request: data::RegisterRequest) -> Result<data::RegisterResponse> { pub async fn register(request: data::RegisterRequest) -> Result<data::RegisterResponse> {
if is_sql_injection(&request.username) || is_sql_injection(&request.email) {
return Ok(data::RegisterResponse::Blocked);
}
Ok(data::RegisterResponse::Success) Ok(data::RegisterResponse::Success)
} }
pub async fn verify(request: data::VerifyRequest) -> Result<data::VerifyResponse> { pub async fn verify(request: data::VerifyRequest) -> Result<data::VerifyResponse> {
if !request.token.is_alpha() {
return Ok(data::VerifyResponse::Blocked);
}
Ok(data::VerifyResponse::Success) Ok(data::VerifyResponse::Success)
} }
pub async fn authenticate( pub async fn authenticate(
request: data::AuthenticateRequest, request: data::AuthenticateRequest,
) -> Result<data::AuthenticateResponse> { ) -> Result<data::AuthenticateResponse> {
if is_sql_injection(&request.username) {
return Ok(data::AuthenticateResponse::Blocked);
}
Ok(data::AuthenticateResponse::Success( Ok(data::AuthenticateResponse::Success(
data::AuthenticateSuccess { data::AuthenticateSuccess {
token: "not_a_valid_token".to_string(), token: "not_a_valid_token".to_string(),
@ -50,10 +21,6 @@ pub async fn authenticate(
} }
pub async fn delete(token: String) -> Result<data::DeleteResponse> { pub async fn delete(token: String) -> Result<data::DeleteResponse> {
if !token.is_alpha() {
return Ok(data::DeleteResponse::Blocked);
}
info!("Token: {}", token); info!("Token: {}", token);
Ok(data::DeleteResponse::Success) Ok(data::DeleteResponse::Success)
} }