From 30edde0ae9ca190df606a15c483ce9e8d79db81e Mon Sep 17 00:00:00 2001 From: Mark Drobnak Date: Fri, 17 Jul 2020 09:51:01 -0400 Subject: [PATCH 1/8] Stub the update token endpoint --- autoendpoint/src/routes/registration.rs | 11 +++++++++++ autoendpoint/src/server.rs | 6 +++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/autoendpoint/src/routes/registration.rs b/autoendpoint/src/routes/registration.rs index 47d90de6d..79e21bd4e 100644 --- a/autoendpoint/src/routes/registration.rs +++ b/autoendpoint/src/routes/registration.rs @@ -77,6 +77,17 @@ pub async fn register_uaid_route( }))) } +/// Handle the `PUT /v1/{router_type}/{app_id}/registration/{uaid}` route +pub async fn update_token_route( + path_args: RegistrationPathArgs, + router_data_input: RouterDataInput, + routers: Routers, + state: Data, + request: HttpRequest, +) -> ApiResult { + unimplemented!() +} + /// Increment a metric with data from the request fn incr_metric(name: &str, metrics: &StatsdClient, request: &HttpRequest) { metrics diff --git a/autoendpoint/src/server.rs b/autoendpoint/src/server.rs index 8b7f8af53..a7dc6e7ab 100644 --- a/autoendpoint/src/server.rs +++ b/autoendpoint/src/server.rs @@ -6,7 +6,7 @@ use crate::metrics; use crate::middleware::sentry::sentry_middleware; use crate::routers::fcm::router::FcmRouter; use crate::routes::health::{health_route, lb_heartbeat_route, status_route, version_route}; -use crate::routes::registration::register_uaid_route; +use crate::routes::registration::{register_uaid_route, update_token_route}; use crate::routes::webpush::{delete_notification_route, webpush_route}; use crate::settings::Settings; use actix_cors::Cors; @@ -86,6 +86,10 @@ impl Server { web::resource("/v1/{router_type}/{app_id}/registration") .route(web::post().to(register_uaid_route)), ) + .service( + web::resource("/v1/{router_type}/{app_id}/registration/{uaid}") + .route(web::put().to(update_token_route)), + ) // Health checks .service(web::resource("/status").route(web::get().to(status_route))) .service(web::resource("/health").route(web::get().to(health_route))) From 2f0e638333bbe1da502ae2d675e9807f0123435e Mon Sep 17 00:00:00 2001 From: Mark Drobnak Date: Fri, 17 Jul 2020 10:33:06 -0400 Subject: [PATCH 2/8] Add the registration endpoint authorization check --- autoendpoint/src/auth.rs | 13 ++++ autoendpoint/src/error.rs | 16 +++-- autoendpoint/src/extractors/mod.rs | 1 + autoendpoint/src/main.rs | 1 + autoendpoint/src/routes/registration.rs | 16 +---- .../server/extractors/authorization_check.rs | 66 +++++++++++++++++++ autoendpoint/src/settings.rs | 2 +- 7 files changed, 96 insertions(+), 19 deletions(-) create mode 100644 autoendpoint/src/auth.rs create mode 100644 autoendpoint/src/server/extractors/authorization_check.rs diff --git a/autoendpoint/src/auth.rs b/autoendpoint/src/auth.rs new file mode 100644 index 000000000..7bf6485bc --- /dev/null +++ b/autoendpoint/src/auth.rs @@ -0,0 +1,13 @@ +use openssl::error::ErrorStack; +use openssl::hash::MessageDigest; +use openssl::pkey::PKey; +use openssl::sign::Signer; + +/// Sign some data with a key and return the hex representation +pub fn sign_with_key(key: &[u8], data: &[u8]) -> Result { + let key = PKey::hmac(key)?; + let mut signer = Signer::new(MessageDigest::sha256(), &key)?; + + signer.update(data)?; + Ok(hex::encode(signer.sign_to_vec()?)) +} diff --git a/autoendpoint/src/error.rs b/autoendpoint/src/error.rs index 12ea0b279..974a70866 100644 --- a/autoendpoint/src/error.rs +++ b/autoendpoint/src/error.rs @@ -110,6 +110,9 @@ pub enum ApiErrorKind { #[error("{0}")] Internal(String), + + #[error("Invalid Authentication")] + InvalidAuthentication, } impl ApiErrorKind { @@ -121,18 +124,20 @@ impl ApiErrorKind { ApiErrorKind::Validation(_) | ApiErrorKind::InvalidEncryption(_) - | ApiErrorKind::TokenHashValidation(_) | ApiErrorKind::NoTTL | ApiErrorKind::InvalidRouterType | ApiErrorKind::InvalidRouterToken | ApiErrorKind::InvalidMessageId => StatusCode::BAD_REQUEST, - ApiErrorKind::NoUser | ApiErrorKind::NoSubscription => StatusCode::GONE, - - ApiErrorKind::VapidError(_) | ApiErrorKind::Jwt(_) => StatusCode::UNAUTHORIZED, + ApiErrorKind::VapidError(_) + | ApiErrorKind::Jwt(_) + | ApiErrorKind::TokenHashValidation(_) + | ApiErrorKind::InvalidAuthentication => StatusCode::UNAUTHORIZED, ApiErrorKind::InvalidToken | ApiErrorKind::InvalidApiVersion => StatusCode::NOT_FOUND, + ApiErrorKind::NoUser | ApiErrorKind::NoSubscription => StatusCode::GONE, + ApiErrorKind::Io(_) | ApiErrorKind::Metrics(_) | ApiErrorKind::Database(_) @@ -166,7 +171,8 @@ impl ApiErrorKind { ApiErrorKind::VapidError(_) | ApiErrorKind::TokenHashValidation(_) - | ApiErrorKind::Jwt(_) => Some(109), + | ApiErrorKind::Jwt(_) + | ApiErrorKind::InvalidAuthentication => Some(109), ApiErrorKind::InvalidEncryption(_) => Some(110), diff --git a/autoendpoint/src/extractors/mod.rs b/autoendpoint/src/extractors/mod.rs index 3526d3a5d..c776800f7 100644 --- a/autoendpoint/src/extractors/mod.rs +++ b/autoendpoint/src/extractors/mod.rs @@ -1,6 +1,7 @@ //! Actix extractors (`FromRequest`). These extractors transform and validate //! the incoming request data. +pub mod authorization_check; pub mod message_id; pub mod notification; pub mod notification_headers; diff --git a/autoendpoint/src/main.rs b/autoendpoint/src/main.rs index 7d75c2acf..f7bb04e1c 100644 --- a/autoendpoint/src/main.rs +++ b/autoendpoint/src/main.rs @@ -3,6 +3,7 @@ #[macro_use] extern crate slog_scope; +mod auth; mod db; mod error; mod extractors; diff --git a/autoendpoint/src/routes/registration.rs b/autoendpoint/src/routes/registration.rs index 79e21bd4e..ddb74e8a3 100644 --- a/autoendpoint/src/routes/registration.rs +++ b/autoendpoint/src/routes/registration.rs @@ -1,4 +1,6 @@ +use crate::auth::sign_with_key; use crate::error::{ApiErrorKind, ApiResult}; +use crate::extractors::authorization_check::AuthorizationCheck; use crate::extractors::registration_path_args::RegistrationPathArgs; use crate::extractors::router_data_input::RouterDataInput; use crate::extractors::routers::Routers; @@ -9,10 +11,6 @@ use actix_web::{HttpRequest, HttpResponse}; use autopush_common::db::DynamoDbUser; use autopush_common::endpoint::make_endpoint; use cadence::{Counted, StatsdClient}; -use openssl::error::ErrorStack; -use openssl::hash::MessageDigest; -use openssl::pkey::PKey; -use openssl::sign::Signer; use uuid::Uuid; /// Handle the `POST /v1/{router_type}/{app_id}/registration` route @@ -79,6 +77,7 @@ pub async fn register_uaid_route( /// Handle the `PUT /v1/{router_type}/{app_id}/registration/{uaid}` route pub async fn update_token_route( + _auth: AuthorizationCheck, path_args: RegistrationPathArgs, router_data_input: RouterDataInput, routers: Routers, @@ -99,12 +98,3 @@ fn incr_metric(name: &str, metrics: &StatsdClient, request: &HttpRequest) { .with_tag("host", get_header(&request, "Host").unwrap_or("unknown")) .send() } - -/// Sign some data with a key and return the hex representation -fn sign_with_key(key: &[u8], data: &[u8]) -> Result { - let key = PKey::hmac(key)?; - let mut signer = Signer::new(MessageDigest::sha256(), &key)?; - - signer.update(data)?; - Ok(hex::encode(signer.sign_to_vec()?)) -} diff --git a/autoendpoint/src/server/extractors/authorization_check.rs b/autoendpoint/src/server/extractors/authorization_check.rs new file mode 100644 index 000000000..51db610fd --- /dev/null +++ b/autoendpoint/src/server/extractors/authorization_check.rs @@ -0,0 +1,66 @@ +use crate::auth::sign_with_key; +use crate::error::{ApiError, ApiErrorKind}; +use crate::server::headers::util::get_header; +use crate::server::ServerState; +use actix_web::dev::{Payload, PayloadStream}; +use actix_web::web::Data; +use actix_web::{FromRequest, HttpRequest}; +use futures::future::LocalBoxFuture; +use futures::FutureExt; + +/// Verifies the request authorization via the authorization header. +/// +/// The expected token is the HMAC-SHA256 hash of the UAID, signed with one of +/// the available keys (allows for key rotation). +pub struct AuthorizationCheck; + +impl FromRequest for AuthorizationCheck { + type Error = ApiError; + type Future = LocalBoxFuture<'static, Result>; + type Config = (); + + fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { + let req = req.clone(); + + async move { + let uaid = req + .match_info() + .get("uaid") + .expect("{uaid} must be part of the path"); + let state: Data = Data::extract(&req) + .into_inner() + .expect("No server state found"); + let auth_header = + get_header(&req, "Authorization").ok_or(ApiErrorKind::InvalidAuthentication)?; + let token = get_token_from_auth_header(auth_header) + .ok_or(ApiErrorKind::InvalidAuthentication)?; + + // Check the token against the expected token for each key + for key in state.settings.auth_keys() { + let expected_token = sign_with_key(key.as_bytes(), uaid.as_bytes()) + .map_err(ApiErrorKind::RegistrationSecretHash)?; + + if expected_token.len() == token.len() + && openssl::memcmp::eq(expected_token.as_bytes(), token.as_bytes()) + { + return Ok(Self); + } + } + + Err(ApiErrorKind::InvalidAuthentication.into()) + } + .boxed_local() + } +} + +/// Get the token from a bearer authorization header +fn get_token_from_auth_header(header: &str) -> Option<&str> { + let mut split = header.splitn(2, ' '); + let scheme = split.next()?; + + if scheme != "Bearer" { + return None; + } + + split.next() +} diff --git a/autoendpoint/src/settings.rs b/autoendpoint/src/settings.rs index 88eaf41ff..973327efa 100644 --- a/autoendpoint/src/settings.rs +++ b/autoendpoint/src/settings.rs @@ -103,7 +103,7 @@ impl Settings { /// Initialize the fernet encryption instance pub fn make_fernet(&self) -> MultiFernet { - let fernets = Self::read_list_from_str(&self.crypto_keys, "Invalid AUTOEND_CRYPTO_KEY") + let fernets = Self::read_list_from_str(&self.crypto_keys, "Invalid AUTOEND_CRYPTO_KEYS") .map(|key| Fernet::new(key).expect("Invalid AUTOEND_CRYPTO_KEYS")) .collect(); MultiFernet::new(fernets) From 1d2c4342c1fe904281b3c69fee5b799694c0c6a6 Mon Sep 17 00:00:00 2001 From: Mark Drobnak Date: Fri, 17 Jul 2020 10:53:07 -0400 Subject: [PATCH 3/8] Add RegistrationPathArgsWithUaid to validate the user exists --- autoendpoint/src/extractors/mod.rs | 1 + autoendpoint/src/routes/registration.rs | 3 +- .../registration_path_args_with_uaid.rs | 53 +++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 autoendpoint/src/server/extractors/registration_path_args_with_uaid.rs diff --git a/autoendpoint/src/extractors/mod.rs b/autoendpoint/src/extractors/mod.rs index c776800f7..34c817021 100644 --- a/autoendpoint/src/extractors/mod.rs +++ b/autoendpoint/src/extractors/mod.rs @@ -6,6 +6,7 @@ pub mod message_id; pub mod notification; pub mod notification_headers; pub mod registration_path_args; +pub mod registration_path_args_with_uaid; pub mod router_data_input; pub mod routers; pub mod subscription; diff --git a/autoendpoint/src/routes/registration.rs b/autoendpoint/src/routes/registration.rs index ddb74e8a3..f5458a33b 100644 --- a/autoendpoint/src/routes/registration.rs +++ b/autoendpoint/src/routes/registration.rs @@ -2,6 +2,7 @@ use crate::auth::sign_with_key; use crate::error::{ApiErrorKind, ApiResult}; use crate::extractors::authorization_check::AuthorizationCheck; use crate::extractors::registration_path_args::RegistrationPathArgs; +use crate::extractors::registration_path_args_with_uaid::RegistrationPathArgsWithUaid; use crate::extractors::router_data_input::RouterDataInput; use crate::extractors::routers::Routers; use crate::headers::util::get_header; @@ -78,7 +79,7 @@ pub async fn register_uaid_route( /// Handle the `PUT /v1/{router_type}/{app_id}/registration/{uaid}` route pub async fn update_token_route( _auth: AuthorizationCheck, - path_args: RegistrationPathArgs, + path_args: RegistrationPathArgsWithUaid, router_data_input: RouterDataInput, routers: Routers, state: Data, diff --git a/autoendpoint/src/server/extractors/registration_path_args_with_uaid.rs b/autoendpoint/src/server/extractors/registration_path_args_with_uaid.rs new file mode 100644 index 000000000..f37c33864 --- /dev/null +++ b/autoendpoint/src/server/extractors/registration_path_args_with_uaid.rs @@ -0,0 +1,53 @@ +use crate::error::{ApiError, ApiErrorKind}; +use crate::server::extractors::registration_path_args::RegistrationPathArgs; +use crate::server::extractors::routers::RouterType; +use crate::server::ServerState; +use actix_web::dev::{Payload, PayloadStream}; +use actix_web::web::Data; +use actix_web::{FromRequest, HttpRequest}; +use futures::future::LocalBoxFuture; +use futures::FutureExt; +use uuid::Uuid; + +/// An extension of `RegistrationPathArgs` which requires a `uaid` path arg. +/// The `uaid` is verified by checking if the user exists in the database. +pub struct RegistrationPathArgsWithUaid { + pub router_type: RouterType, + pub app_id: String, + pub uaid: Uuid, +} + +impl FromRequest for RegistrationPathArgsWithUaid { + type Error = ApiError; + type Future = LocalBoxFuture<'static, Result>; + type Config = (); + + fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { + let req = req.clone(); + + async move { + let state: Data = Data::extract(&req) + .into_inner() + .expect("No server state found"); + let path_args = RegistrationPathArgs::extract(&req).into_inner()?; + let uaid = req + .match_info() + .get("uaid") + .expect("{uaid} must be part of the path") + .parse::() + .map_err(|_| ApiErrorKind::NoUser)?; + + // Verify that the user exists + if state.ddb.get_user(uaid).await?.is_none() { + return Err(ApiErrorKind::NoUser.into()); + } + + Ok(Self { + router_type: path_args.router_type, + app_id: path_args.app_id, + uaid, + }) + } + .boxed_local() + } +} From c953d60510c57ff5afcc6f277578cc5c68cca549 Mon Sep 17 00:00:00 2001 From: Mark Drobnak Date: Fri, 17 Jul 2020 11:27:45 -0400 Subject: [PATCH 4/8] Implement update_token_route and add DbClient::update_user --- autoendpoint/src/db/client.rs | 53 +++++++++++++++++++++++-- autoendpoint/src/routes/registration.rs | 24 ++++++++++- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/autoendpoint/src/db/client.rs b/autoendpoint/src/db/client.rs index dc3029198..050295470 100644 --- a/autoendpoint/src/db/client.rs +++ b/autoendpoint/src/db/client.rs @@ -29,6 +29,11 @@ pub trait DbClient: Send + Sync { /// exists. async fn add_user(&self, user: &DynamoDbUser) -> DbResult<()>; + /// Update a user in the database. An error will occur if the user does not + /// already exist, has a different router type, or has a newer + /// `connected_at` timestamp. + async fn update_user(&self, user: &DynamoDbUser) -> DbResult<()>; + /// Read a user from the database async fn get_user(&self, uaid: Uuid) -> DbResult>; @@ -137,21 +142,62 @@ impl DbClientImpl { impl DbClient for DbClientImpl { async fn add_user(&self, user: &DynamoDbUser) -> DbResult<()> { let input = PutItemInput { + table_name: self.router_table.clone(), item: serde_dynamodb::to_hashmap(user)?, - table_name: self.router_table.to_string(), condition_expression: Some("attribute_not_exists(uaid)".to_string()), ..Default::default() }; retry_policy() .retry_if( - move || self.ddb.put_item(input.clone()), + || self.ddb.put_item(input.clone()), retryable_putitem_error(self.metrics.clone()), ) .await?; Ok(()) } + async fn update_user(&self, user: &DynamoDbUser) -> DbResult<()> { + let user_map = serde_dynamodb::to_hashmap(&user)?; + let input = UpdateItemInput { + table_name: self.router_table.clone(), + key: ddb_item! { uaid: s => user.uaid.to_simple().to_string() }, + update_expression: Some(format!( + "SET {}", + user_map + .keys() + .map(|key| format!("{0}=:{0}", key)) + .collect::>() + .join(", ") + )), + expression_attribute_values: Some( + user_map + .into_iter() + .map(|(key, value)| (format!(":{}", key), value)) + .collect(), + ), + condition_expression: Some( + "attribute_exists(uaid) and ( + attribute_not_exists(router_type) or + (router_type = :router_type) + ) and ( + attribute_not_exists(node_id) or + (connected_at < :connected_at) + )" + .to_string(), + ), + ..Default::default() + }; + + retry_policy() + .retry_if( + || self.ddb.update_item(input.clone()), + retryable_updateitem_error(self.metrics.clone()), + ) + .await?; + Ok(()) + } + async fn get_user(&self, uaid: Uuid) -> DbResult> { let input = GetItemInput { table_name: self.router_table.clone(), @@ -245,8 +291,7 @@ impl DbClient for DbClientImpl { // Convert the IDs from String to Uuid let channels = channels .into_iter() - .map(|s| Uuid::parse_str(&s)) - .filter_map(Result::ok) + .filter_map(|s| Uuid::parse_str(&s).ok()) .collect(); Ok(channels) diff --git a/autoendpoint/src/routes/registration.rs b/autoendpoint/src/routes/registration.rs index f5458a33b..aee89b611 100644 --- a/autoendpoint/src/routes/registration.rs +++ b/autoendpoint/src/routes/registration.rs @@ -83,9 +83,29 @@ pub async fn update_token_route( router_data_input: RouterDataInput, routers: Routers, state: Data, - request: HttpRequest, ) -> ApiResult { - unimplemented!() + // Re-register with router + debug!( + "Updating the token of UAID {} with the {} router", + path_args.uaid, path_args.router_type + ); + trace!("token = {}", router_data_input.token); + let router = routers.get(path_args.router_type); + let router_data = router.register(&router_data_input, &path_args.app_id)?; + + // Update the user in the database + let user = DynamoDbUser { + uaid: path_args.uaid, + router_type: path_args.router_type.to_string(), + router_data: Some(router_data), + ..Default::default() + }; + trace!("Updating user with UAID {}", user.uaid); + trace!("user = {:?}", user); + state.ddb.update_user(&user).await?; + + trace!("Finished updating token for UAID {}", user.uaid); + Ok(HttpResponse::Ok().finish()) } /// Increment a metric with data from the request From 1b767bf711679cac6bd8e1fea2162fbedc78693a Mon Sep 17 00:00:00 2001 From: Mark Drobnak Date: Fri, 17 Jul 2020 12:08:53 -0400 Subject: [PATCH 5/8] Fix setting the UAID in DbClient::update_user It is an error to try and set the primary key of a row via UpdateItem. --- autoendpoint/src/db/client.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/autoendpoint/src/db/client.rs b/autoendpoint/src/db/client.rs index 050295470..a49352faf 100644 --- a/autoendpoint/src/db/client.rs +++ b/autoendpoint/src/db/client.rs @@ -158,7 +158,8 @@ impl DbClient for DbClientImpl { } async fn update_user(&self, user: &DynamoDbUser) -> DbResult<()> { - let user_map = serde_dynamodb::to_hashmap(&user)?; + let mut user_map = serde_dynamodb::to_hashmap(&user)?; + user_map.remove("uaid"); let input = UpdateItemInput { table_name: self.router_table.clone(), key: ddb_item! { uaid: s => user.uaid.to_simple().to_string() }, From a84fc0d618f43b66e3cfdf696a417449a102173d Mon Sep 17 00:00:00 2001 From: Mark Drobnak Date: Fri, 17 Jul 2020 12:09:56 -0400 Subject: [PATCH 6/8] Use the actual UUID bytes (vs str bytes) when checking authorization --- autoendpoint/src/server/extractors/authorization_check.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/autoendpoint/src/server/extractors/authorization_check.rs b/autoendpoint/src/server/extractors/authorization_check.rs index 51db610fd..369bedc0d 100644 --- a/autoendpoint/src/server/extractors/authorization_check.rs +++ b/autoendpoint/src/server/extractors/authorization_check.rs @@ -7,6 +7,7 @@ use actix_web::web::Data; use actix_web::{FromRequest, HttpRequest}; use futures::future::LocalBoxFuture; use futures::FutureExt; +use uuid::Uuid; /// Verifies the request authorization via the authorization header. /// @@ -26,7 +27,9 @@ impl FromRequest for AuthorizationCheck { let uaid = req .match_info() .get("uaid") - .expect("{uaid} must be part of the path"); + .expect("{uaid} must be part of the path") + .parse::() + .map_err(|_| ApiErrorKind::NoUser)?; let state: Data = Data::extract(&req) .into_inner() .expect("No server state found"); From 361d750412fbe9639cb52c3b20fd1fece7d0ccd0 Mon Sep 17 00:00:00 2001 From: Mark Drobnak Date: Fri, 17 Jul 2020 16:30:55 -0400 Subject: [PATCH 7/8] Make the registration auth scheme check case-insensitive --- autoendpoint/src/server/extractors/authorization_check.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoendpoint/src/server/extractors/authorization_check.rs b/autoendpoint/src/server/extractors/authorization_check.rs index 369bedc0d..f050f174b 100644 --- a/autoendpoint/src/server/extractors/authorization_check.rs +++ b/autoendpoint/src/server/extractors/authorization_check.rs @@ -61,7 +61,7 @@ fn get_token_from_auth_header(header: &str) -> Option<&str> { let mut split = header.splitn(2, ' '); let scheme = split.next()?; - if scheme != "Bearer" { + if scheme.to_lowercase() != "bearer" { return None; } From ffbca6aaf45614d55a62cd31a75f37e6e3d10b94 Mon Sep 17 00:00:00 2001 From: Mark Drobnak Date: Tue, 21 Jul 2020 10:00:23 -0400 Subject: [PATCH 8/8] Fix errors after rebase --- autoendpoint/src/db/mock.rs | 6 ++++++ .../src/{server => }/extractors/authorization_check.rs | 2 +- .../extractors/registration_path_args_with_uaid.rs | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) rename autoendpoint/src/{server => }/extractors/authorization_check.rs (98%) rename autoendpoint/src/{server => }/extractors/registration_path_args_with_uaid.rs (92%) diff --git a/autoendpoint/src/db/mock.rs b/autoendpoint/src/db/mock.rs index f81bad99e..aa4ca60f1 100644 --- a/autoendpoint/src/db/mock.rs +++ b/autoendpoint/src/db/mock.rs @@ -17,6 +17,8 @@ mockall::mock! { pub DbClient { fn add_user(&self, user: &DynamoDbUser) -> DbResult<()>; + fn update_user(&self, user: &DynamoDbUser) -> DbResult<()>; + fn get_user(&self, uaid: Uuid) -> DbResult>; fn remove_user(&self, uaid: Uuid) -> DbResult<()>; @@ -47,6 +49,10 @@ impl DbClient for Arc { Arc::as_ref(self).add_user(user) } + async fn update_user(&self, user: &DynamoDbUser) -> DbResult<()> { + Arc::as_ref(self).update_user(user) + } + async fn get_user(&self, uaid: Uuid) -> DbResult> { Arc::as_ref(self).get_user(uaid) } diff --git a/autoendpoint/src/server/extractors/authorization_check.rs b/autoendpoint/src/extractors/authorization_check.rs similarity index 98% rename from autoendpoint/src/server/extractors/authorization_check.rs rename to autoendpoint/src/extractors/authorization_check.rs index f050f174b..1e5153eb8 100644 --- a/autoendpoint/src/server/extractors/authorization_check.rs +++ b/autoendpoint/src/extractors/authorization_check.rs @@ -1,6 +1,6 @@ use crate::auth::sign_with_key; use crate::error::{ApiError, ApiErrorKind}; -use crate::server::headers::util::get_header; +use crate::headers::util::get_header; use crate::server::ServerState; use actix_web::dev::{Payload, PayloadStream}; use actix_web::web::Data; diff --git a/autoendpoint/src/server/extractors/registration_path_args_with_uaid.rs b/autoendpoint/src/extractors/registration_path_args_with_uaid.rs similarity index 92% rename from autoendpoint/src/server/extractors/registration_path_args_with_uaid.rs rename to autoendpoint/src/extractors/registration_path_args_with_uaid.rs index f37c33864..18a59dfda 100644 --- a/autoendpoint/src/server/extractors/registration_path_args_with_uaid.rs +++ b/autoendpoint/src/extractors/registration_path_args_with_uaid.rs @@ -1,6 +1,6 @@ use crate::error::{ApiError, ApiErrorKind}; -use crate::server::extractors::registration_path_args::RegistrationPathArgs; -use crate::server::extractors::routers::RouterType; +use crate::extractors::registration_path_args::RegistrationPathArgs; +use crate::extractors::routers::RouterType; use crate::server::ServerState; use actix_web::dev::{Payload, PayloadStream}; use actix_web::web::Data;