1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-11-20 12:02:22 +03:00

Use iana generated types in more places

This commit is contained in:
Quentin Gliech
2022-01-12 12:22:54 +01:00
parent 2844706bb1
commit 5b9c35a079
20 changed files with 222 additions and 211 deletions

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::collections::{HashMap, HashSet};
use std::collections::HashMap;
use chrono::Duration;
use hyper::{
@@ -25,6 +25,7 @@ use mas_data_model::{
Authentication, AuthorizationCode, AuthorizationGrant, AuthorizationGrantStage, BrowserSession,
Pkce, StorageBackend, TokenType,
};
use mas_iana::oauth::OAuthAuthorizationEndpointResponseType;
use mas_storage::{
oauth2::{
access_token::add_access_token,
@@ -50,9 +51,9 @@ use oauth2_types::{
RegistrationNotSupported, RequestNotSupported, RequestUriNotSupported,
},
pkce,
prelude::*,
requests::{
AccessTokenResponse, AuthorizationRequest, AuthorizationResponse, Prompt, ResponseMode,
ResponseType,
},
scope::ScopeToken,
};
@@ -191,16 +192,15 @@ struct Params {
/// figure out what response mode must be used, and emit an error if the
/// suggested response mode isn't allowed for the given response types.
fn resolve_response_mode(
response_type: &HashSet<ResponseType>,
response_type: OAuthAuthorizationEndpointResponseType,
suggested_response_mode: Option<ResponseMode>,
) -> anyhow::Result<ResponseMode> {
use ResponseMode as M;
use ResponseType as T;
// If the response type includes either "token" or "id_token", the default
// response mode is "fragment" and the response mode "query" must not be
// used
if response_type.contains(&T::Token) || response_type.contains(&T::IdToken) {
if response_type.has_token() || response_type.has_id_token() {
match suggested_response_mode {
None => Ok(M::Fragment),
Some(M::Query) => Err(anyhow::anyhow!("invalid response mode")),
@@ -345,11 +345,11 @@ async fn get(
let redirect_uri = client
.resolve_redirect_uri(&params.auth.redirect_uri)
.wrap_error()?;
let response_type = &params.auth.response_type;
let response_type = params.auth.response_type;
let response_mode =
resolve_response_mode(response_type, params.auth.response_mode).wrap_error()?;
let code: Option<AuthorizationCode> = if response_type.contains(&ResponseType::Code) {
let code: Option<AuthorizationCode> = if response_type.has_code() {
// 32 random alphanumeric characters, about 190bit of entropy
let code: String = thread_rng()
.sample_iter(&Alphanumeric)
@@ -400,8 +400,8 @@ async fn get(
params.auth.max_age,
None,
response_mode,
response_type.contains(&ResponseType::Token),
response_type.contains(&ResponseType::IdToken),
response_type.has_token(),
response_type.has_id_token(),
)
.await
.wrap_error()?;

View File

@@ -15,12 +15,17 @@
use std::collections::HashSet;
use mas_config::OAuth2Config;
use mas_iana::jose::JsonWebSignatureAlg;
use mas_iana::{
jose::JsonWebSignatureAlg,
oauth::{
OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod,
PkceCodeChallengeMethod,
},
};
use mas_jose::SigningKeystore;
use oauth2_types::{
oidc::{ClaimType, Metadata, SubjectType},
pkce::CodeChallengeMethod,
requests::{ClientAuthenticationMethod, Display, GrantType, ResponseMode},
requests::{Display, GrantType, ResponseMode},
};
use warp::{filters::BoxedFilter, Filter, Reply};
@@ -34,11 +39,11 @@ pub(super) fn filter(
// This is how clients can authenticate
let client_auth_methods_supported = Some({
let mut s = HashSet::new();
s.insert(ClientAuthenticationMethod::ClientSecretBasic);
s.insert(ClientAuthenticationMethod::ClientSecretPost);
s.insert(ClientAuthenticationMethod::ClientSecretJwt);
s.insert(ClientAuthenticationMethod::PrivateKeyJwt);
s.insert(ClientAuthenticationMethod::None);
s.insert(OAuthClientAuthenticationMethod::ClientSecretBasic);
s.insert(OAuthClientAuthenticationMethod::ClientSecretPost);
s.insert(OAuthClientAuthenticationMethod::ClientSecretJwt);
s.insert(OAuthClientAuthenticationMethod::PrivateKeyJwt);
s.insert(OAuthClientAuthenticationMethod::None);
s
});
@@ -72,13 +77,13 @@ pub(super) fn filter(
let response_types_supported = Some({
let mut s = HashSet::new();
s.insert("code".to_string());
s.insert("token".to_string());
s.insert("id_token".to_string());
s.insert("code token".to_string());
s.insert("code id_token".to_string());
s.insert("token id_token".to_string());
s.insert("code token id_token".to_string());
s.insert(OAuthAuthorizationEndpointResponseType::Code);
s.insert(OAuthAuthorizationEndpointResponseType::Token);
s.insert(OAuthAuthorizationEndpointResponseType::IdToken);
s.insert(OAuthAuthorizationEndpointResponseType::CodeToken);
s.insert(OAuthAuthorizationEndpointResponseType::CodeIdToken);
s.insert(OAuthAuthorizationEndpointResponseType::IdTokenToken);
s.insert(OAuthAuthorizationEndpointResponseType::CodeIdToken);
s
});
@@ -107,8 +112,8 @@ pub(super) fn filter(
let code_challenge_methods_supported = Some({
let mut s = HashSet::new();
s.insert(CodeChallengeMethod::Plain);
s.insert(CodeChallengeMethod::S256);
s.insert(PkceCodeChallengeMethod::Plain);
s.insert(PkceCodeChallengeMethod::S256);
s
});

View File

@@ -14,6 +14,7 @@
use mas_config::{OAuth2ClientConfig, OAuth2Config};
use mas_data_model::TokenType;
use mas_iana::oauth::{OAuthClientAuthenticationMethod, OAuthTokenTypeHint};
use mas_storage::oauth2::{
access_token::lookup_active_access_token, refresh_token::lookup_active_refresh_token,
};
@@ -21,9 +22,7 @@ use mas_warp_utils::{
errors::WrapError,
filters::{client::client_authentication, database::connection},
};
use oauth2_types::requests::{
ClientAuthenticationMethod, IntrospectionRequest, IntrospectionResponse, TokenTypeHint,
};
use oauth2_types::requests::{IntrospectionRequest, IntrospectionResponse};
use sqlx::{pool::PoolConnection, PgPool, Postgres};
use tracing::{info, warn};
use warp::{filters::BoxedFilter, Filter, Rejection, Reply};
@@ -64,12 +63,12 @@ const INACTIVE: IntrospectionResponse = IntrospectionResponse {
async fn introspect(
mut conn: PoolConnection<Postgres>,
auth: ClientAuthenticationMethod,
auth: OAuthClientAuthenticationMethod,
client: OAuth2ClientConfig,
params: IntrospectionRequest,
) -> Result<Box<dyn Reply>, Rejection> {
// Token introspection is only allowed by confidential clients
if auth.public() {
if auth == OAuthClientAuthenticationMethod::None {
warn!(?client, "Client tried to introspect");
// TODO: have a nice error here
return Ok(Box::new(warp::reply::json(&INACTIVE)));
@@ -96,7 +95,7 @@ async fn introspect(
scope: Some(session.scope),
client_id: Some(session.client.client_id),
username: Some(session.browser_session.user.username),
token_type: Some(TokenTypeHint::AccessToken),
token_type: Some(OAuthTokenTypeHint::AccessToken),
exp: Some(exp),
iat: Some(token.created_at),
nbf: Some(token.created_at),
@@ -116,7 +115,7 @@ async fn introspect(
scope: Some(session.scope),
client_id: Some(session.client.client_id),
username: Some(session.browser_session.user.username),
token_type: Some(TokenTypeHint::RefreshToken),
token_type: Some(OAuthTokenTypeHint::RefreshToken),
exp: None,
iat: Some(token.created_at),
nbf: Some(token.created_at),

View File

@@ -21,7 +21,7 @@ use headers::{CacheControl, Pragma};
use hyper::StatusCode;
use mas_config::{OAuth2ClientConfig, OAuth2Config};
use mas_data_model::{AuthorizationGrantStage, TokenType};
use mas_iana::jose::JsonWebSignatureAlg;
use mas_iana::{jose::JsonWebSignatureAlg, oauth::OAuthClientAuthenticationMethod};
use mas_jose::{
claims::{AT_HASH, AUD, AUTH_TIME, C_HASH, EXP, IAT, ISS, NONCE, SUB},
DecodedJsonWebToken, SigningKeystore, StaticKeystore,
@@ -42,8 +42,7 @@ use mas_warp_utils::{
use oauth2_types::{
errors::{InvalidGrant, InvalidRequest, OAuth2Error, OAuth2ErrorCode, UnauthorizedClient},
requests::{
AccessTokenRequest, AccessTokenResponse, AuthorizationCodeGrant,
ClientAuthenticationMethod, RefreshTokenGrant,
AccessTokenRequest, AccessTokenResponse, AuthorizationCodeGrant, RefreshTokenGrant,
},
scope::OPENID,
};
@@ -131,7 +130,7 @@ async fn recover(rejection: Rejection) -> Result<Box<dyn Reply>, Rejection> {
}
async fn token(
_auth: ClientAuthenticationMethod,
_auth: OAuthClientAuthenticationMethod,
client: OAuth2ClientConfig,
req: AccessTokenRequest,
key_store: Arc<StaticKeystore>,