diff --git a/api/src/guards/request/auth/admin.rs b/api/src/guards/request/auth/admin.rs index b22a145..18ce925 100644 --- a/api/src/guards/request/auth/admin.rs +++ b/api/src/guards/request/auth/admin.rs @@ -1,4 +1,4 @@ -use entity::candidate::Model as Admin; +use entity::admin::Model as Admin; use portfolio_core::sea_orm::prelude::Uuid; use portfolio_core::services::admin_service::AdminService; use rocket::http::Status; diff --git a/core/src/database/mutation/session.rs b/core/src/database/mutation/session.rs index db82b4b..068646e 100644 --- a/core/src/database/mutation/session.rs +++ b/core/src/database/mutation/session.rs @@ -8,13 +8,15 @@ use crate::Mutation; impl Mutation { pub async fn insert_session( db: &DbConn, - user_id: i32, + user_id: Option, + admin_id: Option, random_uuid: Uuid, ip_addr: String, ) -> Result { session::ActiveModel { id: Set(random_uuid), user_id: Set(user_id), + admin_id: Set(admin_id), ip_address: Set(ip_addr), created_at: Set(Utc::now().naive_local()), expires_at: Set(Utc::now() diff --git a/core/src/database/query/admin.rs b/core/src/database/query/admin.rs index fffdfd0..a4700a3 100644 --- a/core/src/database/query/admin.rs +++ b/core/src/database/query/admin.rs @@ -1,10 +1,10 @@ use crate::Query; -use ::entity::{candidate, candidate::Entity as Admin}; +use ::entity::{admin, admin::Entity as Admin}; use sea_orm::*; impl Query { - pub async fn find_admin_by_id(db: &DbConn, id: i32) -> Result, DbErr> { + pub async fn find_admin_by_id(db: &DbConn, id: i32) -> Result, DbErr> { Admin::find_by_id(id).one(db).await } diff --git a/core/src/database/query/session.rs b/core/src/database/query/session.rs index 23ec16c..2b8ed9c 100644 --- a/core/src/database/query/session.rs +++ b/core/src/database/query/session.rs @@ -1,18 +1,26 @@ use crate::Query; use ::entity::{session, session::Entity as Session}; -use sea_orm::*; use sea_orm::prelude::Uuid; +use sea_orm::*; impl Query { - pub async fn find_session_by_uuid(db: &DbConn, uuid: Uuid) -> Result, DbErr> { + pub async fn find_session_by_uuid( + db: &DbConn, + uuid: Uuid, + ) -> Result, DbErr> { Session::find_by_id(uuid).one(db).await } // find session by user id - pub async fn find_sessions_by_user_id(db: &DbConn, user_id: i32) -> Result, DbErr> { + pub async fn find_sessions_by_user_id( + db: &DbConn, + user_id: Option, + admin_id: Option, + ) -> Result, DbErr> { Session::find() .filter(session::Column::UserId.eq(user_id)) + .filter(session::Column::AdminId.eq(admin_id)) .all(db) .await } @@ -20,18 +28,20 @@ impl Query { #[cfg(test)] mod tests { - use sea_orm::DbConn; use entity::candidate; - use sea_orm::{Schema, Database, DbBackend, sea_query::TableCreateStatement, ConnectionTrait}; - + use sea_orm::DbConn; + use sea_orm::{sea_query::TableCreateStatement, ConnectionTrait, Database, DbBackend, Schema}; + #[cfg(test)] async fn get_memory_sqlite_connection() -> DbConn { let base_url = "sqlite::memory:"; let db: DbConn = Database::connect(base_url).await.unwrap(); - + let schema = Schema::new(DbBackend::Sqlite); let stmt: TableCreateStatement = schema.create_table_from_entity(candidate::Entity); - db.execute(db.get_database_backend().build(&stmt)).await.unwrap(); + db.execute(db.get_database_backend().build(&stmt)) + .await + .unwrap(); db } -} \ No newline at end of file +} diff --git a/core/src/services/admin_service.rs b/core/src/services/admin_service.rs index fdadbe4..407b6b4 100644 --- a/core/src/services/admin_service.rs +++ b/core/src/services/admin_service.rs @@ -1,35 +1,29 @@ -use entity::candidate; -use sea_orm::{DbConn, prelude::Uuid}; +use entity::admin; +use sea_orm::{prelude::Uuid, DbConn}; use crate::error::ServiceError; -use super::session_service::SessionService; +use super::session_service::{SessionService, AdminUser}; pub struct AdminService; impl AdminService { pub async fn login( db: &DbConn, - user_id: i32, + admin_id: i32, password: String, - ip_addr: String + ip_addr: String, ) -> Result { - SessionService::new_session(db, user_id, password, ip_addr).await + SessionService::new_session(db, None, Some(admin_id), password, ip_addr).await } - pub async fn auth( - db: &DbConn, - session_uuid: Uuid, - ) -> Result { + pub async fn auth(db: &DbConn, session_uuid: Uuid) -> Result { match SessionService::auth_user_session(db, session_uuid).await { - Ok(user) => { - if user.is_admin { - Ok(user) - } else { - Err(ServiceError::Forbidden) - } + Ok(user) => match user { + AdminUser::Admin(admin) => Ok(admin), + AdminUser::User(_) => Err(ServiceError::DbError), }, - Err(e) => Err(e) + Err(e) => Err(e), } } -} \ No newline at end of file +} diff --git a/core/src/services/candidate_service.rs b/core/src/services/candidate_service.rs index 1791655..f026edc 100644 --- a/core/src/services/candidate_service.rs +++ b/core/src/services/candidate_service.rs @@ -8,7 +8,7 @@ use crate::{ Mutation, Query, }; -use super::session_service::SessionService; +use super::session_service::{AdminUser, SessionService}; const FIELD_OF_STUDY_PREFIXES: [&str; 3] = ["101", "102", "103"]; @@ -150,11 +150,17 @@ impl CandidateService { password: String, ip_addr: String, ) -> Result { - SessionService::new_session(db, user_id, password, ip_addr).await + SessionService::new_session(db, Some(user_id), None, password, ip_addr).await } pub async fn auth(db: &DbConn, session_uuid: Uuid) -> Result { - SessionService::auth_user_session(db, session_uuid).await + match SessionService::auth_user_session(db, session_uuid).await { + Ok(user) => match user { + AdminUser::User(candidate) => Ok(candidate), + AdminUser::Admin(_) => Err(ServiceError::DbError), + }, + Err(e) => Err(e), + } } fn is_application_id_valid(application_id: i32) -> bool { @@ -188,7 +194,7 @@ mod tests { #[cfg(test)] async fn get_memory_sqlite_connection() -> DbConn { - use entity::candidate; + use entity::{admin, candidate}; use sea_orm::Schema; use sea_orm::{sea_query::TableCreateStatement, ConnectionTrait, DbBackend}; @@ -197,9 +203,15 @@ mod tests { let schema = Schema::new(DbBackend::Sqlite); let stmt: TableCreateStatement = schema.create_table_from_entity(candidate::Entity); + + let stmt2: TableCreateStatement = schema.create_table_from_entity(admin::Entity); + db.execute(db.get_database_backend().build(&stmt)) .await .unwrap(); + db.execute(db.get_database_backend().build(&stmt2)) + .await + .unwrap(); db } diff --git a/core/src/services/session_service.rs b/core/src/services/session_service.rs index 1e56ab8..f827679 100644 --- a/core/src/services/session_service.rs +++ b/core/src/services/session_service.rs @@ -1,22 +1,39 @@ use std::cmp::min; -use entity::candidate; -use sea_orm::{DatabaseConnection, prelude::Uuid, ModelTrait}; +use entity::{admin, candidate}; +use sea_orm::{prelude::Uuid, DatabaseConnection, ModelTrait}; -use crate::{crypto::{self}, Query, error::{ServiceError}, Mutation}; +use crate::{ + crypto::{self}, + error::ServiceError, + Mutation, Query, +}; + +pub enum AdminUser { + Admin(entity::admin::Model), + User(entity::candidate::Model), +} -// TODO: generics pub(in crate::services) struct SessionService; impl SessionService { /// Delete n old sessions for user - async fn delete_old_sessions(db: &DatabaseConnection, user_id: i32, keep_n_recent: usize) -> Result<(), ServiceError> { - let mut sessions = Query::find_sessions_by_user_id(db, user_id).await.unwrap(); - - sessions.sort_by_key(|s| s.created_at); + async fn delete_old_sessions( + db: &DatabaseConnection, + user_id: Option, + admin_id: Option, + keep_n_recent: usize, + ) -> Result<(), ServiceError> { + let mut sessions = Query::find_sessions_by_user_id(db, user_id, admin_id) + .await + .unwrap(); - - for session in sessions.iter().take(sessions.len() - min(sessions.len(), keep_n_recent)) { + sessions.sort_by_key(|s| s.created_at); + + for session in sessions + .iter() + .take(sessions.len() - min(sessions.len(), keep_n_recent)) + { Mutation::delete_session(db, session.id).await.unwrap(); } @@ -24,49 +41,92 @@ impl SessionService { } /// Authenticate user by application id and password and generate a new session - pub async fn new_session(db: &DatabaseConnection, user_id: i32, password: String, ip_addr: String) -> Result { - let candidate = match Query::find_candidate_by_id(db, user_id).await { - Ok(candidate) => match candidate { - Some(candidate) => candidate, - None => return Err(ServiceError::UserNotFound) - }, - Err(_) => {return Err(ServiceError::DbError)} - }; - - // compare passwords - match crypto::verify_password(password,candidate.code.clone()).await { - Ok(valid) => { - if !valid { - return Err(ServiceError::InvalidCredentials) - } - }, - Err(_) => {return Err(ServiceError::InvalidCredentials)} + pub async fn new_session( + db: &DatabaseConnection, + user_id: Option, + admin_id: Option, + password: String, + ip_addr: String, + ) -> Result { + if user_id.is_none() && admin_id.is_none() { + return Err(ServiceError::UserNotFoundBySessionId); + } + + if admin_id.is_none() { + // unwrap is safe here + let candidate = match Query::find_candidate_by_id(db, user_id.unwrap()).await { + Ok(candidate) => match candidate { + Some(candidate) => candidate, + None => return Err(ServiceError::UserNotFound), + }, + Err(_) => return Err(ServiceError::DbError), + }; + + // compare passwords + match crypto::verify_password(password.clone(), candidate.code.clone()).await { + Ok(valid) => { + if !valid { + return Err(ServiceError::InvalidCredentials); + } + } + Err(_) => return Err(ServiceError::InvalidCredentials), + } + } + + if user_id.is_none() { + // unwrap is safe here + let admin = match Query::find_admin_by_id(db, admin_id.unwrap()).await { + Ok(admin) => match admin { + Some(admin) => admin, + None => return Err(ServiceError::UserNotFound), + }, + Err(_) => return Err(ServiceError::DbError), + }; + + // compare passwords + match crypto::verify_password(password.clone(), admin.password.clone()).await { + Ok(valid) => { + if !valid { + return Err(ServiceError::InvalidCredentials); + } + } + Err(_) => return Err(ServiceError::InvalidCredentials), + } } - // user is authenticated, generate a new session let random_uuid: Uuid = Uuid::new_v4(); - let session = match Mutation::insert_session(db, user_id, random_uuid, ip_addr).await { - Ok(session) => session, - Err(_) => return Err(ServiceError::DbError) - }; + let session = + match Mutation::insert_session(db, user_id, admin_id, random_uuid, ip_addr).await { + Ok(session) => session, + Err(e) => { + eprintln!("Error creating session: {}", e); + return Err(ServiceError::DbError); + } + }; // delete old sessions - SessionService::delete_old_sessions(db, candidate.application, 3).await.ok(); // TODO move to dotenv + SessionService::delete_old_sessions(db, user_id, admin_id, 3) + .await + .ok(); // TODO move to dotenv Ok(session.id.to_string()) } /// Authenticate user by session id /// Return user model if session is valid - pub async fn auth_user_session(db: &DatabaseConnection, uuid: Uuid) -> Result { + + pub async fn auth_user_session( + db: &DatabaseConnection, + uuid: Uuid, + ) -> Result { let session = match Query::find_session_by_uuid(db, uuid).await { Ok(session) => match session { Some(session) => session, - None => return Err(ServiceError::UserNotFoundBySessionId) + None => return Err(ServiceError::UserNotFoundBySessionId), }, - Err(_) => {return Err(ServiceError::DbError)} + Err(_) => return Err(ServiceError::DbError), }; let now = chrono::Utc::now().naive_utc(); @@ -74,90 +134,133 @@ impl SessionService { if now > session.expires_at { // delete session Mutation::delete_session(db, session.id).await.unwrap(); - return Err(ServiceError::ExpiredSession) + return Err(ServiceError::ExpiredSession); } - let candidate = match session.find_related(candidate::Entity).one(db).await { - Ok(candidate) => match candidate { - Some(candidate) => candidate, - None => return Err(ServiceError::UserNotFoundBySessionId) - }, - Err(_) => {return Err(ServiceError::DbError)} - }; + let candidate = session.find_related(candidate::Entity).one(db).await; + let admin = session.find_related(admin::Entity).one(db).await; - Ok(candidate) + if candidate.is_err() || admin.is_err() { + eprintln!("Kurva"); + return Err(ServiceError::UserNotFoundBySessionId); + } + + if candidate.is_ok() { + if let Some(candidate) = candidate.unwrap() { + return Ok(AdminUser::User(candidate)); + } + } + + if admin.is_ok() { + if let Some(admin) = admin.unwrap() { + return Ok(AdminUser::Admin(admin)); + } + } + return Err(ServiceError::UserNotFoundBySessionId); } } - - #[cfg(test)] mod tests { - use entity::{candidate}; - use sea_orm::{DbConn, Database, sea_query::TableCreateStatement, DbBackend, Schema, ConnectionTrait, prelude::Uuid}; + use entity::{admin, candidate, session}; - use crate::{crypto, services::{session_service::SessionService, candidate_service::CandidateService}}; + use sea_orm::{ + prelude::Uuid, sea_query::TableCreateStatement, ConnectionTrait, Database, DbBackend, + DbConn, Schema, + }; + + use crate::{ + crypto, + services::{candidate_service::CandidateService, session_service::SessionService}, + }; #[cfg(test)] async fn get_memory_sqlite_connection() -> DbConn { - use entity::session; - let base_url = "sqlite::memory:"; let db: DbConn = Database::connect(base_url).await.unwrap(); - + let schema = Schema::new(DbBackend::Sqlite); let stmt: TableCreateStatement = schema.create_table_from_entity(candidate::Entity); - let stmt2: TableCreateStatement = schema.create_table_from_entity(session::Entity); - db.execute(db.get_database_backend().build(&stmt)).await.unwrap(); - db.execute(db.get_database_backend().build(&stmt2)).await.unwrap(); + let stmt2: TableCreateStatement = schema.create_table_from_entity(admin::Entity); + let stmt3: TableCreateStatement = schema.create_table_from_entity(session::Entity); + db.execute(db.get_database_backend().build(&stmt)) + .await + .unwrap(); + db.execute(db.get_database_backend().build(&stmt2)) + .await + .unwrap(); + db.execute(db.get_database_backend().build(&stmt3)) + .await + .unwrap(); db } - + #[tokio::test] async fn test_create_candidate() { const SECRET: &str = "Tajny_kod"; let db = get_memory_sqlite_connection().await; - - let candidate = CandidateService::create(&db, 103151, &SECRET.to_string(), "".to_string()).await.ok().unwrap(); - + + let candidate = CandidateService::create(&db, 103151, &SECRET.to_string(), "".to_string()) + .await + .ok() + .unwrap(); + assert_eq!(candidate.application, 103151); assert_ne!(candidate.code, SECRET.to_string()); - assert!(crypto::verify_password(SECRET.to_string(), candidate.code).await.ok().unwrap()); + assert!(crypto::verify_password(SECRET.to_string(), candidate.code) + .await + .ok() + .unwrap()); } #[tokio::test] async fn test_candidate_session_correct_password() { let db = &get_memory_sqlite_connection().await; - CandidateService::create(&db, 103151, &"Tajny_kod".to_string(), "".to_string()).await.ok().unwrap(); + CandidateService::create(&db, 103151, &"Tajny_kod".to_string(), "".to_string()) + .await + .ok() + .unwrap(); // correct password let session = SessionService::new_session( - db, - 103151, - "Tajny_kod".to_string(), - "127.0.0.1".to_string(), - ) - .await.ok().unwrap(); - // println!("{}", session.err().unwrap().1); - + db, + Some(103151), + None, + "Tajny_kod".to_string(), + "127.0.0.1".to_string(), + ) + .await + .ok() + .unwrap(); + // println!("{}", session.err().unwrap().1); assert!( SessionService::auth_user_session(db, Uuid::parse_str(&session).unwrap()) .await .is_ok() - ); + ); } #[tokio::test] async fn test_candidate_session_incorrect_password() { let db = &get_memory_sqlite_connection().await; - let candidate_form = CandidateService::create(&db, 103151, &"Tajny_kod".to_string(), "".to_string()).await.ok().unwrap(); + let candidate_form = + CandidateService::create(&db, 103151, &"Tajny_kod".to_string(), "".to_string()) + .await + .ok() + .unwrap(); - // incorrect password - assert!( - SessionService::new_session(db, candidate_form.application, "Spatny_kod".to_string(), "127.0.0.1".to_string()).await.is_err() - ); + // incorrect password + assert!(SessionService::new_session( + db, + Some(candidate_form.application), + None, + "Spatny_kod".to_string(), + "127.0.0.1".to_string() + ) + .await + .is_err()); } -} \ No newline at end of file +} diff --git a/entity/src/admin.rs b/entity/src/admin.rs index 5d48632..cc51dae 100644 --- a/entity/src/admin.rs +++ b/entity/src/admin.rs @@ -3,18 +3,27 @@ use sea_orm::entity::prelude::*; #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[sea_orm(table_name = "admin")] pub struct Model { - #[sea_orm(primary_key)] + #[sea_orm(column_type = "Integer", primary_key)] pub id: i32, pub name: String, pub public_key: String, #[sea_orm(column_type = "Text")] - pub private_key_hash: String, - pub password_hash: String, + pub private_key: String, + pub password: String, pub created_at: DateTime, pub updated_at: DateTime, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation {} +pub enum Relation { + #[sea_orm(has_many = "super::session::Entity")] + Session, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Session.def() + } +} impl ActiveModelBehavior for ActiveModel {} diff --git a/entity/src/candidate.rs b/entity/src/candidate.rs index 81b7f72..bf738f9 100644 --- a/entity/src/candidate.rs +++ b/entity/src/candidate.rs @@ -3,7 +3,7 @@ use sea_orm::entity::prelude::*; #[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[sea_orm(table_name = "candidate")] pub struct Model { - #[sea_orm(primary_key, auto_increment = false)] + #[sea_orm(column_type = "Integer", primary_key, auto_increment = false)] pub application: i32, pub code: String, pub name: Option, @@ -22,8 +22,6 @@ pub struct Model { pub personal_identification_number_hash: String, pub public_key: String, pub private_key: String, - #[sea_orm(default_value = false)] - pub is_admin: bool, pub created_at: DateTime, pub updated_at: DateTime, } diff --git a/entity/src/session.rs b/entity/src/session.rs index 99310c8..f4ecf37 100644 --- a/entity/src/session.rs +++ b/entity/src/session.rs @@ -5,7 +5,10 @@ use sea_orm::entity::prelude::*; pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub id: Uuid, - pub user_id: i32, + #[sea_orm(column_type = "Integer", nullable)] + pub admin_id: Option, + #[sea_orm(column_type = "Integer", nullable)] + pub user_id: Option, pub ip_address: String, pub created_at: DateTime, pub expires_at: DateTime, @@ -13,6 +16,14 @@ pub struct Model { #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { + #[sea_orm( + belongs_to = "super::admin::Entity", + from = "Column::AdminId", + to = "super::admin::Column::Id", + on_update = "Cascade", + on_delete = "Cascade" + )] + Admin, #[sea_orm( belongs_to = "super::candidate::Entity", from = "Column::UserId", @@ -29,4 +40,10 @@ impl Related for Entity { } } +impl Related for Entity { + fn to() -> RelationDef { + Relation::Admin.def() + } +} + impl ActiveModelBehavior for ActiveModel {} diff --git a/migration/src/lib.rs b/migration/src/lib.rs index a7409c1..85e2a9c 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -1,10 +1,12 @@ pub use sea_orm_migration::prelude::*; +mod m20221024_111310_create_admin; mod m20221024_121621_create_candidate; mod m20221024_124701_create_parent; mod m20221024_134454_insert_sample_admin; mod m20221025_154422_create_session; mod m20221027_194728_session_create_user_fk; +mod m20221028_194728_session_create_admin_fk; mod m20221030_133428_parent_create_candidate_fk; pub struct Migrator; @@ -12,11 +14,13 @@ pub struct Migrator; impl MigratorTrait for Migrator { fn migrations() -> Vec> { vec![ + Box::new(m20221024_111310_create_admin::Migration), Box::new(m20221024_121621_create_candidate::Migration), Box::new(m20221024_124701_create_parent::Migration), Box::new(m20221024_134454_insert_sample_admin::Migration::default()), Box::new(m20221025_154422_create_session::Migration), Box::new(m20221027_194728_session_create_user_fk::Migration), + Box::new(m20221028_194728_session_create_admin_fk::Migration), Box::new(m20221030_133428_parent_create_candidate_fk::Migration), ] } diff --git a/migration/src/m20221024_111310_create_admin.rs b/migration/src/m20221024_111310_create_admin.rs new file mode 100644 index 0000000..02c23ba --- /dev/null +++ b/migration/src/m20221024_111310_create_admin.rs @@ -0,0 +1,49 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(Admin::Table) + .if_not_exists() + .col( + ColumnDef::new(Admin::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col(ColumnDef::new(Admin::Name).string().not_null()) + .col(ColumnDef::new(Admin::PublicKey).string().not_null()) + .col(ColumnDef::new(Admin::PrivateKey).text().not_null()) + .col(ColumnDef::new(Admin::Password).string().not_null()) + .col(ColumnDef::new(Admin::CreatedAt).date_time().not_null()) + .col(ColumnDef::new(Admin::UpdatedAt).date_time().not_null()) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Admin::Table).to_owned()) + .await + } +} + +#[derive(Iden)] +pub enum Admin { + Table, + Id, + Name, + PublicKey, + PrivateKey, + Password, + CreatedAt, + UpdatedAt, +} diff --git a/migration/src/m20221024_121621_create_candidate.rs b/migration/src/m20221024_121621_create_candidate.rs index 1d0e998..2b7bc26 100644 --- a/migration/src/m20221024_121621_create_candidate.rs +++ b/migration/src/m20221024_121621_create_candidate.rs @@ -34,7 +34,6 @@ impl MigrationTrait for Migration { .col(ColumnDef::new(Candidate::PersonalIdentificationNumberHash).text().not_null()) .col(ColumnDef::new(Candidate::PublicKey).string().not_null()) .col(ColumnDef::new(Candidate::PrivateKey).string().not_null()) - .col(ColumnDef::new(Candidate::IsAdmin).boolean().not_null().default(false)) .col(ColumnDef::new(Candidate::CreatedAt).date_time().not_null()) .col(ColumnDef::new(Candidate::UpdatedAt).date_time().not_null()) .to_owned(), @@ -69,7 +68,6 @@ pub enum Candidate { PersonalIdentificationNumberHash, PublicKey, PrivateKey, - IsAdmin, CreatedAt, UpdatedAt, } diff --git a/migration/src/m20221024_134454_insert_sample_admin.rs b/migration/src/m20221024_134454_insert_sample_admin.rs index 4bee191..94a565f 100644 --- a/migration/src/m20221024_134454_insert_sample_admin.rs +++ b/migration/src/m20221024_134454_insert_sample_admin.rs @@ -1,5 +1,5 @@ use chrono::Local; -use entity::{candidate}; +use entity::admin; use sea_orm_migration::{ prelude::*, sea_orm::{ActiveModelTrait, Set}, @@ -7,24 +7,22 @@ use sea_orm_migration::{ #[derive(DeriveMigrationName)] pub struct Migration { - candidate: candidate::ActiveModel, + admin: admin::ActiveModel, } impl Default for Migration { fn default() -> Self { Self { - candidate: candidate::ActiveModel { - application: Set(1), - name: Set(Some("Admin".to_owned())), + admin: admin::ActiveModel { + id: Set(1), + name: Set("Admin".to_owned()), public_key: Set("age1u889gp407hsz309wn09kxx9anl6uns30m27lfwnctfyq9tq4qpus8tzmq5".to_owned()), // AGE-SECRET-KEY-14QG24502DMUUQDT2SPMX2YXPSES0X8UD6NT0PCTDAT6RH8V5Q3GQGSRXPS private_key: Set("5KCEGk0ueWVGnu5Xo3rmpLoilcVZ2ZWmwIcdZEJ8rrBNW7jwzZU/XTcTXtk/xyy/zjF8s+YnuVpOklQvX3EC/Sn+ZwyPY3jokM2RNwnZZlnqdehOEV1SMm/Y".to_owned()), // test - code: Set("$argon2i$v=19$m=6000,t=3,p=10$WE9xCQmmWdBK82R4SEjoqA$TZSc6PuLd4aWK2x2WAb+Lm9sLySqjK3KLbNyqyQmzPQ".to_owned()), - personal_identification_number_hash: Set("ADMIN".to_owned()), + password: Set("$argon2i$v=19$m=6000,t=3,p=10$WE9xCQmmWdBK82R4SEjoqA$TZSc6PuLd4aWK2x2WAb+Lm9sLySqjK3KLbNyqyQmzPQ".to_owned()), created_at: Set(Local::now().naive_local()), updated_at: Set(Local::now().naive_local()), - is_admin: Set(true), ..Default::default() }, } @@ -36,7 +34,7 @@ impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { let db = manager.get_connection(); - self.candidate.to_owned().insert(db).await?; + self.admin.to_owned().insert(db).await?; Ok(()) } @@ -44,8 +42,8 @@ impl MigrationTrait for Migration { async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { let db = manager.get_connection(); - self.candidate.to_owned().delete(db).await?; + self.admin.to_owned().delete(db).await?; Ok(()) } -} +} \ No newline at end of file diff --git a/migration/src/m20221025_154422_create_session.rs b/migration/src/m20221025_154422_create_session.rs index 9af1f43..3bb8b8c 100644 --- a/migration/src/m20221025_154422_create_session.rs +++ b/migration/src/m20221025_154422_create_session.rs @@ -18,7 +18,8 @@ impl MigrationTrait for Migration { .unique_key() .primary_key(), ) - .col(ColumnDef::new(Session::UserId).integer().not_null()) + .col(ColumnDef::new(Session::UserId).integer()) + .col(ColumnDef::new(Session::AdminId).integer()) .col(ColumnDef::new(Session::IpAddress).string().not_null()) .col(ColumnDef::new(Session::CreatedAt).date_time().not_null()) .col(ColumnDef::new(Session::ExpiresAt).date_time().not_null()) @@ -39,6 +40,7 @@ pub enum Session { Table, Id, UserId, + AdminId, IpAddress, CreatedAt, ExpiresAt, diff --git a/migration/src/m20221028_194728_session_create_admin_fk.rs b/migration/src/m20221028_194728_session_create_admin_fk.rs new file mode 100644 index 0000000..5b36851 --- /dev/null +++ b/migration/src/m20221028_194728_session_create_admin_fk.rs @@ -0,0 +1,26 @@ +use sea_orm_migration::prelude::*; + +use crate::{m20221025_154422_create_session::Session, m20221024_111310_create_admin::Admin}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager.create_foreign_key(ForeignKey::create() + .name("admin_fk") + .from(Session::Table, Session::AdminId) + .to(Admin::Table, Admin::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) + .to_owned()).await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager.drop_foreign_key(ForeignKey::drop() + .name("admin_fk") + .table(Session::Table) + .to_owned()).await + } +} \ No newline at end of file