refactor: project structure
Build Docker Image / build-nightly (push) Successful in 3m5s Details

This commit is contained in:
subcrip 2024-04-07 16:11:24 +08:00
parent de4d6194f4
commit 09cbfbf8a6
Signed by: subcrip
SSH Key Fingerprint: SHA256:dFPFi68d8C87YkFkEBU4TkcrYRySWpekRR1hbnDWUCw
8 changed files with 226 additions and 167 deletions

178
src/db.rs
View File

@ -1,160 +1,5 @@
use uuid::Uuid; use uuid::Uuid;
/// An abstract of OAuth application. The secret should be shown only once. After registration, we
/// should operate on `OAuthHashedApplication`.
pub struct OAuthApplication {
pub client_id: Uuid,
pub client_secret: crate::misc::U256,
pub client_name: String,
pub client_desc: String,
}
impl OAuthApplication {
// TEST: functionality
pub fn create(client_name: &String, client_desc: &String) -> Self {
Self {
client_id: Uuid::new_v4(),
client_secret: crate::misc::random_256(),
client_name: client_name.to_owned(),
client_desc: client_desc.to_owned()
}
}
pub fn new(client_id: &Uuid, client_secret: &crate::misc::U256, client_name: &String, client_desc: &String) -> Self {
Self {
client_id: client_id.to_owned(),
client_secret: client_secret.to_owned(),
client_name: client_name.to_owned(),
client_desc:client_desc.to_owned(),
}
}
}
/// An abstract of OAuth application. The secret is hashed so it's safe to store it in the
/// database.
pub struct OAuthHashedApplication {
pub client_id: Uuid,
pub client_secret: Vec<u8>,
pub client_name: String,
pub client_desc: String,
}
impl OAuthHashedApplication {
// TEST: functionality
pub fn from(app: &OAuthApplication) -> Self {
Self {
client_id: app.client_id,
client_secret: crate::misc::digest(&app.client_secret),
client_name: app.client_name.to_owned(),
client_desc: app.client_desc.to_owned(),
}
}
pub fn new(client_id: &Uuid, client_secret: &Vec<u8>, client_name: &String, client_desc: &String) -> Self {
Self {
client_id: client_id.to_owned(),
client_secret: client_secret.to_owned(),
client_name: client_name.to_owned(),
client_desc: client_desc.to_owned(),
}
}
}
pub struct OAuthApplicationAccess {
pub access_id: Uuid,
pub client_id: Uuid,
pub scope_id: Uuid,
}
impl OAuthApplicationAccess {
pub fn create(app: &OAuthHashedApplication, scope: &OAuthScope) -> Self {
Self {
access_id: Uuid::new_v4(),
client_id: app.client_id,
scope_id: scope.scope_id
}
}
pub fn new(access_id: &Uuid, client_id: &Uuid, scope_id: &Uuid) -> Self {
Self {
access_id: access_id.to_owned(),
client_id: client_id.to_owned(),
scope_id: scope_id.to_owned()
}
}
}
pub struct OAuthScope {
pub scope_id: Uuid,
pub resource_id: Uuid,
pub scope_name: String,
pub scope_desc: String,
}
impl OAuthScope {
// TEST: functionality
pub fn create(resource_id: &Uuid, name: &String, description: &String) -> Self {
Self {
scope_id: Uuid::new_v4(),
resource_id: resource_id.to_owned(),
scope_name: name.to_owned(),
scope_desc: description.to_owned(),
}
}
pub fn new(scope_id: &Uuid, resource_id: &Uuid, scope_name: &String, scope_desc: &String) -> Self {
Self {
scope_id: scope_id.to_owned(),
resource_id: resource_id.to_owned(),
scope_name: scope_name.to_owned(),
scope_desc: scope_desc.to_owned(),
}
}
}
pub struct OAuthUser {
pub user_id: Uuid,
pub user_name: String,
}
impl OAuthUser {
pub fn create(name: &String) -> Self {
Self {
user_id: Uuid::new_v4(),
user_name: name.to_owned(),
}
}
pub fn new(user_id: &Uuid, user_name: &String) -> Self {
Self {
user_id: user_id.to_owned(),
user_name: user_name.to_owned(),
}
}
}
pub struct OAuthResource {
pub resource_id: Uuid,
pub resource_name: String,
pub resource_desc: String,
}
impl OAuthResource {
pub fn create(name: &String, description: &String) -> Self {
Self {
resource_id: Uuid::new_v4(),
resource_name: name.to_owned(),
resource_desc: description.to_owned(),
}
}
pub fn new(resource_id: &Uuid, resource_name: &String, resource_desc: &String) -> Self {
Self {
resource_id: resource_id.to_owned(),
resource_name: resource_name.to_owned(),
resource_desc: resource_desc.to_owned(),
}
}
}
/// Wrapper struct for Postgres database with APIs related to OAuth database operations. /// Wrapper struct for Postgres database with APIs related to OAuth database operations.
pub struct OAuthDatabase { pub struct OAuthDatabase {
client: tokio_postgres::Client, client: tokio_postgres::Client,
@ -201,51 +46,50 @@ impl OAuthDatabase {
self.psql_execute("create table Scopes(scope_id uuid primary key, resource_id uuid, scope_name text, scope_desc text)", &[]).await?; self.psql_execute("create table Scopes(scope_id uuid primary key, resource_id uuid, scope_name text, scope_desc text)", &[]).await?;
self.psql_execute("create table ApplicationAccess(access_id uuid primary key, client_id uuid, scope_id uuid)", &[]).await?; self.psql_execute("create table ApplicationAccess(access_id uuid primary key, client_id uuid, scope_id uuid)", &[]).await?;
self.psql_execute("create table Users(user_id uuid primary key, user_name text)", &[]).await?; self.psql_execute("create table Users(user_id uuid primary key, user_name text)", &[]).await?;
// TODO: struct
self.psql_execute("create table MasterDBAccess(master_db_token bytea primary key, master_db_desc text)", &[]).await?; self.psql_execute("create table MasterDBAccess(master_db_token bytea primary key, master_db_desc text)", &[]).await?;
Ok(()) Ok(())
} }
/// Register an application. /// Register an application.
/// Applicant: client /// Applicant: client
pub async fn trusted_register_application(&mut self, name: &String, description: &String) -> Result<OAuthApplication, tokio_postgres::Error> { pub async fn trusted_register_application(&mut self, name: &String, description: &String) -> Result<crate::oauth_types::oauth_application::OAuthApplication, tokio_postgres::Error> {
// TEST: functionality // TEST: functionality
let app = OAuthApplication::create(name, description); let app = crate::oauth_types::oauth_application::OAuthApplication::create(name, description);
let app_hash = OAuthHashedApplication::from(&app); let app_hash = crate::oauth_types::oauth_application::OAuthHashedApplication::from(&app);
self.psql_execute("insert into Applications (client_id, client_secret, client_name, client_desc) values ($1, $2, $3, $4)", &[&app_hash.client_id, &app_hash.client_secret, &app_hash.client_name, &app_hash.client_desc]).await?; self.psql_execute("insert into Applications (client_id, client_secret, client_name, client_desc) values ($1, $2, $3, $4)", &[&app_hash.client_id, &app_hash.client_secret, &app_hash.client_name, &app_hash.client_desc]).await?;
Ok(app) Ok(app)
} }
/// Register a resource. /// Register a resource.
/// Applicant: resource /// Applicant: resource
pub async fn trusted_register_resource(&mut self, name: &String, description: &String) -> Result<OAuthResource, tokio_postgres::Error> { pub async fn trusted_register_resource(&mut self, name: &String, description: &String) -> Result<crate::oauth_types::oauth_resource::OAuthResource, tokio_postgres::Error> {
// TEST: functionality // TEST: functionality
let resource = OAuthResource::create(name, description); let resource = crate::oauth_types::oauth_resource::OAuthResource::create(name, description);
self.psql_execute("insert into Resources (resource_id, resource_name, resource_desc) values ($1, $2, $3)", &[&resource.resource_id, &resource.resource_name, &resource.resource_desc]).await?; self.psql_execute("insert into Resources (resource_id, resource_name, resource_desc) values ($1, $2, $3)", &[&resource.resource_id, &resource.resource_name, &resource.resource_desc]).await?;
Ok(resource) Ok(resource)
} }
/// Register a scope. /// Register a scope.
/// Applicant: resource /// Applicant: resource
pub async fn trusted_register_scope(&mut self, resource_id: &Uuid, name: &String, description: &String) -> Result<OAuthScope, tokio_postgres::Error> { pub async fn trusted_register_scope(&mut self, resource_id: &Uuid, name: &String, description: &String) -> Result<crate::oauth_types::oauth_scope::OAuthScope, tokio_postgres::Error> {
// TEST: functionality // TEST: functionality
let scope = OAuthScope::create(resource_id, name, description); let scope = crate::oauth_types::oauth_scope::OAuthScope::create(resource_id, name, description);
self.psql_execute("insert into Scopes (scope_id, resource_id, scope_desc) values ($1, $2, $3)", &[&scope.scope_id, &scope.resource_id, &scope.scope_desc]).await?; self.psql_execute("insert into Scopes (scope_id, resource_id, scope_desc) values ($1, $2, $3)", &[&scope.scope_id, &scope.resource_id, &scope.scope_desc]).await?;
Ok(scope) Ok(scope)
} }
/// Register an access relation. /// Register an access relation.
/// Applicant: client /// Applicant: client
pub async fn trusted_register_access(&mut self, app: &OAuthHashedApplication, scope: &OAuthScope) -> Result<(), tokio_postgres::Error> { pub async fn trusted_register_access(&mut self, app: &crate::oauth_types::oauth_application::OAuthHashedApplication, scope: &crate::oauth_types::oauth_scope::OAuthScope) -> Result<(), tokio_postgres::Error> {
let access = OAuthApplicationAccess::create(app, scope); let access = crate::oauth_types::oauth_access::OAuthApplicationAccess::create(app, scope);
self.psql_execute("insert into ApplicationAccess(access_id, client_id, scope_id) values($1, $2, $3)", &[&access.access_id, &access.client_id, &access.scope_id]).await?; self.psql_execute("insert into ApplicationAccess(access_id, client_id, scope_id) values($1, $2, $3)", &[&access.access_id, &access.client_id, &access.scope_id]).await?;
Ok(()) Ok(())
} }
/// Register a user. /// Register a user.
/// Applicant: resource /// Applicant: resource
pub async fn trusted_register_user(&mut self, name: &String) -> Result<OAuthUser, tokio_postgres::Error> { pub async fn trusted_register_user(&mut self, name: &String) -> Result<crate::oauth_types::oauth_user::OAuthUser, tokio_postgres::Error> {
let user = OAuthUser::create(name); let user = crate::oauth_types::oauth_user::OAuthUser::create(name);
self.psql_execute("insert into Users(user_id, user_name) values ($1, $2)", &[&user.user_id, &user.user_name]).await?; self.psql_execute("insert into Users(user_id, user_name) values ($1, $2)", &[&user.user_id, &user.user_name]).await?;
Ok(user) Ok(user)
} }

View File

@ -2,6 +2,7 @@ use tide::Request;
use tide::prelude::*; use tide::prelude::*;
mod db; mod db;
mod oauth_types;
mod misc; mod misc;
#[tokio::main] #[tokio::main]

5
src/oauth_types/mod.rs Normal file
View File

@ -0,0 +1,5 @@
pub mod oauth_application;
pub mod oauth_scope;
pub mod oauth_user;
pub mod oauth_resource;
pub mod oauth_access;

View File

@ -0,0 +1,70 @@
use uuid::Uuid;
pub struct OAuthApplicationAccess {
pub access_id: Uuid,
pub client_id: Uuid,
pub scope_id: Uuid,
}
impl OAuthApplicationAccess {
pub fn create(app: &crate::oauth_types::oauth_application::OAuthHashedApplication, scope: &crate::oauth_types::oauth_scope::OAuthScope) -> Self {
Self {
access_id: Uuid::new_v4(),
client_id: app.client_id,
scope_id: scope.scope_id
}
}
pub fn new(access_id: &Uuid, client_id: &Uuid, scope_id: &Uuid) -> Self {
Self {
access_id: access_id.to_owned(),
client_id: client_id.to_owned(),
scope_id: scope_id.to_owned()
}
}
}
pub struct OAuthMasterDBAccess {
pub master_db_token: crate::misc::U256,
pub master_db_desc: String,
}
impl OAuthMasterDBAccess {
// TEST: functionality
pub fn create(description: &String) -> Self {
Self {
master_db_token: crate::misc::random_256(),
master_db_desc: description.to_owned(),
}
}
pub fn new(master_db_token: &crate::misc::U256, master_db_desc: &String) -> Self {
Self {
master_db_token: master_db_token.to_owned(),
master_db_desc: master_db_desc.to_owned(),
}
}
}
pub struct OAuthHashedMasterDBAccess {
pub master_db_token: Vec<u8>,
pub master_db_desc: String,
}
impl OAuthHashedMasterDBAccess {
// TEST: functionality
pub fn from(access: &OAuthMasterDBAccess) -> Self {
Self {
master_db_token: crate::misc::digest(&access.master_db_token),
master_db_desc: access.master_db_desc.to_owned(),
}
}
pub fn new(master_db_token: &Vec<u8>, master_db_desc: &String) -> Self {
Self {
master_db_token: master_db_token.to_owned(),
master_db_desc: master_db_desc.to_owned(),
}
}
}

View File

@ -0,0 +1,61 @@
use uuid::Uuid;
/// An abstract of OAuth application. The secret should be shown only once. After registration, we
/// should operate on `OAuthHashedApplication`.
pub struct OAuthApplication {
pub client_id: Uuid,
pub client_secret: crate::misc::U256,
pub client_name: String,
pub client_desc: String,
}
impl OAuthApplication {
// TEST: functionality
pub fn create(client_name: &String, client_desc: &String) -> Self {
Self {
client_id: Uuid::new_v4(),
client_secret: crate::misc::random_256(),
client_name: client_name.to_owned(),
client_desc: client_desc.to_owned()
}
}
pub fn new(client_id: &Uuid, client_secret: &crate::misc::U256, client_name: &String, client_desc: &String) -> Self {
Self {
client_id: client_id.to_owned(),
client_secret: client_secret.to_owned(),
client_name: client_name.to_owned(),
client_desc: client_desc.to_owned(),
}
}
}
/// An abstract of OAuth application. The secret is hashed so it's safe to store it in the
/// database.
pub struct OAuthHashedApplication {
pub client_id: Uuid,
pub client_secret: Vec<u8>,
pub client_name: String,
pub client_desc: String,
}
impl OAuthHashedApplication {
// TEST: functionality
pub fn from(app: &OAuthApplication) -> Self {
Self {
client_id: app.client_id,
client_secret: crate::misc::digest(&app.client_secret),
client_name: app.client_name.to_owned(),
client_desc: app.client_desc.to_owned(),
}
}
pub fn new(client_id: &Uuid, client_secret: &Vec<u8>, client_name: &String, client_desc: &String) -> Self {
Self {
client_id: client_id.to_owned(),
client_secret: client_secret.to_owned(),
client_name: client_name.to_owned(),
client_desc: client_desc.to_owned(),
}
}
}

View File

@ -0,0 +1,26 @@
use uuid::Uuid;
pub struct OAuthResource {
pub resource_id: Uuid,
pub resource_name: String,
pub resource_desc: String,
}
impl OAuthResource {
// TEST: functionality
pub fn create(name: &String, description: &String) -> Self {
Self {
resource_id: Uuid::new_v4(),
resource_name: name.to_owned(),
resource_desc: description.to_owned(),
}
}
pub fn new(resource_id: &Uuid, resource_name: &String, resource_desc: &String) -> Self {
Self {
resource_id: resource_id.to_owned(),
resource_name: resource_name.to_owned(),
resource_desc: resource_desc.to_owned(),
}
}
}

View File

@ -0,0 +1,30 @@
use uuid::Uuid;
pub struct OAuthScope {
pub scope_id: Uuid,
pub resource_id: Uuid,
pub scope_name: String,
pub scope_desc: String,
}
impl OAuthScope {
// TEST: functionality
pub fn create(resource_id: &Uuid, name: &String, description: &String) -> Self {
Self {
scope_id: Uuid::new_v4(),
resource_id: resource_id.to_owned(),
scope_name: name.to_owned(),
scope_desc: description.to_owned(),
}
}
pub fn new(scope_id: &Uuid, resource_id: &Uuid, scope_name: &String, scope_desc: &String) -> Self {
Self {
scope_id: scope_id.to_owned(),
resource_id: resource_id.to_owned(),
scope_name: scope_name.to_owned(),
scope_desc: scope_desc.to_owned(),
}
}
}

View File

@ -0,0 +1,22 @@
use uuid::Uuid;
pub struct OAuthUser {
pub user_id: Uuid,
pub user_name: String,
}
impl OAuthUser {
pub fn create(name: &String) -> Self {
Self {
user_id: Uuid::new_v4(),
user_name: name.to_owned(),
}
}
pub fn new(user_id: &Uuid, user_name: &String) -> Self {
Self {
user_id: user_id.to_owned(),
user_name: user_name.to_owned(),
}
}
}