mirror of
				https://github.com/nitnelave/lldap.git
				synced 2023-04-12 14:25:13 +00:00 
			
		
		
		
	server: update actix, inline juniper-actix
This commit is contained in:
		
							parent
							
								
									1bd31081e3
								
							
						
					
					
						commit
						8f765dff54
					
				
							
								
								
									
										1595
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1595
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -11,3 +11,6 @@ default-members = ["server"]
 | 
				
			|||||||
[patch.crates-io.opaque-ke]
 | 
					[patch.crates-io.opaque-ke]
 | 
				
			||||||
git = 'https://github.com/nitnelave/opaque-ke/'
 | 
					git = 'https://github.com/nitnelave/opaque-ke/'
 | 
				
			||||||
branch = 'zeroize_1.5'
 | 
					branch = 'zeroize_1.5'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[patch.crates-io.lber]
 | 
				
			||||||
 | 
					git = 'https://github.com/inejge/ldap3/'
 | 
				
			||||||
 | 
				
			|||||||
@ -5,14 +5,14 @@ name = "lldap"
 | 
				
			|||||||
version = "0.4.2-alpha"
 | 
					version = "0.4.2-alpha"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
actix = "0.12"
 | 
					actix = "0.13"
 | 
				
			||||||
actix-files = "0.6.0-beta.6"
 | 
					actix-files = "0.6"
 | 
				
			||||||
actix-http = "=3.0.0-beta.9"
 | 
					actix-http = "3"
 | 
				
			||||||
actix-rt = "2.2.0"
 | 
					actix-rt = "2"
 | 
				
			||||||
actix-server = "=2.0.0-beta.5"
 | 
					actix-server = "2"
 | 
				
			||||||
actix-service = "2.0.0"
 | 
					actix-service = "2"
 | 
				
			||||||
actix-web = "=4.0.0-beta.8"
 | 
					actix-web = "4.3"
 | 
				
			||||||
actix-web-httpauth = "0.6.0-beta.2"
 | 
					actix-web-httpauth = "0.8"
 | 
				
			||||||
anyhow = "*"
 | 
					anyhow = "*"
 | 
				
			||||||
async-trait = "0.1"
 | 
					async-trait = "0.1"
 | 
				
			||||||
base64 = "0.13"
 | 
					base64 = "0.13"
 | 
				
			||||||
@ -25,9 +25,9 @@ futures-util = "*"
 | 
				
			|||||||
hmac = "0.10"
 | 
					hmac = "0.10"
 | 
				
			||||||
http = "*"
 | 
					http = "*"
 | 
				
			||||||
itertools = "0.10.1"
 | 
					itertools = "0.10.1"
 | 
				
			||||||
juniper = "0.15.10"
 | 
					juniper = "0.15"
 | 
				
			||||||
juniper_actix = "0.4.0"
 | 
					jwt = "0.16"
 | 
				
			||||||
jwt = "0.13"
 | 
					lber = "0.4.1"
 | 
				
			||||||
ldap3_proto = ">=0.3.1"
 | 
					ldap3_proto = ">=0.3.1"
 | 
				
			||||||
log = "*"
 | 
					log = "*"
 | 
				
			||||||
orion = "0.16"
 | 
					orion = "0.16"
 | 
				
			||||||
@ -36,12 +36,12 @@ serde = "*"
 | 
				
			|||||||
serde_json = "1"
 | 
					serde_json = "1"
 | 
				
			||||||
sha2 = "0.9"
 | 
					sha2 = "0.9"
 | 
				
			||||||
thiserror = "*"
 | 
					thiserror = "*"
 | 
				
			||||||
time = "0.2"
 | 
					time = "0.3"
 | 
				
			||||||
tokio-rustls = "0.23"
 | 
					tokio-rustls = "0.23"
 | 
				
			||||||
tokio-stream = "*"
 | 
					tokio-stream = "*"
 | 
				
			||||||
tokio-util = "0.7.3"
 | 
					tokio-util = "0.7.3"
 | 
				
			||||||
