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

Make sure we validate passwords & emails by the policy at all stages

Also refactors the way we get the policy engines in requests
This commit is contained in:
Quentin Gliech
2023-08-30 16:47:57 +02:00
parent 23151ef092
commit 7fcd022eea
30 changed files with 264 additions and 84 deletions

View File

@@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::sync::Arc;
use axum::{
extract::{Path, State},
response::{Html, IntoResponse, Response},
@@ -22,7 +20,7 @@ use hyper::StatusCode;
use mas_axum_utils::{cookies::CookieJar, csrf::CsrfExt, SessionInfoExt};
use mas_data_model::{AuthorizationGrant, BrowserSession, Client, Device};
use mas_keystore::Keystore;
use mas_policy::{EvaluationResult, PolicyFactory};
use mas_policy::{EvaluationResult, Policy};
use mas_router::{PostAuthAction, Route, UrlBuilder};
use mas_storage::{
oauth2::{OAuth2AuthorizationGrantRepository, OAuth2ClientRepository, OAuth2SessionRepository},
@@ -76,7 +74,6 @@ impl IntoResponse for RouteError {
impl_from_error_for_route!(mas_storage::RepositoryError);
impl_from_error_for_route!(mas_templates::TemplateError);
impl_from_error_for_route!(mas_policy::LoadError);
impl_from_error_for_route!(mas_policy::InstantiateError);
impl_from_error_for_route!(mas_policy::EvaluationError);
impl_from_error_for_route!(super::callback::IntoCallbackDestinationError);
impl_from_error_for_route!(super::callback::CallbackDestinationError);
@@ -90,10 +87,10 @@ impl_from_error_for_route!(super::callback::CallbackDestinationError);
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
State(policy_factory): State<Arc<PolicyFactory>>,
State(templates): State<Templates>,
State(url_builder): State<UrlBuilder>,
State(key_store): State<Keystore>,
policy: Policy,
mut repo: BoxRepository,
cookie_jar: CookieJar,
Path(grant_id): Path<Ulid>,
@@ -128,7 +125,7 @@ pub(crate) async fn get(
&clock,
repo,
key_store,
&policy_factory,
policy,
url_builder,
grant,
&client,
@@ -187,7 +184,6 @@ pub enum GrantCompletionError {
impl_from_error_for_route!(GrantCompletionError: mas_storage::RepositoryError);
impl_from_error_for_route!(GrantCompletionError: super::callback::IntoCallbackDestinationError);
impl_from_error_for_route!(GrantCompletionError: mas_policy::LoadError);
impl_from_error_for_route!(GrantCompletionError: mas_policy::InstantiateError);
impl_from_error_for_route!(GrantCompletionError: mas_policy::EvaluationError);
impl_from_error_for_route!(GrantCompletionError: super::super::IdTokenSignatureError);
@@ -196,7 +192,7 @@ pub(crate) async fn complete(
clock: &impl Clock,
mut repo: BoxRepository,
key_store: Keystore,
policy_factory: &PolicyFactory,
mut policy: Policy,
url_builder: UrlBuilder,
grant: AuthorizationGrant,
client: &Client,
@@ -220,7 +216,6 @@ pub(crate) async fn complete(
};
// Run through the policy
let mut policy = policy_factory.instantiate().await?;
let res = policy
.evaluate_authorization_grant(&grant, client, &browser_session.user)
.await?;

View File

@@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::sync::Arc;
use axum::{
extract::{Form, State},
response::{Html, IntoResponse, Response},
@@ -22,7 +20,7 @@ use hyper::StatusCode;
use mas_axum_utils::{cookies::CookieJar, csrf::CsrfExt, SessionInfoExt};
use mas_data_model::{AuthorizationCode, Pkce};
use mas_keystore::Keystore;
use mas_policy::PolicyFactory;
use mas_policy::Policy;
use mas_router::{PostAuthAction, Route, UrlBuilder};
use mas_storage::{
oauth2::{OAuth2AuthorizationGrantRepository, OAuth2ClientRepository},
@@ -94,7 +92,6 @@ impl_from_error_for_route!(mas_storage::RepositoryError);
impl_from_error_for_route!(mas_templates::TemplateError);
impl_from_error_for_route!(self::callback::CallbackDestinationError);
impl_from_error_for_route!(mas_policy::LoadError);
impl_from_error_for_route!(mas_policy::InstantiateError);
impl_from_error_for_route!(mas_policy::EvaluationError);
#[derive(Deserialize)]
@@ -140,10 +137,10 @@ fn resolve_response_mode(
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
State(policy_factory): State<Arc<PolicyFactory>>,
State(templates): State<Templates>,
State(key_store): State<Keystore>,
State(url_builder): State<UrlBuilder>,
policy: Policy,
mut repo: BoxRepository,
cookie_jar: CookieJar,
Form(params): Form<Params>,
@@ -346,7 +343,7 @@ pub(crate) async fn get(
&clock,
repo,
key_store,
&policy_factory,
policy,
url_builder,
grant,
&client,
@@ -393,7 +390,7 @@ pub(crate) async fn get(
&clock,
repo,
key_store,
&policy_factory,
policy,
url_builder,
grant,
&client,

View File

@@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::sync::Arc;
use axum::{
extract::{Form, Path, State},
response::{Html, IntoResponse, Response},
@@ -25,7 +23,7 @@ use mas_axum_utils::{
SessionInfoExt,
};
use mas_data_model::{AuthorizationGrantStage, Device};
use mas_policy::PolicyFactory;
use mas_policy::Policy;
use mas_router::{PostAuthAction, Route};
use mas_storage::{
oauth2::{OAuth2AuthorizationGrantRepository, OAuth2ClientRepository},
@@ -61,7 +59,6 @@ pub enum RouteError {
impl_from_error_for_route!(mas_templates::TemplateError);
impl_from_error_for_route!(mas_storage::RepositoryError);
impl_from_error_for_route!(mas_policy::LoadError);
impl_from_error_for_route!(mas_policy::InstantiateError);
impl_from_error_for_route!(mas_policy::EvaluationError);
impl IntoResponse for RouteError {
@@ -80,8 +77,8 @@ impl IntoResponse for RouteError {
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
State(policy_factory): State<Arc<PolicyFactory>>,
State(templates): State<Templates>,
mut policy: Policy,
mut repo: BoxRepository,
cookie_jar: CookieJar,
Path(grant_id): Path<Ulid>,
@@ -109,7 +106,6 @@ pub(crate) async fn get(
if let Some(session) = maybe_session {
let (csrf_token, cookie_jar) = cookie_jar.csrf_token(&clock, &mut rng);
let mut policy = policy_factory.instantiate().await?;
let res = policy
.evaluate_authorization_grant(&grant, &client, &session.user)
.await?;
@@ -146,7 +142,7 @@ pub(crate) async fn get(
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,
State(policy_factory): State<Arc<PolicyFactory>>,
mut policy: Policy,
mut repo: BoxRepository,
cookie_jar: CookieJar,
Path(grant_id): Path<Ulid>,
@@ -176,7 +172,6 @@ pub(crate) async fn post(
.await?
.ok_or(RouteError::NoSuchClient)?;
let mut policy = policy_factory.instantiate().await?;
let res = policy
.evaluate_authorization_grant(&grant, &client, &session.user)
.await?;

View File

@@ -12,13 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::sync::Arc;
use axum::{extract::State, response::IntoResponse, Json};
use hyper::StatusCode;
use mas_iana::oauth::OAuthClientAuthenticationMethod;
use mas_keystore::Encrypter;
use mas_policy::{PolicyFactory, Violation};
use mas_policy::{Policy, Violation};
use mas_storage::{oauth2::OAuth2ClientRepository, BoxClock, BoxRepository, BoxRng};
use oauth2_types::{
errors::{ClientError, ClientErrorCode},
@@ -49,7 +47,6 @@ pub(crate) enum RouteError {
impl_from_error_for_route!(mas_storage::RepositoryError);
impl_from_error_for_route!(mas_policy::LoadError);
impl_from_error_for_route!(mas_policy::InstantiateError);
impl_from_error_for_route!(mas_policy::EvaluationError);
impl_from_error_for_route!(mas_keystore::aead::Error);
@@ -136,7 +133,7 @@ pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,
mut repo: BoxRepository,
State(policy_factory): State<Arc<PolicyFactory>>,
mut policy: Policy,
State(encrypter): State<Encrypter>,
body: Result<Json<ClientMetadata>, axum::extract::rejection::JsonRejection>,
) -> Result<impl IntoResponse, RouteError> {
@@ -148,7 +145,6 @@ pub(crate) async fn post(
// Validate the body
let metadata = body.validate()?;
let mut policy = policy_factory.instantiate().await?;
let res = policy.evaluate_client_registration(&metadata).await?;
if !res.valid() {
return Err(RouteError::PolicyDenied(res.violations));