feat/web: Patchset 3 (#455)

https://apifox.com/apidoc/shared-ceda7a60-e817-4ea8-827b-de4e874dc45e

implement all backend API
This commit is contained in:
Sijie.Sun
2024-11-02 15:13:19 +08:00
committed by GitHub
parent 18da94bf33
commit 8aca5851f2
41 changed files with 4621 additions and 217 deletions
@@ -0,0 +1,450 @@
// src/migrator/m20220602_000001_create_bakery_table.rs (create new file)
use sea_orm_migration::{prelude::*, schema::*};
pub struct Migration;
/*
-- # Entity schema.
-- Create `users` table.
create table if not exists users (
id integer primary key autoincrement,
username text not null unique,
password text not null
);
-- Create `groups` table.
create table if not exists groups (
id integer primary key autoincrement,
name text not null unique
);
-- Create `permissions` table.
create table if not exists permissions (
id integer primary key autoincrement,
name text not null unique
);
-- # Join tables.
-- Create `users_groups` table for many-to-many relationships between users and groups.
create table if not exists users_groups (
user_id integer references users(id),
group_id integer references groups(id),
primary key (user_id, group_id)
);
-- Create `groups_permissions` table for many-to-many relationships between groups and permissions.
create table if not exists groups_permissions (
group_id integer references groups(id),
permission_id integer references permissions(id),
primary key (group_id, permission_id)
);
-- # Fixture hydration.
-- Insert "user" user. password: "user"
insert into users (username, password)
values (
'user',
'$argon2i$v=19$m=16,t=2,p=1$dHJ5dXZkYmZkYXM$UkrNqWz0BbSVBq4ykLSuJw'
);
-- Insert "admin" user. password: "admin"
insert into users (username, password)
values (
'admin',
'$argon2i$v=19$m=16,t=2,p=1$Ymd1Y2FlcnQ$x0q4oZinW9S1ZB9BcaHEpQ'
);
-- Insert "users" and "superusers" groups.
insert into groups (name) values ('users');
insert into groups (name) values ('superusers');
-- Insert individual permissions.
insert into permissions (name) values ('sessions');
insert into permissions (name) values ('devices');
-- Insert group permissions.
insert into groups_permissions (group_id, permission_id)
values (
(select id from groups where name = 'users'),
(select id from permissions where name = 'devices')
), (
(select id from groups where name = 'superusers'),
(select id from permissions where name = 'sessions')
);
-- Insert users into groups.
insert into users_groups (user_id, group_id)
values (
(select id from users where username = 'user'),
(select id from groups where name = 'users')
), (
(select id from users where username = 'admin'),
(select id from groups where name = 'users')
), (
(select id from users where username = 'admin'),
(select id from groups where name = 'superusers')
);
*/
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20241029_000001_init"
}
}
#[derive(DeriveIden)]
pub enum Users {
Table,
Id,
Username,
Password,
}
#[derive(DeriveIden)]
enum Groups {
Table,
Id,
Name,
}
#[derive(DeriveIden)]
enum Permissions {
Table,
Id,
Name,
}
#[derive(DeriveIden)]
enum UsersGroups {
Table,
Id,
UserId,
GroupId,
}
#[derive(DeriveIden)]
enum GroupsPermissions {
Table,
Id,
GroupId,
PermissionId,
}
#[derive(DeriveIden)]
enum UserRunningNetworkConfigs {
Table,
Id,
UserId,
NetworkInstanceId,
NetworkConfig,
Disabled,
CreateTime,
UpdateTime,
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
// Define how to apply this migration: Create the Bakery table.
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
// Create the `users` table.
manager
.create_table(
Table::create()
.if_not_exists()
.table(Users::Table)
.col(pk_auto(Users::Id).not_null())
.col(string(Users::Username).not_null().unique_key())
.col(string(Users::Password).not_null())
.to_owned(),
)
.await?;
manager
.create_index(
Index::create()
.name("idx_users_username")
.table(Users::Table)
.col(Users::Username)
.to_owned(),
)
.await?;
// Create the `groups` table.
manager
.create_table(
Table::create()
.if_not_exists()
.table(Groups::Table)
.col(pk_auto(Groups::Id).not_null())
.col(string(Groups::Name).not_null().unique_key())
.to_owned(),
)
.await?;
manager
.create_index(
Index::create()
.name("idx_groups_name")
.table(Groups::Table)
.col(Groups::Name)
.to_owned(),
)
.await?;
// Create the `permissions` table.
manager
.create_table(
Table::create()
.if_not_exists()
.table(Permissions::Table)
.col(pk_auto(Permissions::Id).not_null())
.col(string(Permissions::Name).not_null().unique_key())
.to_owned(),
)
.await?;
// Create the `users_groups` table.
manager
.create_table(
Table::create()
.if_not_exists()
.table(UsersGroups::Table)
.col(pk_auto(UsersGroups::Id).not_null())
.col(integer(UsersGroups::UserId).not_null())
.col(integer(UsersGroups::GroupId).not_null())
.foreign_key(
ForeignKey::create()
.name("fk_users_groups_user_id_to_users_id")
.from(UsersGroups::Table, UsersGroups::UserId)
.to(Users::Table, Users::Id)
.on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade),
)
.foreign_key(
ForeignKey::create()
.name("fk_users_groups_group_id_to_groups_id")
.from(UsersGroups::Table, UsersGroups::GroupId)
.to(Groups::Table, Groups::Id)
.on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade),
)
.to_owned(),
)
.await?;
// Create the `groups_permissions` table.
manager
.create_table(
Table::create()
.if_not_exists()
.table(GroupsPermissions::Table)
.col(pk_auto(GroupsPermissions::Id).not_null())
.col(integer(GroupsPermissions::GroupId).not_null())
.col(integer(GroupsPermissions::PermissionId).not_null())
.foreign_key(
ForeignKey::create()
.name("fk_groups_permissions_group_id_to_groups_id")
.from(GroupsPermissions::Table, GroupsPermissions::GroupId)
.to(Groups::Table, Groups::Id)
.on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade),
)
.foreign_key(
ForeignKey::create()
.name("fk_groups_permissions_permission_id_to_permissions_id")
.from(GroupsPermissions::Table, GroupsPermissions::PermissionId)
.to(Permissions::Table, Permissions::Id)
.on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade),
)
.to_owned(),
)
.await?;
// create user running network configs table
manager
.create_table(
Table::create()
.if_not_exists()
.table(UserRunningNetworkConfigs::Table)
.col(pk_auto(UserRunningNetworkConfigs::Id).not_null())
.col(integer(UserRunningNetworkConfigs::UserId).not_null())
.col(
text(UserRunningNetworkConfigs::NetworkInstanceId)
.unique_key()
.not_null(),
)
.col(text(UserRunningNetworkConfigs::NetworkConfig).not_null())
.col(
boolean(UserRunningNetworkConfigs::Disabled)
.not_null()
.default(false),
)
.col(timestamp_with_time_zone(UserRunningNetworkConfigs::CreateTime).not_null())
.col(timestamp_with_time_zone(UserRunningNetworkConfigs::UpdateTime).not_null())
.foreign_key(
ForeignKey::create()
.name("fk_user_running_network_configs_user_id_to_users_id")
.from(
UserRunningNetworkConfigs::Table,
UserRunningNetworkConfigs::UserId,
)
.to(Users::Table, Users::Id)
.on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade),
)
.to_owned(),
)
.await?;
manager
.create_index(
Index::create()
.name("idx_user_running_network_configs_user_id")
.table(UserRunningNetworkConfigs::Table)
.col(UserRunningNetworkConfigs::UserId)
.to_owned(),
)
.await?;
// prepare data
let user = Query::insert()
.into_table(Users::Table)
.columns(vec![Users::Username, Users::Password])
.values_panic(vec![
"user".into(),
"$argon2i$v=19$m=16,t=2,p=1$dHJ5dXZkYmZkYXM$UkrNqWz0BbSVBq4ykLSuJw".into(),
])
.to_owned();
manager.exec_stmt(user).await?;
let admin = Query::insert()
.into_table(Users::Table)
.columns(vec![Users::Username, Users::Password])
.values_panic(vec![
"admin".into(),
"$argon2i$v=19$m=16,t=2,p=1$Ymd1Y2FlcnQ$x0q4oZinW9S1ZB9BcaHEpQ".into(),
])
.to_owned();
manager.exec_stmt(admin).await?;
let users = Query::insert()
.into_table(Groups::Table)
.columns(vec![Groups::Name])
.values_panic(vec!["users".into()])
.to_owned();
manager.exec_stmt(users).await?;
let admins = Query::insert()
.into_table(Groups::Table)
.columns(vec![Groups::Name])
.values_panic(vec!["admins".into()])
.to_owned();
manager.exec_stmt(admins).await?;
let sessions = Query::insert()
.into_table(Permissions::Table)
.columns(vec![Permissions::Name])
.values_panic(vec!["sessions".into()])
.to_owned();
manager.exec_stmt(sessions).await?;
let devices = Query::insert()
.into_table(Permissions::Table)
.columns(vec![Permissions::Name])
.values_panic(vec!["devices".into()])
.to_owned();
manager.exec_stmt(devices).await?;
let users_devices = Query::insert()
.into_table(GroupsPermissions::Table)
.columns(vec![
GroupsPermissions::GroupId,
GroupsPermissions::PermissionId,
])
.select_from(
Query::select()
.column((Groups::Table, Groups::Id))
.column((Permissions::Table, Permissions::Id))
.from(Groups::Table)
.full_outer_join(Permissions::Table, all![])
.cond_where(any![
// users have devices permission
Expr::col((Groups::Table, Groups::Name))
.eq("users")
.and(Expr::col((Permissions::Table, Permissions::Name)).eq("devices")),
// admins have all permissions
Expr::col((Groups::Table, Groups::Name)).eq("admins"),
])
.to_owned(),
)
.unwrap()
.to_owned();
manager.exec_stmt(users_devices).await?;
let add_user_to_users = Query::insert()
.into_table(UsersGroups::Table)
.columns(vec![UsersGroups::UserId, UsersGroups::GroupId])
.select_from(
Query::select()
.column((Users::Table, Users::Id))
.column((Groups::Table, Groups::Id))
.from(Users::Table)
.full_outer_join(Groups::Table, all![])
.cond_where(
Expr::col(Users::Username)
.eq("user")
.and(Expr::col(Groups::Name).eq("users")),
)
.to_owned(),
)
.unwrap()
.to_owned();
manager.exec_stmt(add_user_to_users).await?;
let add_admin_to_admins = Query::insert()
.into_table(UsersGroups::Table)
.columns(vec![UsersGroups::UserId, UsersGroups::GroupId])
.select_from(
Query::select()
.column((Users::Table, Users::Id))
.column((Groups::Table, Groups::Id))
.from(Users::Table)
.full_outer_join(Groups::Table, all![])
.cond_where(
Expr::col(Users::Username)
.eq("admin")
.and(Expr::col(Groups::Name).eq("admins")),
)
.to_owned(),
)
.unwrap()
.to_owned();
manager.exec_stmt(add_admin_to_admins).await?;
Ok(())
}
// Define how to rollback this migration: Drop the Bakery table.
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(Users::Table).to_owned())
.await?;
manager
.drop_table(Table::drop().table(Groups::Table).to_owned())
.await?;
manager
.drop_table(Table::drop().table(Permissions::Table).to_owned())
.await?;
manager
.drop_table(Table::drop().table(UsersGroups::Table).to_owned())
.await?;
manager
.drop_table(Table::drop().table(GroupsPermissions::Table).to_owned())
.await?;
Ok(())
}
}
+12
View File
@@ -0,0 +1,12 @@
use sea_orm_migration::prelude::*;
mod m20241029_000001_init;
pub struct Migrator;
#[async_trait::async_trait]
impl MigratorTrait for Migrator {
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
vec![Box::new(m20241029_000001_init::Migration)]
}
}