tracing = "*"
 | 
					tracing = "*"
 | 
				
			||||||
tracing-actix-web = "0.4.0-beta.7"
 | 
					tracing-actix-web = "0.7"
 | 
				
			||||||
tracing-attributes = "^0.1.21"
 | 
					tracing-attributes = "^0.1.21"
 | 
				
			||||||
tracing-log = "*"
 | 
					tracing-log = "*"
 | 
				
			||||||
rustls-pemfile = "1.0.0"
 | 
					rustls-pemfile = "1.0.0"
 | 
				
			||||||
@ -97,7 +97,7 @@ version = "^0.1.4"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[dependencies.actix-tls]
 | 
					[dependencies.actix-tls]
 | 
				
			||||||
features = ["default", "rustls"]
 | 
					features = ["default", "rustls"]
 | 
				
			||||||
version = "=3.0.0-beta.5"
 | 
					version = "3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies.image]
 | 
					[dependencies.image]
 | 
				
			||||||
features = ["jpeg"]
 | 
					features = ["jpeg"]
 | 
				
			||||||
 | 
				
			|||||||
@ -451,14 +451,15 @@ where
 | 
				
			|||||||
#[instrument(skip_all, level = "debug")]
 | 
					#[instrument(skip_all, level = "debug")]
 | 
				
			||||||
async fn opaque_register_start<Backend>(
 | 
					async fn opaque_register_start<Backend>(
 | 
				
			||||||
    request: actix_web::HttpRequest,
 | 
					    request: actix_web::HttpRequest,
 | 
				
			||||||
    mut payload: actix_web::web::Payload,
 | 
					    payload: actix_web::web::Payload,
 | 
				
			||||||
    data: web::Data<AppState<Backend>>,
 | 
					    data: web::Data<AppState<Backend>>,
 | 
				
			||||||
) -> TcpResult<registration::ServerRegistrationStartResponse>
 | 
					) -> TcpResult<registration::ServerRegistrationStartResponse>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    Backend: BackendHandler + OpaqueHandler + 'static,
 | 
					    Backend: BackendHandler + OpaqueHandler + 'static,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use actix_web::FromRequest;
 | 
					    use actix_web::FromRequest;
 | 
				
			||||||
    let validation_result = BearerAuth::from_request(&request, &mut payload.0)
 | 
					    let inner_payload = &mut payload.into_inner();
 | 
				
			||||||
 | 
					    let validation_result = BearerAuth::from_request(&request, inner_payload)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .ok()
 | 
					        .ok()
 | 
				
			||||||
        .and_then(|bearer| check_if_token_is_valid(&data, bearer.token()).ok())
 | 
					        .and_then(|bearer| check_if_token_is_valid(&data, bearer.token()).ok())
 | 
				
			||||||
