1use sea_orm_migration::prelude::*;
4
5pub struct AuthMigrator;
7
8#[async_trait::async_trait]
9impl MigratorTrait for AuthMigrator {
10 fn migrations() -> Vec<Box<dyn MigrationTrait>> {
11 let mut v = sova_passport::AuthMigrator::migrations();
12 v.push(Box::new(m20260308_000002_fortify::Migration));
13 v
14 }
15}
16
17mod m20260308_000002_fortify {
18 use sea_orm_migration::prelude::*;
19
20 pub struct Migration;
21
22 impl MigrationName for Migration {
23 fn name(&self) -> &str {
24 "m20260308_000002_fortify"
25 }
26 }
27
28 #[async_trait::async_trait]
29 impl MigrationTrait for Migration {
30 async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
31 manager
32 .create_table(
33 Table::create()
34 .table(AuthPasswordResetTokens::Table)
35 .if_not_exists()
36 .col(
37 ColumnDef::new(AuthPasswordResetTokens::Email)
38 .string()
39 .not_null()
40 .primary_key(),
41 )
42 .col(
43 ColumnDef::new(AuthPasswordResetTokens::TokenHash)
44 .string()
45 .not_null(),
46 )
47 .col(
48 ColumnDef::new(AuthPasswordResetTokens::CreatedAt)
49 .timestamp_with_time_zone()
50 .not_null(),
51 )
52 .to_owned(),
53 )
54 .await?;
55
56 manager
57 .create_table(
58 Table::create()
59 .table(AuthRoles::Table)
60 .if_not_exists()
61 .col(
62 ColumnDef::new(AuthRoles::Id)
63 .big_integer()
64 .not_null()
65 .auto_increment()
66 .primary_key(),
67 )
68 .col(ColumnDef::new(AuthRoles::Name).string().not_null())
69 .col(
70 ColumnDef::new(AuthRoles::Slug)
71 .string()
72 .not_null()
73 .unique_key(),
74 )
75 .to_owned(),
76 )
77 .await?;
78
79 manager
80 .create_table(
81 Table::create()
82 .table(AuthPermissions::Table)
83 .if_not_exists()
84 .col(
85 ColumnDef::new(AuthPermissions::Id)
86 .big_integer()
87 .not_null()
88 .auto_increment()
89 .primary_key(),
90 )
91 .col(ColumnDef::new(AuthPermissions::Name).string().not_null())
92 .col(
93 ColumnDef::new(AuthPermissions::Slug)
94 .string()
95 .not_null()
96 .unique_key(),
97 )
98 .to_owned(),
99 )
100 .await?;
101
102 manager
103 .create_table(
104 Table::create()
105 .table(AuthRoleUser::Table)
106 .if_not_exists()
107 .col(
108 ColumnDef::new(AuthRoleUser::UserId)
109 .big_integer()
110 .not_null(),
111 )
112 .col(
113 ColumnDef::new(AuthRoleUser::RoleId)
114 .big_integer()
115 .not_null(),
116 )
117 .primary_key(
118 Index::create()
119 .col(AuthRoleUser::UserId)
120 .col(AuthRoleUser::RoleId),
121 )
122 .foreign_key(
123 ForeignKey::create()
124 .name("fk_auth_role_user_user")
125 .from(AuthRoleUser::Table, AuthRoleUser::UserId)
126 .to(AuthUsers::Table, AuthUsers::Id)
127 .on_delete(ForeignKeyAction::Cascade),
128 )
129 .foreign_key(
130 ForeignKey::create()
131 .name("fk_auth_role_user_role")
132 .from(AuthRoleUser::Table, AuthRoleUser::RoleId)
133 .to(AuthRoles::Table, AuthRoles::Id)
134 .on_delete(ForeignKeyAction::Cascade),
135 )
136 .to_owned(),
137 )
138 .await?;
139
140 manager
141 .create_index(
142 Index::create()
143 .if_not_exists()
144 .name("idx_auth_role_user_role_id")
145 .table(AuthRoleUser::Table)
146 .col(AuthRoleUser::RoleId)
147 .to_owned(),
148 )
149 .await?;
150
151 manager
152 .create_table(
153 Table::create()
154 .table(AuthPermissionRole::Table)
155 .if_not_exists()
156 .col(
157 ColumnDef::new(AuthPermissionRole::RoleId)
158 .big_integer()
159 .not_null(),
160 )
161 .col(
162 ColumnDef::new(AuthPermissionRole::PermissionId)
163 .big_integer()
164 .not_null(),
165 )
166 .primary_key(
167 Index::create()
168 .col(AuthPermissionRole::RoleId)
169 .col(AuthPermissionRole::PermissionId),
170 )
171 .foreign_key(
172 ForeignKey::create()
173 .name("fk_auth_permission_role_role")
174 .from(AuthPermissionRole::Table, AuthPermissionRole::RoleId)
175 .to(AuthRoles::Table, AuthRoles::Id)
176 .on_delete(ForeignKeyAction::Cascade),
177 )
178 .foreign_key(
179 ForeignKey::create()
180 .name("fk_auth_permission_role_perm")
181 .from(
182 AuthPermissionRole::Table,
183 AuthPermissionRole::PermissionId,
184 )
185 .to(AuthPermissions::Table, AuthPermissions::Id)
186 .on_delete(ForeignKeyAction::Cascade),
187 )
188 .to_owned(),
189 )
190 .await?;
191
192 manager
193 .create_index(
194 Index::create()
195 .if_not_exists()
196 .name("idx_auth_permission_role_permission_id")
197 .table(AuthPermissionRole::Table)
198 .col(AuthPermissionRole::PermissionId)
199 .to_owned(),
200 )
201 .await?;
202
203 let conn = manager.get_connection();
204 conn.execute_unprepared(
205 "INSERT INTO auth_roles (name, slug) VALUES ('User', 'user'), ('Admin', 'admin')",
206 )
207 .await?;
208 conn.execute_unprepared(
209 "INSERT INTO auth_permissions (name, slug) VALUES \
210 ('Cabinet access', 'cabinet.access'), \
211 ('Manage users', 'users.manage')",
212 )
213 .await?;
214 conn.execute_unprepared(
215 "INSERT INTO auth_permission_role (role_id, permission_id) \
216 SELECT r.id, p.id FROM auth_roles r, auth_permissions p \
217 WHERE r.slug = 'user' AND p.slug = 'cabinet.access'",
218 )
219 .await?;
220 conn.execute_unprepared(
221 "INSERT INTO auth_permission_role (role_id, permission_id) \
222 SELECT r.id, p.id FROM auth_roles r, auth_permissions p \
223 WHERE r.slug = 'admin'",
224 )
225 .await?;
226
227 Ok(())
228 }
229
230 async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
231 manager
232 .drop_table(Table::drop().table(AuthPermissionRole::Table).to_owned())
233 .await?;
234 manager
235 .drop_table(Table::drop().table(AuthRoleUser::Table).to_owned())
236 .await?;
237 manager
238 .drop_table(Table::drop().table(AuthPermissions::Table).to_owned())
239 .await?;
240 manager
241 .drop_table(Table::drop().table(AuthRoles::Table).to_owned())
242 .await?;
243 manager
244 .drop_table(
245 Table::drop()
246 .table(AuthPasswordResetTokens::Table)
247 .to_owned(),
248 )
249 .await?;
250 Ok(())
251 }
252 }
253
254 #[derive(Iden)]
255 enum AuthUsers {
256 Table,
257 Id,
258 }
259
260 #[derive(Iden)]
261 enum AuthPasswordResetTokens {
262 Table,
263 Email,
264 TokenHash,
265 CreatedAt,
266 }
267
268 #[derive(Iden)]
269 enum AuthRoles {
270 Table,
271 Id,
272 Name,
273 Slug,
274 }
275
276 #[derive(Iden)]
277 enum AuthPermissions {
278 Table,
279 Id,
280 Name,
281 Slug,
282 }
283
284 #[derive(Iden)]
285 enum AuthRoleUser {
286 Table,
287 UserId,
288 RoleId,
289 }
290
291 #[derive(Iden)]
292 enum AuthPermissionRole {
293 Table,
294 RoleId,
295 PermissionId,
296 }
297}