Skip to content

Commit

Permalink
Merge branch 'main' into add-contact-email
Browse files Browse the repository at this point in the history
  • Loading branch information
augustuswm committed Nov 19, 2024
2 parents bd9a91c + 032cc12 commit 90cffd1
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 28 deletions.
34 changes: 17 additions & 17 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ http = "1"
http-body-util = "0.1.2"
hyper = "1.5.0"
jsonwebtoken = "9.3.0"
mockall = "0.13.0"
mockall = "0.13.1"
newtype-uuid = { version = "1.1.3", features = ["schemars08", "serde", "v4"] }
oauth2 = { version = "4.4.2", default-features = false, features = ["rustls-tls"] }
partial-struct = { git = "https://github.com/oxidecomputer/partial-struct" }
Expand Down
32 changes: 22 additions & 10 deletions v-api/src/endpoints/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ mod macros {

// DEVICE CODE

// Get the metadata about an OAuth provider necessary to begin a device code exchange
/// Retrieve the metadata about an OAuth provider
#[endpoint {
method = GET,
path = "/login/oauth/{provider}/device"
Expand All @@ -314,6 +314,7 @@ mod macros {
get_device_provider_op(&rqctx, path).await
}

/// Exchange an OAuth device code request for an access token
#[endpoint {
method = POST,
path = "/login/oauth/{provider}/device/exchange",
Expand All @@ -327,8 +328,9 @@ mod macros {
exchange_device_token_op(&rqctx, path, body).await
}

// MAGIC LINK
// MAGIC LINK

/// Send a new magic link authentication link
#[endpoint {
method = POST,
path = "/login/magic/{channel}/send"
Expand All @@ -341,6 +343,7 @@ mod macros {
magic_link_send_op(&rqctx, path, body).await
}

/// Exchange a magic link access code for an access token
#[endpoint {
method = POST,
path = "/login/magic/{channel}/exchange"
Expand Down Expand Up @@ -392,7 +395,7 @@ mod macros {

// API USER

/// Retrieve the user information of the calling user
/// View details for the calling user
#[endpoint {
method = GET,
path = "/self",
Expand All @@ -403,7 +406,7 @@ mod macros {
get_self_op(&rqctx).await
}

/// Get user information for a given user id
/// View details for a user
#[endpoint {
method = GET,
path = "/api-user/{user_id}",
Expand All @@ -415,7 +418,7 @@ mod macros {
get_api_user_op(&rqctx, path).await
}

/// Create a new user with a given set of permissions
/// Create a new user
#[endpoint {
method = POST,
path = "/api-user",
Expand All @@ -440,7 +443,7 @@ mod macros {
update_api_user_op(&rqctx, path.into_inner(), body.into_inner()).await
}

/// List the active and expired API tokens for a given user
/// List api keys for a user
#[endpoint {
method = GET,
path = "/api-user/{user_id}/token",
Expand All @@ -452,8 +455,7 @@ mod macros {
list_api_user_tokens_op(&rqctx, path.into_inner()).await
}

// Create a new API token for a given user with a specific set of permissions and expiration. This
// is the only time that the returned token will be accessible
/// Create a new api key for a user
#[endpoint {
method = POST,
path = "/api-user/{user_id}/token",
Expand All @@ -466,7 +468,7 @@ mod macros {
create_api_user_token_op(&rqctx, path.into_inner(), body.into_inner()).await
}

// Get details for a specific API token
/// View details of an api key for a user
#[endpoint {
method = GET,
path = "/api-user/{user_id}/token/{api_key_id}",
Expand All @@ -478,7 +480,7 @@ mod macros {
get_api_user_token_op(&rqctx, path.into_inner()).await
}

// Revoke a specific API token so it can no longer be used
/// Revoke an api key for a user
#[endpoint {
method = DELETE,
path = "/api-user/{user_id}/token/{api_key_id}",
Expand All @@ -490,6 +492,7 @@ mod macros {
delete_api_user_token_op(&rqctx, path.into_inner()).await
}

/// Add a user to a group
#[endpoint {
method = POST,
path = "/api-user/{user_id}/group",
Expand All @@ -502,6 +505,7 @@ mod macros {
add_api_user_to_group_op(&rqctx, path.into_inner(), body.into_inner()).await
}

/// Remove a user from a group
#[endpoint {
method = DELETE,
path = "/api-user/{user_id}/group/{group_id}",
Expand All @@ -528,6 +532,7 @@ mod macros {

// GROUPS

/// List all groups
#[endpoint {
method = GET,
path = "/group",
Expand All @@ -538,6 +543,7 @@ mod macros {
get_groups_op(&rqctx).await
}

/// Create a group
#[endpoint {
method = POST,
path = "/group",
Expand All @@ -549,6 +555,7 @@ mod macros {
create_group_op(&rqctx, body.into_inner()).await
}

/// Update a group
#[endpoint {
method = PUT,
path = "/group/{group_id}",
Expand All @@ -561,6 +568,7 @@ mod macros {
update_group_op(&rqctx, path.into_inner(), body.into_inner()).await
}

/// Delete a group
#[endpoint {
method = DELETE,
path = "/group/{group_id}",
Expand All @@ -574,6 +582,7 @@ mod macros {

// MAPPERS

/// List all mappers
#[endpoint {
method = GET,
path = "/mapper",
Expand All @@ -585,6 +594,7 @@ mod macros {
get_mappers_op(&rqctx, query.into_inner()).await
}

/// Create a mapper
#[endpoint {
method = POST,
path = "/mapper",
Expand All @@ -596,6 +606,7 @@ mod macros {
create_mapper_op(&rqctx, body.into_inner()).await
}

/// Delete a mapper
#[endpoint {
method = DELETE,
path = "/mapper/{mapper_id}",
Expand All @@ -611,6 +622,7 @@ mod macros {
use v_api::endpoints::login::local::{local_login_op, LocalLogin};

#[cfg(feature = "local-dev")]
/// Login as a local development user
#[endpoint {
method = POST,
path = "/login/local"
Expand Down
9 changes: 9 additions & 0 deletions v-api/src/mapper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ pub mod email_domain;
pub mod github_username;

#[async_trait]
/// Mapping rules that determine permissions and groups for users
pub trait MapperRule<T>: Send + Sync
where
T: VAppPermission,
{
/// Determines the permissions for a given user.
async fn permissions_for(&self, user: &UserInfo) -> Result<Permissions<T>, StoreError>;
/// Determines the access groups for a given user.
async fn groups_for(
&self,
user: &UserInfo,
Expand All @@ -54,11 +57,15 @@ pub enum MappingEngineError {
Other(Box<dyn StdError + Send + Sync + 'static>),
}

/// Interface for generating mapping rules from mapper configurations
pub trait MappingEngine<T>: Send + Sync + 'static {
/// Creates a new mapping rule from a Mapper configuration
fn create_mapping(&self, value: Mapper) -> Result<Box<dyn MapperRule<T>>, MappingEngineError>;
/// Validates whether the provided data represents a known mapping rule
fn validate_mapping_data(&self, value: &Value) -> bool;
}

/// Default implementation of the MappingEngine trait
pub struct DefaultMappingEngine<T> {
caller: Caller<T>,
group: GroupContext<T>,
Expand All @@ -73,12 +80,14 @@ where
}
}

/// The default mapping rule configurations that are supported by the default mapping engine
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
#[serde(tag = "rule", rename_all = "snake_case")]
pub enum MappingRulesData<T> {
Default(DefaultMapperData<T>),
EmailAddress(EmailAddressMapperData<T>),
EmailDomain(EmailDomainMapperData<T>),
#[serde(rename = "github_username")]
GitHubUsername(GitHubUsernameMapperData<T>),
}

Expand Down

0 comments on commit 90cffd1

Please sign in to comment.