@ -468,7 +469,7 @@ where
 | 
				
			|||||||
    let registration_start_request =
 | 
					    let registration_start_request =
 | 
				
			||||||
        web::Json::<registration::ClientRegistrationStartRequest>::from_request(
 | 
					        web::Json::<registration::ClientRegistrationStartRequest>::from_request(
 | 
				
			||||||
            &request,
 | 
					            &request,
 | 
				
			||||||
            &mut payload.0,
 | 
					            inner_payload,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map_err(|e| TcpError::BadRequest(format!("{:#?}", e)))?
 | 
					        .map_err(|e| TcpError::BadRequest(format!("{:#?}", e)))?
 | 
				
			||||||
 | 
				
			|||||||
@ -11,10 +11,17 @@ use crate::{
 | 
				
			|||||||
        tcp_server::AppState,
 | 
					        tcp_server::AppState,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use actix_web::{web, Error, HttpResponse};
 | 
					use actix_web::FromRequest;
 | 
				
			||||||
 | 
					use actix_web::HttpMessage;
 | 
				
			||||||
 | 
					use actix_web::{error::JsonPayloadError, web, Error, HttpRequest, HttpResponse};
 | 
				
			||||||
use actix_web_httpauth::extractors::bearer::BearerAuth;
 | 
					use actix_web_httpauth::extractors::bearer::BearerAuth;
 | 
				
			||||||
use juniper::{EmptySubscription, FieldError, RootNode};
 | 
					use juniper::{
 | 
				
			||||||
use juniper_actix::{graphiql_handler, graphql_handler, playground_handler};
 | 
					    http::{
 | 
				
			||||||
 | 
					        graphiql::graphiql_source, playground::playground_source, GraphQLBatchRequest,
 | 
				
			||||||
 | 
					        GraphQLRequest,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    EmptySubscription, FieldError, RootNode, ScalarValue,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
use tracing::debug;
 | 
					use tracing::debug;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Context<Handler: BackendHandler> {
 | 
					pub struct Context<Handler: BackendHandler> {
 | 
				
			||||||
@ -100,25 +107,129 @@ pub fn export_schema(opts: ExportGraphQLSchemaOpts) -> anyhow::Result<()> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async fn graphiql_route() -> Result<HttpResponse, Error> {
 | 
					async fn graphiql_route() -> Result<HttpResponse, Error> {
 | 
				
			||||||
    graphiql_handler("/api/graphql", None).await
 | 
					    let html = graphiql_source("/api/graphql", None);
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok()
 | 
				
			||||||
 | 
					        .content_type("text/html; charset=utf-8")
 | 
				
			||||||
 | 
					        .body(html))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
async fn playground_route() -> Result<HttpResponse, Error> {
 | 
					async fn playground_route() -> Result<HttpResponse, Error> {
 | 
				
			||||||
    playground_handler("/api/graphql", None).await
 | 
					    let html = playground_source("/api/graphql", None);
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok()
 | 
				
			||||||
 | 
					        .content_type("text/html; charset=utf-8")
 | 
				
			||||||
 | 
					        .body(html))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Deserialize, Clone, PartialEq, Debug)]
 | 
				
			||||||
 | 
					struct GetGraphQLRequest {
 | 
				
			||||||
 | 
					    query: String,
 | 
				
			||||||
 | 
					    #[serde(rename = "operationName")]
 | 
				
			||||||
 | 
					    operation_name: Option<String>,
 | 
				
			||||||
 | 
					    variables: Option<String>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<S> From<GetGraphQLRequest> for GraphQLRequest<S>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    S: ScalarValue,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    fn from(get_req: GetGraphQLRequest) -> Self {
 | 
				
			||||||
 | 
					        let GetGraphQLRequest {
 | 
				
			||||||
 | 
					            query,
 | 
				
			||||||
 | 
					            operation_name,
 | 
				
			||||||
 | 
					            variables,
 | 
				
			||||||
 | 
					        } = get_req;
 | 
				
			||||||
 | 
					        let variables = variables.map(|s| serde_json::from_str(&s).unwrap());
 | 
				
			||||||
 | 
					        Self::new(query, operation_name, variables)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Actix GraphQL Handler for GET requests
 | 
				
			||||||
 | 
					pub async fn get_graphql_handler<Query, Mutation, Subscription, CtxT, S>(
 | 
				
			||||||
 | 
					    schema: &juniper::RootNode<'static, Query, Mutation, Subscription, S>,
 | 
				
			||||||
 | 
					    context: &CtxT,
 | 
				
			||||||
 | 
					    req: HttpRequest,
 | 
				
			||||||
 | 
					) -> Result<HttpResponse, Error>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    Query: juniper::GraphQLTypeAsync<S, Context = CtxT>,
 | 
				
			||||||
 | 
					    Query::TypeInfo: Sync,
 | 
				
			||||||
 | 
					    Mutation: juniper::GraphQLTypeAsync<S, Context = CtxT>,
 | 
				
			||||||
 | 
					    Mutation::TypeInfo: Sync,
 | 
				
			||||||
 | 
					    Subscription: juniper::GraphQLSubscriptionType<S, Context = CtxT>,
 | 
				
			||||||
 | 
					    Subscription::TypeInfo: Sync,
 | 
				
			||||||
 | 
					    CtxT: Sync,
 | 
				
			||||||
 | 
					    S: ScalarValue + Send + Sync,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    let get_req = web::Query::<GetGraphQLRequest>::from_query(req.query_string())?;
 | 
				
			||||||
 | 
					    let req = GraphQLRequest::from(get_req.into_inner());
 | 
				
			||||||
 | 
					    let gql_response = req.execute(schema, context).await;
 | 
				
			||||||
 | 
					    let body_response = serde_json::to_string(&gql_response)?;
 | 
				
			||||||
 | 
					    let mut response = match gql_response.is_ok() {
 | 
				
			||||||
 | 
					        true => HttpResponse::Ok(),
 | 
				
			||||||
 | 
					        false => HttpResponse::BadRequest(),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    Ok(response
 | 
				
			||||||
 | 
					        .content_type("application/json")
 | 
				
			||||||
 | 
					        .body(body_response))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Actix GraphQL Handler for POST requests
 | 
				
			||||||
 | 
					pub async fn post_graphql_handler<Query, Mutation, Subscription, CtxT, S>(
 | 
				
			||||||
 | 
					    schema: &juniper::RootNode<'static, Query, Mutation, Subscription, S>,
 | 
				
			||||||
 | 
					    context: &CtxT,
 | 
				
			||||||
 | 
					    req: HttpRequest,
 | 
				
			||||||
 | 
					    mut payload: actix_http::Payload,
 | 
				
			||||||
 | 
					) -> Result<HttpResponse, Error>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    Query: juniper::GraphQLTypeAsync<S, Context = CtxT>,
 | 
				
			||||||
 | 
					    Query::TypeInfo: Sync,
 | 
				
			||||||
 | 
					    Mutation: juniper::GraphQLTypeAsync<S, Context = CtxT>,
 | 
				
			||||||
 | 
					    Mutation::TypeInfo: Sync,
 | 
				
			||||||
 | 
					    Subscription: juniper::GraphQLSubscriptionType<S, Context = CtxT>,
 | 
				
			||||||
 | 
					    Subscription::TypeInfo: Sync,
 | 
				
			||||||
 | 
					    CtxT: Sync,
 | 
				
			||||||
 | 
					    S: ScalarValue + Send + Sync,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    let req = match req.content_type() {
 | 
				
			||||||
 | 
					        "application/json" => {
 | 
				
			||||||
 | 
					            let body = String::from_request(&req, &mut payload).await?;
 | 
				
			||||||
 | 
					            serde_json::from_str::<GraphQLBatchRequest<S>>(&body)
 | 
				
			||||||
 | 
					                .map_err(JsonPayloadError::Deserialize)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        "application/graphql" => {
 | 
				
			||||||
 | 
					            let body = String::from_request(&req, &mut payload).await?;
 | 
				
			||||||
 | 
					            Ok(GraphQLBatchRequest::Single(GraphQLRequest::new(
 | 
				
			||||||
 | 
					                body, None, None,
 | 
				
			||||||
 | 
					            )))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        _ => Err(JsonPayloadError::ContentType),
 | 
				
			||||||
 | 
					    }?;
 | 
				
			||||||
 | 
					    let gql_batch_response = req.execute(schema, context).await;
 | 
				
			||||||
 | 
					    let gql_response = serde_json::to_string(&gql_batch_response)?;
 | 
				
			||||||
 | 
					    let mut response = match gql_batch_response.is_ok() {
 | 
				
			||||||
 | 
					        true => HttpResponse::Ok(),
 | 
				
			||||||
 | 
					        false => HttpResponse::BadRequest(),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    Ok(response.content_type("application/json").body(gql_response))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async fn graphql_route<Handler: BackendHandler + Clone>(
 | 
					async fn graphql_route<Handler: BackendHandler + Clone>(
 | 
				
			||||||
    req: actix_web::HttpRequest,
 | 
					    req: actix_web::HttpRequest,
 | 
				
			||||||
    mut payload: actix_web::web::Payload,
 | 
					    payload: actix_web::web::Payload,
 | 
				
			||||||
    data: web::Data<AppState<Handler>>,
 | 
					    data: web::Data<AppState<Handler>>,
 | 
				
			||||||
) -> Result<HttpResponse, Error> {
 | 
					) -> Result<HttpResponse, Error> {
 | 
				
			||||||
    use actix_web::FromRequest;
 | 
					    let mut inner_payload = payload.into_inner();
 | 
				
			||||||
    let bearer = BearerAuth::from_request(&req, &mut payload.0).await?;
 | 
					    let bearer = BearerAuth::from_request(&req, &mut inner_payload).await?;
 | 
				
			||||||
    let validation_result = check_if_token_is_valid(&data, bearer.token())?;
 | 
					    let validation_result = check_if_token_is_valid(&data, bearer.token())?;
 | 
				
			||||||
    let context = Context::<Handler> {
 | 
					    let context = Context::<Handler> {
 | 
				
			||||||
        handler: data.backend_handler.clone(),
 | 
					        handler: data.backend_handler.clone(),
 | 
				
			||||||
        validation_result,
 | 
					        validation_result,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    graphql_handler(&schema(), &context, req, payload).await
 | 
					    let schema = &schema();
 | 
				
			||||||
 | 
					    let context = &context;
 | 
				
			||||||
 | 
					    match *req.method() {
 | 
				
			||||||
 | 
					        actix_http::Method::POST => post_graphql_handler(schema, context, req, inner_payload).await,
 | 
				
			||||||
 | 
					        actix_http::Method::GET => get_graphql_handler(schema, context, req).await,
 | 
				
			||||||
 | 
					        _ => Err(actix_web::error::UrlGenerationError::ResourceNotFound.into()),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn configure_endpoint<Backend>(cfg: &mut web::ServiceConfig)
 | 
					pub fn configure_endpoint<Backend>(cfg: &mut web::ServiceConfig)
 | 
				
			||||||
 | 
				
			|||||||
@ -85,7 +85,10 @@ fn http_config<Backend>(
 | 
				
			|||||||
        server_url,
 | 
					        server_url,
 | 
				
			||||||
        mail_options,
 | 
					        mail_options,
 | 
				
			||||||
    }))
 | 
					    }))
 | 
				
			||||||
    .route("/health", web::get().to(|| HttpResponse::Ok().finish()))
 | 
					    .route(
 | 
				
			||||||
 | 
					        "/health",
 | 
				
			||||||
 | 
					        web::get().to(|| async { HttpResponse::Ok().finish() }),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    .service(
 | 
					    .service(
 | 
				
			||||||
        web::scope("/auth")
 | 
					        web::scope("/auth")
 | 
				
			||||||
            .configure(|cfg| auth_service::configure_server::<Backend>(cfg, enable_password_reset)),
 | 
					            .configure(|cfg| auth_service::configure_server::<Backend>(cfg, enable_password_reset)),
 | 
				
			||||||
@ -165,7 +168,7 @@ where
 | 
				
			|||||||
                let jwt_blacklist = jwt_blacklist.clone();
 | 
					                let jwt_blacklist = jwt_blacklist.clone();
 | 
				
			||||||
                let server_url = server_url.clone();
 | 
					                let server_url = server_url.clone();
 | 
				
			||||||
                let mail_options = mail_options.clone();
 | 
					                let mail_options = mail_options.clone();
 | 
				
			||||||
                HttpServiceBuilder::new()
 | 
					                HttpServiceBuilder::default()
 | 
				
			||||||
                    .finish(map_config(
 | 
					                    .finish(map_config(
 | 
				
			||||||
                        App::new()
 | 
					                        App::new()
 | 
				
			||||||
                            .wrap(tracing_actix_web::TracingLogger::<CustomRootSpanBuilder>::new())
 | 
					                            .wrap(tracing_actix_web::TracingLogger::<CustomRootSpanBuilder>::new())
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user