1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-11-21 23:00:50 +03:00

storage: remaining oauth2 repositories

- authorization grants
 - access tokens
 - refresh tokens
This commit is contained in:
Quentin Gliech
2023-01-12 18:26:04 +01:00
parent 36396c0b45
commit 488a666a8d
17 changed files with 1700 additions and 1366 deletions

View File

@@ -26,11 +26,7 @@ use mas_keystore::Encrypter;
use mas_policy::PolicyFactory;
use mas_router::{PostAuthAction, Route};
use mas_storage::{
oauth2::{
authorization_grant::{fulfill_grant, get_grant_by_id},
consent::fetch_client_consent,
OAuth2ClientRepository, OAuth2SessionRepository,
},
oauth2::{OAuth2AuthorizationGrantRepository, OAuth2ClientRepository, OAuth2SessionRepository},
Repository,
};
use mas_templates::Templates;
@@ -94,7 +90,9 @@ pub(crate) async fn get(
let maybe_session = session_info.load_session(&mut txn).await?;
let grant = get_grant_by_id(&mut txn, grant_id)
let grant = txn
.oauth2_authorization_grant()
.lookup(grant_id)
.await?
.ok_or(RouteError::NotFound)?;
@@ -192,7 +190,10 @@ pub(crate) async fn complete(
.await?
.ok_or(GrantCompletionError::NoSuchClient)?;
let current_consent = fetch_client_consent(&mut txn, &browser_session.user, &client).await?;
let current_consent = txn
.oauth2_client()
.get_consent_for_user(&client, &browser_session.user)
.await?;
let lacks_consent = grant
.scope
@@ -211,7 +212,10 @@ pub(crate) async fn complete(
.create_from_grant(&mut rng, &clock, &grant, &browser_session)
.await?;
let grant = fulfill_grant(&mut txn, grant, session.clone()).await?;
let grant = txn
.oauth2_authorization_grant()
.fulfill(&clock, &session, grant)
.await?;
// Yep! Let's complete the auth now
let mut params = AuthorizationResponse::default();

View File

@@ -26,7 +26,7 @@ use mas_keystore::Encrypter;
use mas_policy::PolicyFactory;
use mas_router::{PostAuthAction, Route};
use mas_storage::{
oauth2::{authorization_grant::new_authorization_grant, OAuth2ClientRepository},
oauth2::{OAuth2AuthorizationGrantRepository, OAuth2ClientRepository},
Repository,
};
use mas_templates::Templates;
@@ -275,23 +275,23 @@ pub(crate) async fn get(
let requires_consent = prompt.contains(&Prompt::Consent);
let grant = new_authorization_grant(
&mut txn,
&mut rng,
&clock,
client,
redirect_uri.clone(),
params.auth.scope,
code,
params.auth.state.clone(),
params.auth.nonce,
params.auth.max_age,
None,
response_mode,
response_type.has_id_token(),
requires_consent,
)
.await?;
let grant = txn
.oauth2_authorization_grant()
.add(
&mut rng,
&clock,
&client,
redirect_uri.clone(),
params.auth.scope,
code,
params.auth.state.clone(),
params.auth.nonce,
params.auth.max_age,
response_mode,
response_type.has_id_token(),
requires_consent,
)
.await?;
let continue_grant = PostAuthAction::continue_grant(grant.id);
let res = match maybe_session {

View File

@@ -29,11 +29,7 @@ use mas_keystore::Encrypter;
use mas_policy::PolicyFactory;
use mas_router::{PostAuthAction, Route};
use mas_storage::{
oauth2::{
authorization_grant::{get_grant_by_id, give_consent_to_grant},
consent::insert_client_consent,
OAuth2ClientRepository,
},
oauth2::{OAuth2AuthorizationGrantRepository, OAuth2ClientRepository},
Repository,
};
use mas_templates::{ConsentContext, PolicyViolationContext, TemplateContext, Templates};
@@ -91,7 +87,9 @@ pub(crate) async fn get(
let maybe_session = session_info.load_session(&mut conn).await?;
let grant = get_grant_by_id(&mut conn, grant_id)
let grant = conn
.oauth2_authorization_grant()
.lookup(grant_id)
.await?
.ok_or(RouteError::GrantNotFound)?;
@@ -146,7 +144,9 @@ pub(crate) async fn post(
let maybe_session = session_info.load_session(&mut txn).await?;
let grant = get_grant_by_id(&mut txn, grant_id)
let grant = txn
.oauth2_authorization_grant()
.lookup(grant_id)
.await?
.ok_or(RouteError::GrantNotFound)?;
let next = PostAuthAction::continue_grant(grant_id);
@@ -180,17 +180,17 @@ pub(crate) async fn post(
.filter(|s| !s.starts_with("urn:matrix:org.matrix.msc2967.client:device:"))
.cloned()
.collect();
insert_client_consent(
&mut txn,
&mut rng,
&clock,
&session.user,
&client,
&scope_without_device,
)
.await?;
txn.oauth2_client()
.give_consent_for_user(
&mut rng,
&clock,
&client,
&session.user,
&scope_without_device,
)
.await?;
let _grant = give_consent_to_grant(&mut txn, grant).await?;
txn.oauth2_authorization_grant().give_consent(grant).await?;
txn.commit().await?;

View File

@@ -23,10 +23,7 @@ use mas_iana::oauth::{OAuthClientAuthenticationMethod, OAuthTokenTypeHint};
use mas_keystore::Encrypter;
use mas_storage::{
compat::{CompatAccessTokenRepository, CompatRefreshTokenRepository, CompatSessionRepository},
oauth2::{
access_token::find_access_token, refresh_token::lookup_refresh_token,
OAuth2SessionRepository,
},
oauth2::{OAuth2AccessTokenRepository, OAuth2RefreshTokenRepository, OAuth2SessionRepository},
user::{BrowserSessionRepository, UserRepository},
Clock, Repository,
};
@@ -169,7 +166,9 @@ pub(crate) async fn post(
let reply = match token_type {
TokenType::AccessToken => {
let token = find_access_token(&mut conn, token)
let token = conn
.oauth2_access_token()
.find_by_token(token)
.await?
.filter(|t| t.is_valid(clock.now()))
.ok_or(RouteError::UnknownToken)?;
@@ -206,7 +205,9 @@ pub(crate) async fn post(
}
TokenType::RefreshToken => {
let token = lookup_refresh_token(&mut conn, token)
let token = conn
.oauth2_refresh_token()
.find_by_token(token)
.await?
.filter(|t| t.is_valid())
.ok_or(RouteError::UnknownToken)?;

View File

@@ -1,4 +1,4 @@
// Copyright 2021, 2022 The Matrix.org Foundation C.I.C.
// Copyright 2021-2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -33,10 +33,8 @@ use mas_keystore::{Encrypter, Keystore};
use mas_router::UrlBuilder;
use mas_storage::{
oauth2::{
access_token::{add_access_token, lookup_access_token, revoke_access_token},
authorization_grant::{exchange_grant, lookup_grant_by_code},
refresh_token::{add_refresh_token, consume_refresh_token, lookup_refresh_token},
OAuth2SessionRepository,
OAuth2AccessTokenRepository, OAuth2AuthorizationGrantRepository,
OAuth2RefreshTokenRepository, OAuth2SessionRepository,
},
user::BrowserSessionRepository,
Repository,
@@ -217,9 +215,9 @@ async fn authorization_code_grant(
) -> Result<AccessTokenResponse, RouteError> {
let (clock, mut rng) = crate::clock_and_rng();
// TODO: there is a bunch of unnecessary cloning here
// TODO: handle "not found" cases
let authz_grant = lookup_grant_by_code(&mut txn, &grant.code)
let authz_grant = txn
.oauth2_authorization_grant()
.find_by_code(&grant.code)
.await?
.ok_or(RouteError::GrantNotFound)?;
@@ -301,18 +299,15 @@ async fn authorization_code_grant(
let access_token_str = TokenType::AccessToken.generate(&mut rng);
let refresh_token_str = TokenType::RefreshToken.generate(&mut rng);
let access_token =
add_access_token(&mut txn, &mut rng, &clock, &session, access_token_str, ttl).await?;
let access_token = txn
.oauth2_access_token()
.add(&mut rng, &clock, &session, access_token_str, ttl)
.await?;
let refresh_token = add_refresh_token(
&mut txn,
&mut rng,
&clock,
&session,
&access_token,
refresh_token_str,
)
.await?;
let refresh_token = txn
.oauth2_refresh_token()
.add(&mut rng, &clock, &session, &access_token, refresh_token_str)
.await?;
let id_token = if session.scope.contains(&scope::OPENID) {
let mut claims = HashMap::new();
@@ -360,7 +355,9 @@ async fn authorization_code_grant(
params = params.with_id_token(id_token);
}
exchange_grant(&mut txn, &clock, authz_grant).await?;
txn.oauth2_authorization_grant()
.exchange(&clock, authz_grant)
.await?;
txn.commit().await?;
@@ -374,7 +371,9 @@ async fn refresh_token_grant(
) -> Result<AccessTokenResponse, RouteError> {
let (clock, mut rng) = crate::clock_and_rng();
let refresh_token = lookup_refresh_token(&mut txn, &grant.refresh_token)
let refresh_token = txn
.oauth2_refresh_token()
.find_by_token(&grant.refresh_token)
.await?
.ok_or(RouteError::InvalidGrant)?;
@@ -397,31 +396,32 @@ async fn refresh_token_grant(
let access_token_str = TokenType::AccessToken.generate(&mut rng);
let refresh_token_str = TokenType::RefreshToken.generate(&mut rng);
let new_access_token = add_access_token(
&mut txn,
&mut rng,
&clock,
&session,
access_token_str.clone(),
ttl,
)
.await?;
let new_access_token = txn
.oauth2_access_token()
.add(&mut rng, &clock, &session, access_token_str.clone(), ttl)
.await?;
let new_refresh_token = add_refresh_token(
&mut txn,
&mut rng,
&clock,
&session,
&new_access_token,
refresh_token_str,
)
.await?;
let new_refresh_token = txn
.oauth2_refresh_token()
.add(
&mut rng,
&clock,
&session,
&new_access_token,
refresh_token_str,
)
.await?;
let refresh_token = consume_refresh_token(&mut txn, &clock, refresh_token).await?;
let refresh_token = txn
.oauth2_refresh_token()
.consume(&clock, refresh_token)
.await?;
if let Some(access_token_id) = refresh_token.access_token_id {
if let Some(access_token) = lookup_access_token(&mut txn, access_token_id).await? {
revoke_access_token(&mut txn, &clock, access_token).await?;
if let Some(access_token) = txn.oauth2_access_token().lookup(access_token_id).await? {
txn.oauth2_access_token()
.revoke(&clock, access_token)
.await?;
}
}