-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic email mapper and initial data configs
- Loading branch information
1 parent
ab2aedf
commit 2b9d6b3
Showing
11 changed files
with
372 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use config::{Config, ConfigError, Environment, File}; | ||
use rfd_model::{storage::StoreError, NewAccessGroup}; | ||
use serde::Deserialize; | ||
use uuid::Uuid; | ||
|
||
use crate::{context::ApiContext, mapper::MapperRules, ApiPermissions}; | ||
|
||
#[derive(Debug, Deserialize)] | ||
pub struct InitialData { | ||
pub groups: Vec<InitialGroup>, | ||
pub mappers: Vec<MapperRules>, | ||
} | ||
|
||
#[derive(Debug, Deserialize)] | ||
pub struct InitialGroup { | ||
pub name: String, | ||
pub permissions: ApiPermissions, | ||
} | ||
|
||
impl InitialData { | ||
pub fn new() -> Result<Self, ConfigError> { | ||
let config = Config::builder() | ||
.add_source(File::with_name("baseline.toml").required(false)) | ||
.add_source(File::with_name("rfd-api/baseline.toml").required(false)) | ||
.add_source(Environment::default()) | ||
.build()?; | ||
|
||
config.try_deserialize() | ||
} | ||
|
||
pub async fn initialize(&self, ctx: &ApiContext) -> Result<(), StoreError> { | ||
for group in &self.groups { | ||
ctx.create_group(NewAccessGroup { | ||
id: Uuid::new_v4(), | ||
name: group.name.clone(), | ||
permissions: group.permissions.clone(), | ||
}) | ||
.await?; | ||
} | ||
|
||
for _mapper in &self.mappers { | ||
// TODO: Configure initial mappers | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,82 @@ | ||
use async_trait::async_trait; | ||
use rfd_model::storage::StoreError; | ||
use serde::Deserialize; | ||
use uuid::Uuid; | ||
|
||
use crate::{context::ApiContext, endpoints::login::UserInfo, ApiPermissions}; | ||
|
||
#[async_trait] | ||
pub trait ApiPermissionMapper: Send + Sync { | ||
async fn permissions_for(&self, ctx: &ApiContext, user: &UserInfo) -> ApiPermissions; | ||
pub trait MapperRule: Send + Sync { | ||
async fn permissions_for( | ||
&self, | ||
ctx: &ApiContext, | ||
user: &UserInfo, | ||
) -> Result<ApiPermissions, StoreError>; | ||
async fn groups_for(&self, ctx: &ApiContext, user: &UserInfo) -> Result<Vec<Uuid>, StoreError>; | ||
} | ||
|
||
#[derive(Debug, Deserialize)] | ||
pub enum MapperRules { | ||
EmailDomain(EmailDomainMapper), | ||
} | ||
|
||
#[derive(Debug, Deserialize)] | ||
pub struct EmailDomainMapper { | ||
domain: String, | ||
groups: Vec<String>, | ||
} | ||
|
||
#[async_trait] | ||
impl MapperRule for EmailDomainMapper { | ||
async fn permissions_for( | ||
&self, | ||
_ctx: &ApiContext, | ||
_user: &UserInfo, | ||
) -> Result<ApiPermissions, StoreError> { | ||
Ok(ApiPermissions::new()) | ||
} | ||
|
||
async fn groups_for(&self, ctx: &ApiContext, user: &UserInfo) -> Result<Vec<Uuid>, StoreError> { | ||
let has_email_in_domain = user | ||
.verified_emails | ||
.iter() | ||
.fold(false, |found, email| found || email.ends_with(&self.domain)); | ||
|
||
if has_email_in_domain { | ||
let groups = ctx | ||
.get_groups() | ||
.await? | ||
.into_iter() | ||
.filter_map(|group| { | ||
if self.groups.contains(&group.name) { | ||
Some(group.id) | ||
} else { | ||
None | ||
} | ||
}) | ||
.collect::<Vec<_>>(); | ||
Ok(groups) | ||
} else { | ||
Ok(vec![]) | ||
} | ||
} | ||
} | ||
|
||
#[async_trait] | ||
pub trait GroupMapper: Send + Sync { | ||
async fn groups_for(&self, ctx: &ApiContext, user: &UserInfo) -> Vec<Uuid>; | ||
impl MapperRule for MapperRules { | ||
async fn permissions_for( | ||
&self, | ||
ctx: &ApiContext, | ||
user: &UserInfo, | ||
) -> Result<ApiPermissions, StoreError> { | ||
match self { | ||
Self::EmailDomain(rule) => rule.permissions_for(ctx, user).await, | ||
} | ||
} | ||
|
||
async fn groups_for(&self, ctx: &ApiContext, user: &UserInfo) -> Result<Vec<Uuid>, StoreError> { | ||
match self { | ||
Self::EmailDomain(rule) => rule.groups_for(ctx, user).await, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DROP TABLE mapper; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
CREATE TABLE mapper ( | ||
id UUID PRIMARY KEY, | ||
name VARCHAR NOT NULL UNIQUE, | ||
rule JSONB NOT NULL, | ||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), | ||
deleted_at TIMESTAMPTZ | ||
); |
Oops, something went wrong.