Skip to content

Commit b728e92

Browse files
committed
Add session counts to policy input
1 parent b6097cb commit b728e92

File tree

5 files changed

+67
-2
lines changed

5 files changed

+67
-2
lines changed

crates/handlers/src/oauth2/authorization/consent.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use super::callback::CallbackDestination;
3232
use crate::{
3333
BoundActivityTracker, PreferredLanguage, impl_from_error_for_route,
3434
oauth2::generate_id_token,
35-
session::{SessionOrFallback, load_session_or_fallback},
35+
session::{SessionOrFallback, count_user_sessions_for_limiting, load_session_or_fallback},
3636
};
3737

3838
#[derive(Debug, Error)]
@@ -136,10 +136,15 @@ pub(crate) async fn get(
136136

137137
let (csrf_token, cookie_jar) = cookie_jar.csrf_token(&clock, &mut rng);
138138

139+
let session_counts = count_user_sessions_for_limiting(&mut repo, &session.user)
140+
.await
141+
.map_err(|e| RouteError::Internal(e.into()))?;
142+
139143
let res = policy
140144
.evaluate_authorization_grant(mas_policy::AuthorizationGrantInput {
141145
user: Some(&session.user),
142146
client: &client,
147+
session_counts: Some(session_counts),
143148
scope: &grant.scope,
144149
grant_type: mas_policy::GrantType::AuthorizationCode,
145150
requester: mas_policy::Requester {
@@ -235,10 +240,15 @@ pub(crate) async fn post(
235240
return Err(RouteError::GrantNotPending(grant.id));
236241
}
237242

243+
let session_counts = count_user_sessions_for_limiting(&mut repo, &browser_session.user)
244+
.await
245+
.map_err(|e| RouteError::Internal(e.into()))?;
246+
238247
let res = policy
239248
.evaluate_authorization_grant(mas_policy::AuthorizationGrantInput {
240249
user: Some(&browser_session.user),
241250
client: &client,
251+
session_counts: Some(session_counts),
242252
scope: &grant.scope,
243253
grant_type: mas_policy::GrantType::AuthorizationCode,
244254
requester: mas_policy::Requester {

crates/handlers/src/oauth2/device/consent.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use ulid::Ulid;
2727

2828
use crate::{
2929
BoundActivityTracker, PreferredLanguage,
30-
session::{SessionOrFallback, load_session_or_fallback},
30+
session::{SessionOrFallback, count_user_sessions_for_limiting, load_session_or_fallback},
3131
};
3232

3333
#[derive(Deserialize, Debug)]
@@ -103,11 +103,16 @@ pub(crate) async fn get(
103103
.context("Client not found")
104104
.map_err(InternalError::from_anyhow)?;
105105

106+
let session_counts = count_user_sessions_for_limiting(&mut repo, &session.user)
107+
.await
108+
.map_err(InternalError::from_anyhow)?;
109+
106110
// Evaluate the policy
107111
let res = policy
108112
.evaluate_authorization_grant(mas_policy::AuthorizationGrantInput {
109113
grant_type: mas_policy::GrantType::DeviceCode,
110114
client: &client,
115+
session_counts: Some(session_counts),
111116
scope: &grant.scope,
112117
user: Some(&session.user),
113118
requester: mas_policy::Requester {
@@ -205,11 +210,16 @@ pub(crate) async fn post(
205210
.context("Client not found")
206211
.map_err(InternalError::from_anyhow)?;
207212

213+
let session_counts = count_user_sessions_for_limiting(&mut repo, &session.user)
214+
.await
215+
.map_err(InternalError::from_anyhow)?;
216+
208217
// Evaluate the policy
209218
let res = policy
210219
.evaluate_authorization_grant(mas_policy::AuthorizationGrantInput {
211220
grant_type: mas_policy::GrantType::DeviceCode,
212221
client: &client,
222+
session_counts: Some(session_counts),
213223
scope: &grant.scope,
214224
user: Some(&session.user),
215225
requester: mas_policy::Requester {

crates/handlers/src/oauth2/token.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,7 @@ async fn client_credentials_grant(
781781
.evaluate_authorization_grant(mas_policy::AuthorizationGrantInput {
782782
user: None,
783783
client,
784+
session_counts: None,
784785
scope: &scope,
785786
grant_type: mas_policy::GrantType::ClientCredentials,
786787
requester: mas_policy::Requester {

crates/policy/src/model.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ pub struct AuthorizationGrantInput<'a> {
168168
#[schemars(with = "Option<std::collections::HashMap<String, serde_json::Value>>")]
169169
pub user: Option<&'a User>,
170170

171+
/// How many sessions the user has.
172+
/// Not populated if it's not a user logging in.
173+
pub session_counts: Option<SessionCounts>,
174+
171175
#[schemars(with = "std::collections::HashMap<String, serde_json::Value>")]
172176
pub client: &'a Client,
173177

policies/schema/authorization_grant_input.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
"type": "object",
1515
"additionalProperties": true
1616
},
17+
"session_counts": {
18+
"description": "How many sessions the user has. Not populated if it's not a user logging in.",
19+
"allOf": [
20+
{
21+
"$ref": "#/definitions/SessionCounts"
22+
}
23+
]
24+
},
1725
"client": {
1826
"type": "object",
1927
"additionalProperties": true
@@ -29,6 +37,38 @@
2937
}
3038
},
3139
"definitions": {
40+
"SessionCounts": {
41+
"description": "Information about how many sessions the user has",
42+
"type": "object",
43+
"required": [
44+
"compat",
45+
"oauth2",
46+
"personal",
47+
"total"
48+
],
49+
"properties": {
50+
"total": {
51+
"type": "integer",
52+
"format": "uint64",
53+
"minimum": 0.0
54+
},
55+
"oauth2": {
56+
"type": "integer",
57+
"format": "uint64",
58+
"minimum": 0.0
59+
},
60+
"compat": {
61+
"type": "integer",
62+
"format": "uint64",
63+
"minimum": 0.0
64+
},
65+
"personal": {
66+
"type": "integer",
67+
"format": "uint64",
68+
"minimum": 0.0
69+
}
70+
}
71+
},
3272
"GrantType": {
3373
"type": "string",
3474
"enum": [

0 commit comments

Comments
 (0)