Skip to content

Commit

Permalink
general cleanup and maintenance (#362)
Browse files Browse the repository at this point in the history
* general cleanup and maintenance

changed `StatusCode` from `i31` to `u16`.

refactored logic

expanded documentation

added TODOs

made some functions more generic (to improve API w/o causing breaking changes)

* fmt fix
  • Loading branch information
AnthonyMichaelTDM authored May 2, 2024
1 parent 3d08fef commit 500c06d
Show file tree
Hide file tree
Showing 49 changed files with 1,563 additions and 1,257 deletions.
526 changes: 263 additions & 263 deletions create-rust-app/src/auth/controller.rs

Large diffs are not rendered by default.

70 changes: 35 additions & 35 deletions create-rust-app/src/auth/endpoints/service_actixweb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ async fn sessions(
match result {
Ok(sessions) => Ok(HttpResponse::Ok().json(sessions)),
Err((status_code, error_message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": error_message }).to_string())),
}
Expand Down Expand Up @@ -92,11 +92,11 @@ async fn destroy_session(
web::block(move || controller::destroy_session(&db, &auth, item_id.into_inner())).await?;

match result {
Ok(_) => Ok(
Ok(()) => Ok(
HttpResponse::build(StatusCode::OK).body(json!({"message": "Deleted."}).to_string())
),
Err((status_code, error_message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": error_message }).to_string())),
}
Expand All @@ -123,11 +123,11 @@ async fn destroy_sessions(db: Data<Database>, auth: Auth) -> Result<HttpResponse
let result = web::block(move || controller::destroy_sessions(&db, &auth)).await?;

match result {
Ok(_) => Ok(
Ok(()) => Ok(
HttpResponse::build(StatusCode::OK).body(json!({"message": "Deleted."}).to_string())
),
Err((status_code, error_message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": error_message }).to_string())),
}
Expand Down Expand Up @@ -166,7 +166,7 @@ async fn login(db: Data<Database>, Json(item): Json<LoginInput>) -> Result<HttpR
)
.body(json!({ "access_token": access_token }).to_string())),
Err((status_code, message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": message }).to_string())),
}
Expand All @@ -190,22 +190,17 @@ async fn oidc_login_redirect(
)
.await;

if result.is_err() {
return Ok(HttpResponse::InternalServerError().finish());
}

let result = result.unwrap();

match result {
Some(url) => {
Ok(Some(url)) => {
let mut response = HttpResponse::SeeOther().body(());
response
.headers_mut()
.append(LOCATION, HeaderValue::from_str(url.as_str()).unwrap());

Ok(response)
}
None => Ok(HttpResponse::NotImplemented().finish()),
Ok(None) => Ok(HttpResponse::NotImplemented().finish()),
Err(_) => Ok(HttpResponse::InternalServerError().finish()),
}
}

Expand All @@ -219,6 +214,7 @@ pub struct OIDCLoginQueryParams {

#[cfg(feature = "plugin_auth-oidc")]
#[get("/oidc/{provider}/login")]
/// TODO: return result (or specific http response) instead of panicking
async fn oidc_login(
db: Data<Database>,
app_config: Data<AppConfig>,
Expand All @@ -229,12 +225,13 @@ async fn oidc_login(
use actix_web::http::header::{HeaderValue, LOCATION};
let provider_name = path_params.to_string();

let provider = auth_config
let provider = if let Some(provider) = auth_config
.oidc_providers
.iter()
.find(|p| p.name.eq(&provider_name));

if provider.is_none() {
.find(|p| p.name.eq(&provider_name))
{
provider
} else {
return HttpResponse::InternalServerError().json(
json!({
"success": false,
Expand All @@ -243,9 +240,7 @@ async fn oidc_login(
})
.to_string(),
);
}

let provider = provider.unwrap();
};

let query_params = query_params.into_inner();
let query_param_code = query_params.code;
Expand Down Expand Up @@ -315,24 +310,26 @@ async fn oidc_login(
tag = "Sessions",
))]
#[post("/logout")]
#[allow(clippy::future_not_send)] // safe because we're running blocking actions in a web::block
async fn logout(db: Data<Database>, req: HttpRequest) -> Result<HttpResponse, AWError> {
let refresh_token = req
.cookie(COOKIE_NAME)
.map(|cookie| String::from(cookie.value()));

let result =
web::block(move || controller::logout(&db, refresh_token.as_ref().map(|t| t.as_ref())))
.await?;
let result = web::block(move || {
controller::logout(&db, refresh_token.as_ref().map(std::convert::AsRef::as_ref))
})
.await?;

match result {
Ok(_) => {
Ok(()) => {
let mut cookie = Cookie::named(COOKIE_NAME);
cookie.make_removal();

Ok(HttpResponse::Ok().cookie(cookie).finish())
}
Err((status_code, message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": message }).to_string())),
}
Expand All @@ -353,14 +350,16 @@ async fn logout(db: Data<Database>, req: HttpRequest) -> Result<HttpResponse, AW
tag = "Sessions",
))]
#[post("/refresh")]
#[allow(clippy::future_not_send)] // safe because we're running blocking actions in a web::block
async fn refresh(db: Data<Database>, req: HttpRequest) -> Result<HttpResponse, AWError> {
let refresh_token = req
.cookie(COOKIE_NAME)
.map(|cookie| String::from(cookie.value()));

let result =
web::block(move || controller::refresh(&db, refresh_token.as_ref().map(|t| t.as_ref())))
.await?;
let result = web::block(move || {
controller::refresh(&db, refresh_token.as_ref().map(std::convert::AsRef::as_ref))
})
.await?;

match result {
Ok((access_token, refresh_token)) => Ok(HttpResponse::build(StatusCode::OK)
Expand All @@ -374,7 +373,7 @@ async fn refresh(db: Data<Database>, req: HttpRequest) -> Result<HttpResponse, A
)
.body(json!({ "access_token": access_token }).to_string())),
Err((status_code, message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": message }).to_string())),
}
Expand Down Expand Up @@ -408,7 +407,7 @@ async fn register(
Ok(()) => Ok(HttpResponse::build(StatusCode::OK)
.body("{ \"message\": \"Registered! Check your email to activate your account.\" }")),
Err((status_code, message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": message }).to_string())),
}
Expand Down Expand Up @@ -440,7 +439,7 @@ async fn activate(
match result {
Ok(()) => Ok(HttpResponse::build(StatusCode::OK).body("{ \"message\": \"Activated!\" }")),
Err((status_code, message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": message }).to_string())),
}
Expand Down Expand Up @@ -475,7 +474,7 @@ async fn forgot_password(
Ok(()) => Ok(HttpResponse::build(StatusCode::OK)
.body("{ \"message\": \"Please check your email.\" }")),
Err((status_code, message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": message }).to_string())),
}
Expand Down Expand Up @@ -515,7 +514,7 @@ async fn change_password(
Ok(()) => Ok(HttpResponse::build(StatusCode::OK)
.body(json!({"message": "Password changed."}).to_string())),
Err((status_code, message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": message }).to_string())),
}
Expand Down Expand Up @@ -567,13 +566,14 @@ async fn reset_password(
Ok(()) => Ok(HttpResponse::build(StatusCode::OK)
.body(json!({"message": "Password reset"}).to_string())),
Err((status_code, message)) => Ok(HttpResponse::build(
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
.body(json!({ "message": message }).to_string())),
}
}

/// returns the endpoints for the Auth service
#[must_use]
pub fn endpoints(scope: actix_web::Scope) -> actix_web::Scope {
let mut scope = scope
.service(sessions)
Expand Down
4 changes: 2 additions & 2 deletions create-rust-app/src/auth/endpoints/service_poem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ use crate::auth::controller::{
use crate::auth::{controller, Auth, PaginationParams, ID};
use crate::{Database, Mailer};

fn error_response(status_code: i32, message: &'static str) -> Error {
fn error_response(status_code: u16, message: &'static str) -> Error {
Error::from_string(
json!({ "message": message }).to_string(),
StatusCode::from_u16(status_code as u16).unwrap(),
StatusCode::from_u16(status_code).unwrap(),
)
}

Expand Down
32 changes: 22 additions & 10 deletions create-rust-app/src/auth/extractors/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::HashSet;

use crate::auth::{Permission, ID};

#[allow(clippy::module_name_repetitions)]
#[derive(Debug, Clone)]
/// roles and permissions available to a User
///
Expand All @@ -14,6 +15,7 @@ pub struct Auth {

impl Auth {
/// does the user with the id [`self.user_id`](`ID`) have the given `permission`
#[must_use]
pub fn has_permission(&self, permission: String) -> bool {
self.permissions.contains(&Permission {
permission,
Expand All @@ -22,27 +24,37 @@ impl Auth {
}

/// does the user with the id [`self.user_id`](`ID`) have all of the given `perms`
pub fn has_all_permissions(&self, perms: Vec<String>) -> bool {
perms.iter().all(|p| self.has_permission(p.to_string()))
#[must_use]
pub fn has_all_permissions(&self, perms: impl AsRef<[String]>) -> bool {
perms
.as_ref()
.iter()
.all(|p| self.has_permission(p.to_string()))
}

/// does the user with the id [`self.user_id`](`ID`) have any of the given `perms`
pub fn has_any_permission(&self, perms: Vec<String>) -> bool {
perms.iter().any(|p| self.has_permission(p.to_string()))
#[must_use]
pub fn has_any_permission(&self, perms: impl AsRef<[String]>) -> bool {
perms
.as_ref()
.iter()
.any(|p| self.has_permission(p.to_string()))
}

/// does the user with the id [`self.user_id`](`ID`) have the given `role`
pub fn has_role(&self, role: String) -> bool {
self.roles.contains(&role)
#[must_use]
pub fn has_role(&self, role: impl AsRef<str>) -> bool {
self.roles.contains(role.as_ref())
}

/// does the user with the id [`self.user_id`](`ID`) have all of the given `roles`
pub fn has_all_roles(&self, roles: Vec<String>) -> bool {
roles.iter().all(|r| self.has_role(r.to_string()))
#[must_use]
pub fn has_all_roles(&self, roles: impl AsRef<[String]>) -> bool {
roles.as_ref().iter().all(|r| self.has_role(r))
}

/// does the user with the id [`self.user_id`](`ID`) have any of the given `roles`
pub fn has_any_roles(&self, roles: Vec<String>) -> bool {
roles.iter().any(|r| self.has_role(r.to_string()))
pub fn has_any_roles(&self, roles: impl AsRef<[String]>) -> bool {
roles.as_ref().iter().any(|r| self.has_role(r))
}
}
Loading

0 comments on commit 500c06d

Please sign in to comment.