aboutsummaryrefslogtreecommitdiff
path: root/server/src/routes/ui/account/mod.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-12-11 01:19:51 +0100
committermetamuffin <metamuffin@disroot.org>2023-12-11 01:19:51 +0100
commit36d7fb2790774c53415c96f8c6955be42bad952f (patch)
tree4481dac53a6d0896e90ff72b9b68665e59e159db /server/src/routes/ui/account/mod.rs
parent767d6c4c7b8518198b0343781128027051b94ae5 (diff)
downloadjellything-36d7fb2790774c53415c96f8c6955be42bad952f.tar
jellything-36d7fb2790774c53415c96f8c6955be42bad952f.tar.bz2
jellything-36d7fb2790774c53415c96f8c6955be42bad952f.tar.zst
(partially) fix security problem with federated session
Diffstat (limited to 'server/src/routes/ui/account/mod.rs')
-rw-r--r--server/src/routes/ui/account/mod.rs28
1 files changed, 22 insertions, 6 deletions
diff --git a/server/src/routes/ui/account/mod.rs b/server/src/routes/ui/account/mod.rs
index 88f6f45..1c5b19a 100644
--- a/server/src/routes/ui/account/mod.rs
+++ b/server/src/routes/ui/account/mod.rs
@@ -6,6 +6,8 @@
pub mod session;
pub mod settings;
+use std::collections::HashSet;
+
use super::{error::MyError, layout::LayoutPage};
use crate::{
database::Database,
@@ -16,7 +18,7 @@ use anyhow::anyhow;
use argon2::{password_hash::Salt, Argon2, PasswordHasher};
use chrono::Duration;
use jellybase::CONF;
-use jellycommon::user::{PermissionSet, Theme, User};
+use jellycommon::user::{PermissionSet, Theme, User, UserPermission};
use rocket::{
form::{Contextual, Form},
get,
@@ -162,7 +164,7 @@ pub fn r_account_login_post(
jar.add(
Cookie::build(
"session",
- login_logic(database, &form.username, &form.password)?,
+ login_logic(database, &form.username, &form.password, None, None)?,
)
.permanent()
.finish(),
@@ -177,11 +179,17 @@ pub fn r_account_logout_post(jar: &CookieJar) -> MyResult<Redirect> {
Ok(Redirect::found(rocket::uri!(r_home())))
}
-pub fn login_logic(database: &Database, username: &str, password: &str) -> MyResult<String> {
+pub fn login_logic(
+ database: &Database,
+ username: &str,
+ password: &str,
+ expire: Option<i64>,
+ drop_permissions: Option<HashSet<UserPermission>>,
+) -> MyResult<String> {
// hashing the password regardless if the accounts exists to prevent timing attacks
let password = hash_password(username, password);
- let user = database
+ let mut user = database
.user
.get(&username.to_string())?
.ok_or(anyhow!("invalid password"))?;
@@ -190,9 +198,17 @@ pub fn login_logic(database: &Database, username: &str, password: &str) -> MyRes
Err(anyhow!("invalid password"))?
}
+ if let Some(ep) = drop_permissions {
+ // remove all grant perms that are in `ep`
+ user.permissions
+ .0
+ .retain(|p, val| if *val { !ep.contains(p) } else { true })
+ }
+
Ok(session::token::create(
- &user,
- Duration::days(CONF.login_expire),
+ user.name,
+ user.permissions,
+ Duration::days(CONF.login_expire.min(expire.unwrap_or(i64::MAX))),
))
}