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