Skip to content

Commit

Permalink
Merge pull request #75 from shield-auth/feat/api-user
Browse files Browse the repository at this point in the history
Feat/api user
  • Loading branch information
CA-MKSingh authored Nov 7, 2024
2 parents 9e6dccd + a19a55d commit 080dbc8
Show file tree
Hide file tree
Showing 41 changed files with 1,089 additions and 943 deletions.
395 changes: 222 additions & 173 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ axum = "0.7.7"
axum-extra = { version = "0.9.4", features = ["typed-header"] }
bcrypt = "0.15.1"
chrono = { version = "0.4.38", features = ["serde"] }
config = { version = "0.14.0", features = ["yaml"] }
config = { version = "0.14.1", features = ["yaml"] }
dotenvy = "0.15.7"
futures = "0.3.31"
jsonwebtoken = "9.3.0"
once_cell = "1.20.2"
parking_lot = "0.12.3"
sea-orm = { version = "1.0.1", features = [
sea-orm = { version = "1.1.0", features = [
"macros",
"runtime-tokio-rustls",
"sqlx-postgres",
] }
sea-orm-migration = "1.0.1"
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
thiserror = "1.0.64"
tokio = { version = "1.40.0", features = ["full"] }
sea-orm-migration = "1.1.0"
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.132"
thiserror = "1.0.65"
tokio = { version = "1.41.0", features = ["full"] }
tower-http = { version = "0.6.1", features = [
"trace",
"compression-br",
Expand All @@ -39,6 +39,6 @@ tower-http = { version = "0.6.1", features = [
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
uaparser = "0.6.4"
uuid = { version = "1.10.0", features = ["v7"] }
uuid = { version = "1.11.0", features = ["v7"] }
rand = "0.8.5"
base64 = "0.22.1"
Binary file not shown.
17 changes: 0 additions & 17 deletions assets/images/flow-charts/1-shield-start-transparent.svg

This file was deleted.

Binary file removed assets/images/flow-charts/1-shield-start.png
Binary file not shown.
Binary file not shown.
17 changes: 0 additions & 17 deletions assets/images/flow-charts/2-admin-login-transparent.svg

This file was deleted.

Binary file removed assets/images/flow-charts/2-admin-login.png
Binary file not shown.
3 changes: 2 additions & 1 deletion config/env/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ database:
uri: "postgres://postgres:1234@localhost:5432"
name: shield
secrets:
signing_key: 87cc20e216861442af1bc993ad6f274b61bb65b956444da50f446b2046c0d260
signing_key: 87cc20e216861442af1bc993ad6f274b61bb65b956444da50f446b2046c0d260 # NOTE: This key must be changed in production by providing SIGNING_KEY env variable
api_key_signing_secret: 87cc20e216861442af1bc993ad6f274b61bb65b956444da50f446b2046c0d261 # NOTE: This key must be changed in production by providing API_KEY_SIGNING_SECRET env variable
logger:
level: debug
admin:
Expand Down
106 changes: 0 additions & 106 deletions docs/latest.md

This file was deleted.

36 changes: 34 additions & 2 deletions entity/src/extensions/active_enums.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
use crate::sea_orm_active_enums::ApiUserAccess;
use crate::sea_orm_active_enums::{ApiUserAccess, ApiUserScope};
use std::cmp::Ordering;

pub mod role_level {
pub const REALM_ADMIN: u32 = 10;
pub const CLIENT_ADMIN: u32 = 20;
}

pub mod access_level {
pub const READ: u32 = 10;
pub const WRITE: u32 = 20;
pub const DELETE: u32 = 30;
pub const UPDATE: u32 = 30;
pub const DELETE: u32 = 40;
pub const ADMIN: u32 = 100;
}

Expand All @@ -13,6 +19,7 @@ impl ApiUserAccess {
match self {
ApiUserAccess::Read => access_level::READ,
ApiUserAccess::Write => access_level::WRITE,
ApiUserAccess::Update => access_level::UPDATE,
ApiUserAccess::Delete => access_level::DELETE,
ApiUserAccess::Admin => access_level::ADMIN,
}
Expand All @@ -23,6 +30,19 @@ impl ApiUserAccess {
}
}

impl ApiUserScope {
fn to_level(&self) -> u32 {
match self {
ApiUserScope::Realm => role_level::REALM_ADMIN,
ApiUserScope::Client => role_level::CLIENT_ADMIN,
}
}

pub fn has_access(&self, required: ApiUserScope) -> bool {
self.to_level() <= required.to_level()
}
}

impl PartialOrd for ApiUserAccess {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.to_level().cmp(&other.to_level()))
Expand All @@ -34,3 +54,15 @@ impl Ord for ApiUserAccess {
self.to_level().cmp(&other.to_level())
}
}

impl PartialOrd for ApiUserScope {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.to_level().cmp(&other.to_level()))
}
}

impl Ord for ApiUserScope {
fn cmp(&self, other: &Self) -> Ordering {
self.to_level().cmp(&other.to_level())
}
}
1 change: 1 addition & 0 deletions entity/src/middlewares/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod api_user;
pub mod client;
pub mod realm;
pub mod refresh_token;
pub mod resource;
pub mod resource_group;
pub mod session;
Expand Down
29 changes: 29 additions & 0 deletions entity/src/middlewares/refresh_token.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use crate::{models::refresh_token, utils::check_locked_at_constraint};
use async_trait::async_trait;
use sea_orm::{entity::prelude::*, sqlx::types::chrono::Utc, ActiveValue};

#[async_trait]
impl ActiveModelBehavior for refresh_token::ActiveModel {
/// Will be triggered before insert / update
async fn before_save<C>(mut self, db: &C, _insert: bool) -> Result<Self, DbErr>
where
C: ConnectionTrait,
{
if let ActiveValue::Set(ref locked_at) = self.locked_at {
check_locked_at_constraint(locked_at)?
}

if let ActiveValue::Set(ref expires) = self.expires {
if expires < &Utc::now().fixed_offset() {
return Err(DbErr::Custom("Expires must be greater than created_at".to_owned()));
}
}

refresh_token::Entity::delete_many()
.filter(refresh_token::Column::Expires.lt(Utc::now()))
.exec(db)
.await?;

Ok(self)
}
}
23 changes: 2 additions & 21 deletions entity/src/models/api_user.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0
use super::sea_orm_active_enums::ApiUserAccess;
use super::sea_orm_active_enums::ApiUserRole;
use super::sea_orm_active_enums::ApiUserScope;
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};

Expand All @@ -10,15 +10,12 @@ use serde::{Deserialize, Serialize};
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
pub secret: String,
pub name: String,
pub description: Option<String>,
pub realm_id: Uuid,
pub client_id: Uuid,
pub role: ApiUserRole,
pub role: ApiUserScope,
pub access: ApiUserAccess,
pub created_by: Uuid,
pub updated_by: Uuid,
pub expires: DateTimeWithTimeZone,
pub locked_at: Option<DateTimeWithTimeZone>,
pub created_at: DateTimeWithTimeZone,
Expand All @@ -43,22 +40,6 @@ pub enum Relation {
on_delete = "Cascade"
)]
Realm,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::CreatedBy",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User2,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UpdatedBy",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User1,
}

