mirror of
				https://github.com/nitnelave/lldap.git
				synced 2023-04-12 14:25:13 +00:00 
			
		
		
		
	Implement per-user guards for the user details endpoint
This commit is contained in:
		
							parent
							
								
									a799ef2376
								
							
						
					
					
						commit
						fca7b04586
					
				@ -340,6 +340,7 @@ where
 | 
				
			|||||||
pub async fn token_validator<Backend>(
 | 
					pub async fn token_validator<Backend>(
 | 
				
			||||||
    req: ServiceRequest,
 | 
					    req: ServiceRequest,
 | 
				
			||||||
    credentials: BearerAuth,
 | 
					    credentials: BearerAuth,
 | 
				
			||||||
 | 
					    admin_required: bool,
 | 
				
			||||||
) -> Result<ServiceRequest, actix_web::Error>
 | 
					) -> Result<ServiceRequest, actix_web::Error>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    Backend: TcpBackendHandler + BackendHandler + 'static,
 | 
					    Backend: TcpBackendHandler + BackendHandler + 'static,
 | 
				
			||||||
@ -360,17 +361,39 @@ where
 | 
				
			|||||||
    if state.jwt_blacklist.read().unwrap().contains(&jwt_hash) {
 | 
					    if state.jwt_blacklist.read().unwrap().contains(&jwt_hash) {
 | 
				
			||||||
        return Err(ErrorUnauthorized("JWT was logged out"));
 | 
					        return Err(ErrorUnauthorized("JWT was logged out"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let groups = &token.claims().groups;
 | 
					    let is_admin = token.claims().groups.contains("lldap_admin");
 | 
				
			||||||
    if groups.contains("lldap_admin") {
 | 
					    if is_admin
 | 
				
			||||||
 | 
					        || (!admin_required && req.match_info().get("user_id") == Some(&token.claims().user))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        debug!("Got authorized token for user {}", &token.claims().user);
 | 
					        debug!("Got authorized token for user {}", &token.claims().user);
 | 
				
			||||||
        Ok(req)
 | 
					        Ok(req)
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        Err(ErrorUnauthorized(
 | 
					        Err(ErrorUnauthorized(
 | 
				
			||||||
            "JWT error: User is not in group lldap_admin",
 | 
					            "JWT error: User is not authorized to access this resource",
 | 
				
			||||||
        ))
 | 
					        ))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn admin_token_validator<Backend>(
 | 
				
			||||||
 | 
					    req: ServiceRequest,
 | 
				
			||||||
 | 
					    credentials: BearerAuth,
 | 
				
			||||||
 | 
					) -> Result<ServiceRequest, actix_web::Error>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    Backend: TcpBackendHandler + BackendHandler + 'static,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    token_validator::<Backend>(req, credentials, true).await
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn user_token_validator<Backend>(
 | 
				
			||||||
 | 
					    req: ServiceRequest,
 | 
				
			||||||
 | 
					    credentials: BearerAuth,
 | 
				
			||||||
 | 
					) -> Result<ServiceRequest, actix_web::Error>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    Backend: TcpBackendHandler + BackendHandler + 'static,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    token_validator::<Backend>(req, credentials, false).await
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn configure_server<Backend>(cfg: &mut web::ServiceConfig)
 | 
					pub fn configure_server<Backend>(cfg: &mut web::ServiceConfig)
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    Backend: TcpBackendHandler + LoginHandler + OpaqueHandler + BackendHandler + 'static,
 | 
					    Backend: TcpBackendHandler + LoginHandler + OpaqueHandler + BackendHandler + 'static,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,13 @@
 | 
				
			|||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    domain::{error::DomainError, handler::*},
 | 
					    domain::{error::DomainError, handler::*},
 | 
				
			||||||
    infra::{
 | 
					    infra::{
 | 
				
			||||||
 | 
					        auth_service,
 | 
				
			||||||
        tcp_backend_handler::*,
 | 
					        tcp_backend_handler::*,
 | 
				
			||||||
        tcp_server::{error_to_http_response, AppState},
 | 
					        tcp_server::{error_to_http_response, AppState},
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use actix_web::{web, HttpRequest, HttpResponse};
 | 
					use actix_web::{web, HttpRequest, HttpResponse};
 | 
				
			||||||
 | 
					use actix_web_httpauth::middleware::HttpAuthentication;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) fn error_to_api_response<T>(error: DomainError) -> ApiResult<T> {
 | 
					pub(crate) fn error_to_api_response<T>(error: DomainError) -> ApiResult<T> {
 | 
				
			||||||
    ApiResult::Right(error_to_http_response(error))
 | 
					    ApiResult::Right(error_to_http_response(error))
 | 
				
			||||||
@ -76,10 +78,17 @@ where
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    cfg.app_data(json_config);
 | 
					    cfg.app_data(json_config);
 | 
				
			||||||
    cfg.service(
 | 
					    cfg.service(
 | 
				
			||||||
        web::resource("/user/{user_id}").route(web::get().to(user_details_handler::<Backend>)),
 | 
					        web::resource("/user/{user_id}")
 | 
				
			||||||
 | 
					            .route(web::get().to(user_details_handler::<Backend>))
 | 
				
			||||||
 | 
					            .wrap(HttpAuthentication::bearer(
 | 
				
			||||||
 | 
					                auth_service::user_token_validator::<Backend>,
 | 
				
			||||||
 | 
					            )),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    cfg.service(
 | 
					    cfg.service(
 | 
				
			||||||
        web::scope("/users")
 | 
					        web::scope("/users")
 | 
				
			||||||
 | 
					            .wrap(HttpAuthentication::bearer(
 | 
				
			||||||
 | 
					                auth_service::admin_token_validator::<Backend>,
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
            .guard(actix_web::guard::Header("content-type", "application/json"))
 | 
					            .guard(actix_web::guard::Header("content-type", "application/json"))
 | 
				
			||||||
            .service(web::resource("").route(web::post().to(user_list_handler::<Backend>)))
 | 
					            .service(web::resource("").route(web::post().to(user_list_handler::<Backend>)))
 | 
				
			||||||
            .service(
 | 
					            .service(
 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,6 @@ use actix_http::HttpServiceBuilder;
 | 
				
			|||||||
use actix_server::ServerBuilder;
 | 
					use actix_server::ServerBuilder;
 | 
				
			||||||
use actix_service::map_config;
 | 
					use actix_service::map_config;
 | 
				
			||||||
use actix_web::{dev::AppConfig, web, App, HttpRequest, HttpResponse};
 | 
					use actix_web::{dev::AppConfig, web, App, HttpRequest, HttpResponse};
 | 
				
			||||||
use actix_web_httpauth::middleware::HttpAuthentication;
 | 
					 | 
				
			||||||
use anyhow::{Context, Result};
 | 
					use anyhow::{Context, Result};
 | 
				
			||||||
use hmac::{Hmac, NewMac};
 | 
					use hmac::{Hmac, NewMac};
 | 
				
			||||||
use sha2::Sha512;
 | 
					use sha2::Sha512;
 | 
				
			||||||
@ -64,9 +63,6 @@ fn http_config<Backend>(
 | 
				
			|||||||
    // API endpoint.
 | 
					    // API endpoint.
 | 
				
			||||||
    .service(
 | 
					    .service(
 | 
				
			||||||
        web::scope("/api")
 | 
					        web::scope("/api")
 | 
				
			||||||
            .wrap(HttpAuthentication::bearer(
 | 
					 | 
				
			||||||
                auth_service::token_validator::<Backend>,
 | 
					 | 
				
			||||||
            ))
 | 
					 | 
				
			||||||
            .wrap(auth_service::CookieToHeaderTranslatorFactory)
 | 
					            .wrap(auth_service::CookieToHeaderTranslatorFactory)
 | 
				
			||||||
            .configure(tcp_api::api_config::<Backend>),
 | 
					            .configure(tcp_api::api_config::<Backend>),
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user