Don't apply a session limit when genuinely replacing a session
This commit is contained in:
@@ -576,7 +576,8 @@ async fn token_login(
|
|||||||
Device::generate(rng)
|
Device::generate(rng)
|
||||||
};
|
};
|
||||||
|
|
||||||
repo.app_session()
|
let session_replaced = repo
|
||||||
|
.app_session()
|
||||||
.finish_sessions_to_replace_device(clock, &browser_session.user, &device)
|
.finish_sessions_to_replace_device(clock, &browser_session.user, &device)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@@ -586,6 +587,7 @@ async fn token_login(
|
|||||||
.evaluate_compat_login(mas_policy::CompatLoginInput {
|
.evaluate_compat_login(mas_policy::CompatLoginInput {
|
||||||
user: &browser_session.user,
|
user: &browser_session.user,
|
||||||
login_type: CompatLoginType::WebSso,
|
login_type: CompatLoginType::WebSso,
|
||||||
|
session_replaced,
|
||||||
session_counts,
|
session_counts,
|
||||||
requester,
|
requester,
|
||||||
})
|
})
|
||||||
@@ -702,7 +704,8 @@ async fn user_password_login(
|
|||||||
Device::generate(&mut rng)
|
Device::generate(&mut rng)
|
||||||
};
|
};
|
||||||
|
|
||||||
repo.app_session()
|
let session_replaced = repo
|
||||||
|
.app_session()
|
||||||
.finish_sessions_to_replace_device(clock, &user, &device)
|
.finish_sessions_to_replace_device(clock, &user, &device)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@@ -712,6 +715,7 @@ async fn user_password_login(
|
|||||||
.evaluate_compat_login(mas_policy::CompatLoginInput {
|
.evaluate_compat_login(mas_policy::CompatLoginInput {
|
||||||
user: &user,
|
user: &user,
|
||||||
login_type: CompatLoginType::Password,
|
login_type: CompatLoginType::Password,
|
||||||
|
session_replaced,
|
||||||
session_counts,
|
session_counts,
|
||||||
requester: policy_requester,
|
requester: policy_requester,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ pub async fn get(
|
|||||||
.evaluate_compat_login(mas_policy::CompatLoginInput {
|
.evaluate_compat_login(mas_policy::CompatLoginInput {
|
||||||
user: &session.user,
|
user: &session.user,
|
||||||
login_type: CompatLoginType::WebSso,
|
login_type: CompatLoginType::WebSso,
|
||||||
|
// TODO should we predict a replacement?
|
||||||
|
session_replaced: false,
|
||||||
session_counts,
|
session_counts,
|
||||||
requester: mas_policy::Requester {
|
requester: mas_policy::Requester {
|
||||||
ip_address: activity_tracker.ip(),
|
ip_address: activity_tracker.ip(),
|
||||||
@@ -251,6 +253,8 @@ pub async fn post(
|
|||||||
user: &session.user,
|
user: &session.user,
|
||||||
login_type: CompatLoginType::WebSso,
|
login_type: CompatLoginType::WebSso,
|
||||||
session_counts,
|
session_counts,
|
||||||
|
// TODO should we predict a replacement?
|
||||||
|
session_replaced: false,
|
||||||
requester: mas_policy::Requester {
|
requester: mas_policy::Requester {
|
||||||
ip_address: activity_tracker.ip(),
|
ip_address: activity_tracker.ip(),
|
||||||
user_agent,
|
user_agent,
|
||||||
|
|||||||
@@ -197,6 +197,9 @@ pub struct CompatLoginInput<'a> {
|
|||||||
/// How many sessions the user has.
|
/// How many sessions the user has.
|
||||||
pub session_counts: SessionCounts,
|
pub session_counts: SessionCounts,
|
||||||
|
|
||||||
|
/// Whether a session will be replaced by this login
|
||||||
|
pub session_replaced: bool,
|
||||||
|
|
||||||
// TODO is this actually what we care about? Don't we care a bit more about whether we're in an
|
// TODO is this actually what we care about? Don't we care a bit more about whether we're in an
|
||||||
// interactive context or a non-interactive context? (SSO type has both phases :()
|
// interactive context or a non-interactive context? (SSO type has both phases :()
|
||||||
pub login_type: CompatLoginType,
|
pub login_type: CompatLoginType,
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ violation contains {
|
|||||||
# TODO not strictly correct...
|
# TODO not strictly correct...
|
||||||
input.login_type == "m.login.sso"
|
input.login_type == "m.login.sso"
|
||||||
|
|
||||||
|
# Only apply if this login doesn't replace a session
|
||||||
|
# (As then this login is not actually increasing the number of devices)
|
||||||
|
not input.session_replaced
|
||||||
|
|
||||||
# For web-based 'compat SSO' login, a violation occurs when the soft limit has already been
|
# For web-based 'compat SSO' login, a violation occurs when the soft limit has already been
|
||||||
# reached or exceeded.
|
# reached or exceeded.
|
||||||
# We use the soft limit because the user will be able to interactively remove
|
# We use the soft limit because the user will be able to interactively remove
|
||||||
@@ -53,6 +57,10 @@ violation contains {
|
|||||||
# This is not a web-based interactive login
|
# This is not a web-based interactive login
|
||||||
input.login_type == "m.login.password"
|
input.login_type == "m.login.password"
|
||||||
|
|
||||||
|
# Only apply if this login doesn't replace a session
|
||||||
|
# (As then this login is not actually increasing the number of devices)
|
||||||
|
not input.session_replaced
|
||||||
|
|
||||||
# For `m.login.password` login, a violation occurs when the hard limit has already been
|
# For `m.login.password` login, a violation occurs when the hard limit has already been
|
||||||
# reached or exceeded.
|
# reached or exceeded.
|
||||||
# We don't use the soft limit because the user won't be able to interactively remove
|
# We don't use the soft limit because the user won't be able to interactively remove
|
||||||
|
|||||||
@@ -14,32 +14,38 @@ test_session_limiting_sso if {
|
|||||||
compat_login.allow with input.user as user
|
compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 1}
|
with input.session_counts as {"total": 1}
|
||||||
with input.login_type as "m.login.sso"
|
with input.login_type as "m.login.sso"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
|
||||||
compat_login.allow with input.user as user
|
compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 31}
|
with input.session_counts as {"total": 31}
|
||||||
with input.login_type as "m.login.sso"
|
with input.login_type as "m.login.sso"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
|
||||||
not compat_login.allow with input.user as user
|
not compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 32}
|
with input.session_counts as {"total": 32}
|
||||||
with input.login_type as "m.login.sso"
|
with input.login_type as "m.login.sso"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
|
||||||
not compat_login.allow with input.user as user
|
not compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 42}
|
with input.session_counts as {"total": 42}
|
||||||
with input.login_type as "m.login.sso"
|
with input.login_type as "m.login.sso"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
|
||||||
not compat_login.allow with input.user as user
|
not compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 65}
|
with input.session_counts as {"total": 65}
|
||||||
with input.login_type as "m.login.sso"
|
with input.login_type as "m.login.sso"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
|
||||||
# No limit configured
|
# No limit configured
|
||||||
compat_login.allow with input.user as user
|
compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 1}
|
with input.session_counts as {"total": 1}
|
||||||
with input.login_type as "m.login.sso"
|
with input.login_type as "m.login.sso"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as null
|
with data.session_limit as null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,26 +53,45 @@ test_session_limiting_password if {
|
|||||||
compat_login.allow with input.user as user
|
compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 1}
|
with input.session_counts as {"total": 1}
|
||||||
with input.login_type as "m.login.password"
|
with input.login_type as "m.login.password"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
|
||||||
compat_login.allow with input.user as user
|
compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 63}
|
with input.session_counts as {"total": 63}
|
||||||
with input.login_type as "m.login.password"
|
with input.login_type as "m.login.password"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
|
||||||
not compat_login.allow with input.user as user
|
not compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 64}
|
with input.session_counts as {"total": 64}
|
||||||
with input.login_type as "m.login.password"
|
with input.login_type as "m.login.password"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
|
||||||
not compat_login.allow with input.user as user
|
not compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 65}
|
with input.session_counts as {"total": 65}
|
||||||
with input.login_type as "m.login.password"
|
with input.login_type as "m.login.password"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
|
||||||
# No limit configured
|
# No limit configured
|
||||||
compat_login.allow with input.user as user
|
compat_login.allow with input.user as user
|
||||||
with input.session_counts as {"total": 1}
|
with input.session_counts as {"total": 1}
|
||||||
with input.login_type as "m.login.password"
|
with input.login_type as "m.login.password"
|
||||||
|
with input.session_replaced as false
|
||||||
with data.session_limit as null
|
with data.session_limit as null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_no_session_limiting_upon_replacement if {
|
||||||
|
not compat_login.allow with input.user as user
|
||||||
|
with input.session_counts as {"total": 65}
|
||||||
|
with input.login_type as "m.login.password"
|
||||||
|
with input.session_replaced as false
|
||||||
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
|
||||||
|
not compat_login.allow with input.user as user
|
||||||
|
with input.session_counts as {"total": 65}
|
||||||
|
with input.login_type as "m.login.sso"
|
||||||
|
with input.session_replaced as false
|
||||||
|
with data.session_limit as {"soft_limit": 32, "hard_limit": 64}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"login_type",
|
"login_type",
|
||||||
"requester",
|
"requester",
|
||||||
"session_counts",
|
"session_counts",
|
||||||
|
"session_replaced",
|
||||||
"user"
|
"user"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -22,6 +23,10 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"session_replaced": {
|
||||||
|
"description": "Whether a session will be replaced by this login",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"login_type": {
|
"login_type": {
|
||||||
"$ref": "#/definitions/CompatLoginType"
|
"$ref": "#/definitions/CompatLoginType"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user