Skip to content

Commit

Permalink
Shield: Add user to storage
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielleHuisman committed Dec 27, 2024
1 parent db73523 commit f162c2d
Show file tree
Hide file tree
Showing 8 changed files with 338 additions and 78 deletions.
4 changes: 3 additions & 1 deletion packages/core/shield/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub enum StorageError {
Configuration(#[from] ConfigurationError),
#[error("{0}")]
Validation(String),
#[error("{0} with ID `{1}` not found.")]
NotFound(String, String),
#[error("{0}")]
Engine(String),
}
Expand Down Expand Up @@ -52,5 +54,5 @@ pub enum ShieldError {
#[error("{0}")]
Request(String),
#[error("{0}")]
Verification(String),
Validation(String),
}
39 changes: 37 additions & 2 deletions packages/core/shield/src/storage.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use async_trait::async_trait;

use crate::{error::StorageError, user::User};
use crate::{
error::StorageError,
user::{CreateEmailAddress, CreateUser, UpdateUser, User},
};

#[async_trait]
pub trait Storage<U: User>: Send + Sync {
Expand All @@ -9,13 +12,29 @@ pub trait Storage<U: User>: Send + Sync {
async fn user_by_id(&self, user_id: &str) -> Result<Option<U>, StorageError>;

async fn user_by_email(&self, email: &str) -> Result<Option<U>, StorageError>;

async fn create_user(
&self,
user: CreateUser,
email_address: CreateEmailAddress,
) -> Result<U, StorageError>;

async fn update_user(&self, user: UpdateUser) -> Result<U, StorageError>;

async fn delete_user(&self, user_id: &str) -> Result<(), StorageError>;

// TODO: create, update, delete email address
}

#[cfg(test)]
pub(crate) mod tests {
use async_trait::async_trait;

use crate::{error::StorageError, storage::Storage, user::tests::TestUser};
use crate::{
error::StorageError,
storage::Storage,
user::{tests::TestUser, CreateEmailAddress, CreateUser, UpdateUser},
};

pub const TEST_STORAGE_ID: &str = "test";

Expand All @@ -35,5 +54,21 @@ pub(crate) mod tests {
async fn user_by_email(&self, _email: &str) -> Result<Option<TestUser>, StorageError> {
todo!("user_by_email")
}

async fn create_user(
&self,
_user: CreateUser,
_email_address: CreateEmailAddress,
) -> Result<TestUser, StorageError> {
todo!("create_user")
}

async fn update_user(&self, _user: UpdateUser) -> Result<TestUser, StorageError> {
todo!("update_user")
}

async fn delete_user(&self, _user_id: &str) -> Result<(), StorageError> {
todo!("delete_user")
}
}
}
35 changes: 33 additions & 2 deletions packages/core/shield/src/user.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
use chrono::{DateTime, Utc};

pub trait User: Send + Sync {
fn id(&self) -> String;
}

#[derive(Clone, Debug)]
pub struct CreateUser {
pub name: Option<String>,
}

#[derive(Clone, Debug)]
pub struct UpdateUser {
pub id: String,
pub name: Option<Option<String>>,
}

#[derive(Clone, Debug)]
pub struct EmailAddress {
pub id: String,
Expand All @@ -12,8 +27,24 @@ pub struct EmailAddress {
pub user_id: String,
}

pub trait User: Send + Sync {
fn id(&self) -> String;
#[derive(Clone, Debug)]
pub struct CreateEmailAddress {
pub email: String,
pub is_primary: bool,
pub is_verified: bool,
pub verification_token: Option<String>,
pub verification_token_expired_at: Option<DateTime<Utc>>,
pub verified_at: Option<DateTime<Utc>>,
}

#[derive(Clone, Debug)]
pub struct UpdateEmailAddress {
pub id: String,
pub is_primary: Option<bool>,
pub is_verified: Option<bool>,
pub verification_token: Option<Option<String>>,
pub verification_token_expired_at: Option<Option<DateTime<Utc>>>,
pub verified_at: Option<Option<DateTime<Utc>>>,
}

#[cfg(test)]
Expand Down
13 changes: 9 additions & 4 deletions packages/providers/shield-oidc/src/claims.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use openidconnect::{
core::CoreGenderClaim, EmptyAdditionalClaims, EndUserEmail, IdTokenClaims, SubjectIdentifier,
UserInfoClaims,
core::CoreGenderClaim, EmptyAdditionalClaims, EndUserEmail, EndUserName, IdTokenClaims,
LocalizedClaim, SubjectIdentifier, UserInfoClaims,
};

/// Unified interface for [`IdTokenClaims`] and [`UserInfoClaims`].
Expand All @@ -18,14 +18,19 @@ impl Claims {
}
}

// TODO: Remove allow dead code.
#[allow(dead_code)]
pub fn email(&self) -> Option<&EndUserEmail> {
match &self {
Claims::IdToken(id_token_claims) => id_token_claims.email(),
Claims::UserInfo(user_info_claims) => user_info_claims.email(),
}
}

pub fn name(&self) -> Option<&LocalizedClaim<EndUserName>> {
match &self {
Claims::IdToken(id_token_claims) => id_token_claims.name(),
Claims::UserInfo(user_info_claims) => user_info_claims.name(),
}
}
}

impl From<IdTokenClaims<EmptyAdditionalClaims, CoreGenderClaim>> for Claims {
Expand Down
Loading

0 comments on commit f162c2d

Please sign in to comment.