1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-29 22:01:14 +03:00

Simple consent screen and storage

This commit is contained in:
Quentin Gliech
2022-04-29 12:16:39 +02:00
parent bfb00e281d
commit 28ff912029
13 changed files with 419 additions and 6 deletions

View File

@ -0,0 +1,17 @@
-- Copyright 2022 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.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
DROP TRIGGER set_timestamp ON oauth2_consents;
DROP INDEX oauth2_consents_client_id_user_id_key;
DROP TABLE oauth2_consents;

View File

@ -0,0 +1,32 @@
-- Copyright 2022 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.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
CREATE TABLE oauth2_consents (
"id" BIGSERIAL PRIMARY KEY,
"oauth2_client_id" BIGINT NOT NULL REFERENCES oauth2_clients (id) ON DELETE CASCADE,
"user_id" BIGINT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
"scope_token" TEXT NOT NULL,
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
"updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
CONSTRAINT user_client_scope_tuple UNIQUE ("oauth2_client_id", "user_id", "scope_token")
);
CREATE INDEX oauth2_consents_client_id_user_id_key
ON oauth2_consents ("oauth2_client_id", "user_id");
CREATE TRIGGER set_timestamp
BEFORE UPDATE ON oauth2_consents
FOR EACH ROW
EXECUTE PROCEDURE trigger_set_timestamp();

View File

@ -399,6 +399,27 @@
},
"query": "\n SELECT\n og.id AS grant_id,\n og.created_at AS grant_created_at,\n og.cancelled_at AS grant_cancelled_at,\n og.fulfilled_at AS grant_fulfilled_at,\n og.exchanged_at AS grant_exchanged_at,\n og.scope AS grant_scope,\n og.state AS grant_state,\n og.redirect_uri AS grant_redirect_uri,\n og.response_mode AS grant_response_mode,\n og.nonce AS grant_nonce,\n og.max_age AS grant_max_age,\n og.acr_values AS grant_acr_values,\n og.oauth2_client_id AS oauth2_client_id,\n og.code AS grant_code,\n og.response_type_code AS grant_response_type_code,\n og.response_type_token AS grant_response_type_token,\n og.response_type_id_token AS grant_response_type_id_token,\n og.code_challenge AS grant_code_challenge,\n og.code_challenge_method AS grant_code_challenge_method,\n os.id AS \"session_id?\",\n us.id AS \"user_session_id?\",\n us.created_at AS \"user_session_created_at?\",\n u.id AS \"user_id?\",\n u.username AS \"user_username?\",\n usa.id AS \"user_session_last_authentication_id?\",\n usa.created_at AS \"user_session_last_authentication_created_at?\",\n ue.id AS \"user_email_id?\",\n ue.email AS \"user_email?\",\n ue.created_at AS \"user_email_created_at?\",\n ue.confirmed_at AS \"user_email_confirmed_at?\"\n FROM\n oauth2_authorization_grants og\n LEFT JOIN oauth2_sessions os\n ON os.id = og.oauth2_session_id\n LEFT JOIN user_sessions us\n ON us.id = os.user_session_id\n LEFT JOIN users u\n ON u.id = us.user_id\n LEFT JOIN user_session_authentications usa\n ON usa.session_id = us.id\n LEFT JOIN user_emails ue\n ON ue.id = u.primary_email_id\n\n WHERE og.id = $1\n\n ORDER BY usa.created_at DESC\n LIMIT 1\n "
},
"51158bfcaa1a8d8e051bffe7c5ba0369bf53fb162f7622626054e89e68fc07bd": {
"describe": {
"columns": [
{
"name": "scope_token",
"ordinal": 0,
"type_info": "Text"
}
],
"nullable": [
false
],
"parameters": {
"Left": [
"Int8",
"Int8"
]
}
},
"query": "\n SELECT scope_token\n FROM oauth2_consents\n WHERE user_id = $1 AND oauth2_client_id = $2\n "
},
"581243a7f0c033548cc9644e0c60855ecb8bfefe51779eb135dd7547b886de79": {
"describe": {
"columns": [],
@ -1027,6 +1048,20 @@
},
"query": "\n DELETE FROM oauth2_access_tokens\n WHERE id = $1\n "
},
"8ff8e80c3af4f8ab47b30301a573dee26c85bf21f61317278a892d54875ae983": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Int8",
"Int8",
"TextArray"
]
}
},
"query": "\n INSERT INTO oauth2_consents (user_id, oauth2_client_id, scope_token)\n SELECT $1, $2, scope_token FROM UNNEST($3::text[]) scope_token\n "
},
"99270fd3ddcc7421c5b26d0b8e0116356c13166887e7cf6ed6352cc879c80a68": {
"describe": {
"columns": [

View File

@ -0,0 +1,70 @@
// Copyright 2022 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.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::str::FromStr;
use mas_data_model::{Client, User};
use oauth2_types::scope::{Scope, ScopeToken};
use sqlx::PgExecutor;
use crate::PostgresqlBackend;
pub async fn fetch_client_consent(
executor: impl PgExecutor<'_>,
user: &User<PostgresqlBackend>,
client: &Client<PostgresqlBackend>,
) -> anyhow::Result<Scope> {
let scope_tokens: Vec<String> = sqlx::query_scalar!(
r#"
SELECT scope_token
FROM oauth2_consents
WHERE user_id = $1 AND oauth2_client_id = $2
"#,
user.data,
client.data,
)
.fetch_all(executor)
.await?;
let scope: Result<Scope, _> = scope_tokens
.into_iter()
.map(|s| ScopeToken::from_str(&s))
.collect();
Ok(scope?)
}
pub async fn insert_client_consent(
executor: impl PgExecutor<'_>,
user: &User<PostgresqlBackend>,
client: &Client<PostgresqlBackend>,
scope: &Scope,
) -> anyhow::Result<()> {
let tokens: Vec<String> = scope.iter().map(ToString::to_string).collect();
sqlx::query!(
r#"
INSERT INTO oauth2_consents (user_id, oauth2_client_id, scope_token)
SELECT $1, $2, scope_token FROM UNNEST($3::text[]) scope_token
ON CONFLICT (user_id, oauth2_client_id, scope_token) DO UPDATE SET updated_at = NOW()
"#,
user.data,
client.data,
&tokens,
)
.execute(executor)
.await?;
Ok(())
}

View File

@ -1,4 +1,4 @@
// Copyright 2021 The Matrix.org Foundation C.I.C.
// Copyright 2021, 2022 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.
@ -20,6 +20,7 @@ use crate::PostgresqlBackend;
pub mod access_token;
pub mod authorization_grant;
pub mod client;
pub mod consent;
pub mod refresh_token;
pub async fn end_oauth_session(