impl Related<super::client::Entity> for Entity {
Expand Down
3 changes: 1 addition & 2 deletions entity/src/models/refresh_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct Model {
pub client_id: Option<Uuid>,
pub realm_id: Uuid,
pub re_used_count: i32,
pub expires: DateTimeWithTimeZone,
pub locked_at: Option<DateTimeWithTimeZone>,
pub created_at: DateTimeWithTimeZone,
pub updated_at: DateTimeWithTimeZone,
Expand Down Expand Up @@ -70,5 +71,3 @@ impl Related<super::user::Entity> for Entity {
Relation::User.def()
}
}

impl ActiveModelBehavior for ActiveModel {}
14 changes: 8 additions & 6 deletions entity/src/models/sea_orm_active_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ pub enum ApiUserAccess {
Delete,
#[sea_orm(string_value = "read")]
Read,
#[sea_orm(string_value = "update")]
Update,
#[sea_orm(string_value = "write")]
Write,
}
#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Serialize, Deserialize)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "api_user_role")]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "api_user_scope")]
#[serde(rename_all = "snake_case")]
pub enum ApiUserRole {
#[sea_orm(string_value = "client_admin")]
ClientAdmin,
#[sea_orm(string_value = "realm_admin")]
RealmAdmin,
pub enum ApiUserScope {
#[sea_orm(string_value = "client")]
Client,
#[sea_orm(string_value = "realm")]
Realm,
}
1 change: 0 additions & 1 deletion entity/src/models/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub struct Model {
pub id: Uuid,
pub first_name: String,
pub last_name: Option<String>,
#[sea_orm(unique)]
pub email: String,
pub email_verified_at: Option<DateTimeWithTimeZone>,
pub phone: Option<String>,
Expand Down
10 changes: 9 additions & 1 deletion migration/src/m20220101_000003_create_user_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl MigrationTrait for Migration {
.col(ColumnDef::new(User::Id).uuid().not_null().primary_key())
.col(ColumnDef::new(User::FirstName).string().not_null())
.col(ColumnDef::new(User::LastName).string())
.col(ColumnDef::new(User::Email).unique_key().string().not_null())
.col(ColumnDef::new(User::Email).string().not_null())
.col(ColumnDef::new(User::EmailVerifiedAt).timestamp_with_time_zone())
.col(ColumnDef::new(User::Phone).string())
.col(ColumnDef::new(User::Image).string())
Expand Down Expand Up @@ -44,6 +44,14 @@ impl MigrationTrait for Migration {
.not_null()
.default(chrono::Utc::now()),
)
.index(
Index::create()
.name("user_email_realm_id_index")
.table(User::Table)
.col(User::Email)
.col(User::RealmId)
.unique(),
)
.to_owned(),
)
.await
Expand Down
2 changes: 2 additions & 0 deletions migration/src/m20220101_000006_create_refresh_token_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ impl MigrationTrait for Migration {
.col(ColumnDef::new(RefreshToken::ClientId).uuid())
.col(ColumnDef::new(RefreshToken::RealmId).uuid().not_null())
.col(ColumnDef::new(RefreshToken::ReUsedCount).integer().not_null().default(0))
.col(ColumnDef::new(RefreshToken::Expires).timestamp_with_time_zone().not_null())
.col(ColumnDef::new(RefreshToken::LockedAt).timestamp_with_time_zone())
.col(
ColumnDef::new(RefreshToken::CreatedAt)
Expand Down Expand Up @@ -118,6 +119,7 @@ pub enum RefreshToken {
RealmId,
ReUsedCount,
LockedAt,
Expires,
CreatedAt,
UpdatedAt,
}
Loading

0 comments on commit 080dbc8

Please sign in to comment.