diff --git a/crates/data-model/src/users.rs b/crates/data-model/src/users.rs index 920726ef8..5221f4867 100644 --- a/crates/data-model/src/users.rs +++ b/crates/data-model/src/users.rs @@ -21,6 +21,7 @@ pub struct User { pub locked_at: Option>, pub deactivated_at: Option>, pub can_request_admin: bool, + pub is_guest: bool, } impl User { @@ -43,6 +44,7 @@ impl User { locked_at: None, deactivated_at: None, can_request_admin: false, + is_guest: false, }] } } diff --git a/crates/handlers/src/admin/model.rs b/crates/handlers/src/admin/model.rs index 62065dfe4..2f6648402 100644 --- a/crates/handlers/src/admin/model.rs +++ b/crates/handlers/src/admin/model.rs @@ -52,6 +52,9 @@ pub struct User { /// Whether the user can request admin privileges. admin: bool, + + /// Whether the user was a guest before migrating to MAS, + legacy_guest: bool, } impl User { @@ -65,6 +68,7 @@ impl User { locked_at: None, deactivated_at: None, admin: false, + legacy_guest: false, }, Self { id: Ulid::from_bytes([0x02; 16]), @@ -73,6 +77,7 @@ impl User { locked_at: None, deactivated_at: None, admin: true, + legacy_guest: false, }, Self { id: Ulid::from_bytes([0x03; 16]), @@ -81,6 +86,7 @@ impl User { locked_at: Some(DateTime::default()), deactivated_at: None, admin: false, + legacy_guest: true, }, ] } @@ -95,6 +101,7 @@ impl From for User { locked_at: user.locked_at, deactivated_at: user.deactivated_at, admin: user.can_request_admin, + legacy_guest: user.is_guest, } } } diff --git a/crates/handlers/src/admin/v1/users/deactivate.rs b/crates/handlers/src/admin/v1/users/deactivate.rs index 8a135fadc..b963b73d5 100644 --- a/crates/handlers/src/admin/v1/users/deactivate.rs +++ b/crates/handlers/src/admin/v1/users/deactivate.rs @@ -209,7 +209,8 @@ mod tests { "created_at": "2022-01-16T14:40:00Z", "locked_at": null, "deactivated_at": "2022-01-16T14:40:00Z", - "admin": false + "admin": false, + "legacy_guest": false }, "links": { "self": "/api/admin/v1/users/01FSHN9AG0MZAA6S4AF7CTV32E" @@ -289,7 +290,8 @@ mod tests { "created_at": "2022-01-16T14:40:00Z", "locked_at": "2022-01-16T14:40:00Z", "deactivated_at": "2022-01-16T14:41:00Z", - "admin": false + "admin": false, + "legacy_guest": false }, "links": { "self": "/api/admin/v1/users/01FSHN9AG0MZAA6S4AF7CTV32E" diff --git a/crates/handlers/src/rate_limit.rs b/crates/handlers/src/rate_limit.rs index 8b2485941..0471e6351 100644 --- a/crates/handlers/src/rate_limit.rs +++ b/crates/handlers/src/rate_limit.rs @@ -328,6 +328,7 @@ mod tests { locked_at: None, deactivated_at: None, can_request_admin: false, + is_guest: true, }; let bob = User { @@ -338,6 +339,7 @@ mod tests { locked_at: None, deactivated_at: None, can_request_admin: false, + is_guest: true, }; // Three times the same IP address should be allowed diff --git a/crates/storage-pg/.sqlx/query-d2a4f5c01603463b78198529d295f7f121769ea5730d01c20c0ddbcdc79a5716.json b/crates/storage-pg/.sqlx/query-23d5fcd8bf611dc7279bef0d66ce05461c3c1f43f966fee3a80ae42540783f08.json similarity index 74% rename from crates/storage-pg/.sqlx/query-d2a4f5c01603463b78198529d295f7f121769ea5730d01c20c0ddbcdc79a5716.json rename to crates/storage-pg/.sqlx/query-23d5fcd8bf611dc7279bef0d66ce05461c3c1f43f966fee3a80ae42540783f08.json index 171a83623..28391d844 100644 --- a/crates/storage-pg/.sqlx/query-d2a4f5c01603463b78198529d295f7f121769ea5730d01c20c0ddbcdc79a5716.json +++ b/crates/storage-pg/.sqlx/query-23d5fcd8bf611dc7279bef0d66ce05461c3c1f43f966fee3a80ae42540783f08.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT user_id\n , username\n , created_at\n , locked_at\n , deactivated_at\n , can_request_admin\n FROM users\n WHERE LOWER(username) = LOWER($1)\n ", + "query": "\n SELECT user_id\n , username\n , created_at\n , locked_at\n , deactivated_at\n , can_request_admin\n , is_guest\n FROM users\n WHERE LOWER(username) = LOWER($1)\n ", "describe": { "columns": [ { @@ -32,6 +32,11 @@ "ordinal": 5, "name": "can_request_admin", "type_info": "Bool" + }, + { + "ordinal": 6, + "name": "is_guest", + "type_info": "Bool" } ], "parameters": { @@ -45,8 +50,9 @@ false, true, true, + false, false ] }, - "hash": "d2a4f5c01603463b78198529d295f7f121769ea5730d01c20c0ddbcdc79a5716" + "hash": "23d5fcd8bf611dc7279bef0d66ce05461c3c1f43f966fee3a80ae42540783f08" } diff --git a/crates/storage-pg/.sqlx/query-cc332eda5965715607ffa4eeeacc1b6532cbd8fe49904ccdb1afe315804d348d.json b/crates/storage-pg/.sqlx/query-4dad1838536c10ba723adc0fb6da0f24afb3d6a1925a80a1b6d35b9a8258a0ce.json similarity index 75% rename from crates/storage-pg/.sqlx/query-cc332eda5965715607ffa4eeeacc1b6532cbd8fe49904ccdb1afe315804d348d.json rename to crates/storage-pg/.sqlx/query-4dad1838536c10ba723adc0fb6da0f24afb3d6a1925a80a1b6d35b9a8258a0ce.json index 6603fa37d..6c8cdbe88 100644 --- a/crates/storage-pg/.sqlx/query-cc332eda5965715607ffa4eeeacc1b6532cbd8fe49904ccdb1afe315804d348d.json +++ b/crates/storage-pg/.sqlx/query-4dad1838536c10ba723adc0fb6da0f24afb3d6a1925a80a1b6d35b9a8258a0ce.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT user_id\n , username\n , created_at\n , locked_at\n , deactivated_at\n , can_request_admin\n FROM users\n WHERE user_id = $1\n ", + "query": "\n SELECT user_id\n , username\n , created_at\n , locked_at\n , deactivated_at\n , can_request_admin\n , is_guest\n FROM users\n WHERE user_id = $1\n ", "describe": { "columns": [ { @@ -32,6 +32,11 @@ "ordinal": 5, "name": "can_request_admin", "type_info": "Bool" + }, + { + "ordinal": 6, + "name": "is_guest", + "type_info": "Bool" } ], "parameters": { @@ -45,8 +50,9 @@ false, true, true, + false, false ] }, - "hash": "cc332eda5965715607ffa4eeeacc1b6532cbd8fe49904ccdb1afe315804d348d" + "hash": "4dad1838536c10ba723adc0fb6da0f24afb3d6a1925a80a1b6d35b9a8258a0ce" } diff --git a/crates/storage-pg/.sqlx/query-f924db60febad26c9fff24881b05dd1e1f7ba288d7b2f2f8e30a1ea43e98b8c8.json b/crates/storage-pg/.sqlx/query-572ead41d62cfbe40e6f0c8edf6928e8eebd99036255b62d688ac02b5bd74b40.json similarity index 84% rename from crates/storage-pg/.sqlx/query-f924db60febad26c9fff24881b05dd1e1f7ba288d7b2f2f8e30a1ea43e98b8c8.json rename to crates/storage-pg/.sqlx/query-572ead41d62cfbe40e6f0c8edf6928e8eebd99036255b62d688ac02b5bd74b40.json index 1ddb0acc8..155277181 100644 --- a/crates/storage-pg/.sqlx/query-f924db60febad26c9fff24881b05dd1e1f7ba288d7b2f2f8e30a1ea43e98b8c8.json +++ b/crates/storage-pg/.sqlx/query-572ead41d62cfbe40e6f0c8edf6928e8eebd99036255b62d688ac02b5bd74b40.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT s.user_session_id\n , s.created_at AS \"user_session_created_at\"\n , s.finished_at AS \"user_session_finished_at\"\n , s.user_agent AS \"user_session_user_agent\"\n , s.last_active_at AS \"user_session_last_active_at\"\n , s.last_active_ip AS \"user_session_last_active_ip: IpAddr\"\n , u.user_id\n , u.username AS \"user_username\"\n , u.created_at AS \"user_created_at\"\n , u.locked_at AS \"user_locked_at\"\n , u.deactivated_at AS \"user_deactivated_at\"\n , u.can_request_admin AS \"user_can_request_admin\"\n FROM user_sessions s\n INNER JOIN users u\n USING (user_id)\n WHERE s.user_session_id = $1\n ", + "query": "\n SELECT s.user_session_id\n , s.created_at AS \"user_session_created_at\"\n , s.finished_at AS \"user_session_finished_at\"\n , s.user_agent AS \"user_session_user_agent\"\n , s.last_active_at AS \"user_session_last_active_at\"\n , s.last_active_ip AS \"user_session_last_active_ip: IpAddr\"\n , u.user_id\n , u.username AS \"user_username\"\n , u.created_at AS \"user_created_at\"\n , u.locked_at AS \"user_locked_at\"\n , u.deactivated_at AS \"user_deactivated_at\"\n , u.can_request_admin AS \"user_can_request_admin\"\n , u.is_guest AS \"user_is_guest\"\n FROM user_sessions s\n INNER JOIN users u\n USING (user_id)\n WHERE s.user_session_id = $1\n ", "describe": { "columns": [ { @@ -62,6 +62,11 @@ "ordinal": 11, "name": "user_can_request_admin", "type_info": "Bool" + }, + { + "ordinal": 12, + "name": "user_is_guest", + "type_info": "Bool" } ], "parameters": { @@ -81,8 +86,9 @@ false, true, true, + false, false ] }, - "hash": "f924db60febad26c9fff24881b05dd1e1f7ba288d7b2f2f8e30a1ea43e98b8c8" + "hash": "572ead41d62cfbe40e6f0c8edf6928e8eebd99036255b62d688ac02b5bd74b40" } diff --git a/crates/storage-pg/src/iden.rs b/crates/storage-pg/src/iden.rs index e6c03acc4..a861f59c7 100644 --- a/crates/storage-pg/src/iden.rs +++ b/crates/storage-pg/src/iden.rs @@ -39,6 +39,7 @@ pub enum Users { LockedAt, DeactivatedAt, CanRequestAdmin, + IsGuest, } #[derive(sea_query::Iden)] diff --git a/crates/storage-pg/src/user/mod.rs b/crates/storage-pg/src/user/mod.rs index 8af61b61c..c88c60d3d 100644 --- a/crates/storage-pg/src/user/mod.rs +++ b/crates/storage-pg/src/user/mod.rs @@ -73,6 +73,7 @@ mod priv_ { pub(super) locked_at: Option>, pub(super) deactivated_at: Option>, pub(super) can_request_admin: bool, + pub(super) is_guest: bool, } } @@ -89,6 +90,7 @@ impl From for User { locked_at: value.locked_at, deactivated_at: value.deactivated_at, can_request_admin: value.can_request_admin, + is_guest: value.is_guest, } } } @@ -140,6 +142,7 @@ impl UserRepository for PgUserRepository<'_> { , locked_at , deactivated_at , can_request_admin + , is_guest FROM users WHERE user_id = $1 "#, @@ -176,6 +179,7 @@ impl UserRepository for PgUserRepository<'_> { , locked_at , deactivated_at , can_request_admin + , is_guest FROM users WHERE LOWER(username) = LOWER($1) "#, @@ -249,6 +253,7 @@ impl UserRepository for PgUserRepository<'_> { locked_at: None, deactivated_at: None, can_request_admin: false, + is_guest: false, }) } @@ -487,6 +492,10 @@ impl UserRepository for PgUserRepository<'_> { Expr::col((Users::Table, Users::CanRequestAdmin)), UserLookupIden::CanRequestAdmin, ) + .expr_as( + Expr::col((Users::Table, Users::IsGuest)), + UserLookupIden::IsGuest, + ) .from(Users::Table) .apply_filter(filter) .generate_pagination((Users::Table, Users::UserId), pagination) diff --git a/crates/storage-pg/src/user/session.rs b/crates/storage-pg/src/user/session.rs index a8c5ab458..54645b3cb 100644 --- a/crates/storage-pg/src/user/session.rs +++ b/crates/storage-pg/src/user/session.rs @@ -61,6 +61,7 @@ struct SessionLookup { user_locked_at: Option>, user_deactivated_at: Option>, user_can_request_admin: bool, + user_is_guest: bool, } impl TryFrom for BrowserSession { @@ -76,6 +77,7 @@ impl TryFrom for BrowserSession { locked_at: value.user_locked_at, deactivated_at: value.user_deactivated_at, can_request_admin: value.user_can_request_admin, + is_guest: value.user_is_guest, }; Ok(BrowserSession { @@ -201,6 +203,7 @@ impl BrowserSessionRepository for PgBrowserSessionRepository<'_> { , u.locked_at AS "user_locked_at" , u.deactivated_at AS "user_deactivated_at" , u.can_request_admin AS "user_can_request_admin" + , u.is_guest AS "user_is_guest" FROM user_sessions s INNER JOIN users u USING (user_id) @@ -391,6 +394,10 @@ impl BrowserSessionRepository for PgBrowserSessionRepository<'_> { Expr::col((Users::Table, Users::CanRequestAdmin)), SessionLookupIden::UserCanRequestAdmin, ) + .expr_as( + Expr::col((Users::Table, Users::IsGuest)), + SessionLookupIden::UserIsGuest, + ) .from(UserSessions::Table) .inner_join( Users::Table, diff --git a/docs/api/spec.json b/docs/api/spec.json index ab8e7f2ec..37ad58e05 100644 --- a/docs/api/spec.json +++ b/docs/api/spec.json @@ -937,7 +937,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": null, "deactivated_at": null, - "admin": false + "admin": false, + "legacy_guest": false }, "links": { "self": "/api/admin/v1/users/01040G2081040G2081040G2081" @@ -951,7 +952,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": null, "deactivated_at": null, - "admin": true + "admin": true, + "legacy_guest": false }, "links": { "self": "/api/admin/v1/users/02081040G2081040G2081040G2" @@ -965,7 +967,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": "1970-01-01T00:00:00Z", "deactivated_at": null, - "admin": false + "admin": false, + "legacy_guest": true }, "links": { "self": "/api/admin/v1/users/030C1G60R30C1G60R30C1G60R3" @@ -1017,7 +1020,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": null, "deactivated_at": null, - "admin": false + "admin": false, + "legacy_guest": false }, "links": { "self": "/api/admin/v1/users/01040G2081040G2081040G2081" @@ -1103,7 +1107,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": null, "deactivated_at": null, - "admin": false + "admin": false, + "legacy_guest": false }, "links": { "self": "/api/admin/v1/users/01040G2081040G2081040G2081" @@ -1260,7 +1265,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": null, "deactivated_at": null, - "admin": false + "admin": false, + "legacy_guest": false }, "links": { "self": "/api/admin/v1/users/01040G2081040G2081040G2081" @@ -1340,7 +1346,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": null, "deactivated_at": null, - "admin": true + "admin": true, + "legacy_guest": false }, "links": { "self": "/api/admin/v1/users/02081040G2081040G2081040G2" @@ -1419,7 +1426,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": "1970-01-01T00:00:00Z", "deactivated_at": null, - "admin": false + "admin": false, + "legacy_guest": true }, "links": { "self": "/api/admin/v1/users/030C1G60R30C1G60R30C1G60R3" @@ -1489,7 +1497,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": null, "deactivated_at": null, - "admin": false + "admin": false, + "legacy_guest": false }, "links": { "self": "/api/admin/v1/users/01040G2081040G2081040G2081" @@ -1559,7 +1568,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": "1970-01-01T00:00:00Z", "deactivated_at": null, - "admin": false + "admin": false, + "legacy_guest": true }, "links": { "self": "/api/admin/v1/users/030C1G60R30C1G60R30C1G60R3" @@ -1629,7 +1639,8 @@ "created_at": "1970-01-01T00:00:00Z", "locked_at": null, "deactivated_at": null, - "admin": false + "admin": false, + "legacy_guest": false }, "links": { "self": "/api/admin/v1/users/01040G2081040G2081040G2081" @@ -3941,6 +3952,7 @@ "required": [ "admin", "created_at", + "legacy_guest", "username" ], "properties": { @@ -3968,6 +3980,10 @@ "admin": { "description": "Whether the user can request admin privileges.", "type": "boolean" + }, + "legacy_guest": { + "description": "Whether the user was a guest before migrating to MAS,", + "type": "boolean" } } },