You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-28 11:02:02 +03:00
Add a admin flag to the compatibility session
Also adds a CLI tool to issue a compatibility token.
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3139,6 +3139,7 @@ dependencies = [
|
|||||||
"itertools",
|
"itertools",
|
||||||
"listenfd",
|
"listenfd",
|
||||||
"mas-config",
|
"mas-config",
|
||||||
|
"mas-data-model",
|
||||||
"mas-email",
|
"mas-email",
|
||||||
"mas-handlers",
|
"mas-handlers",
|
||||||
"mas-http",
|
"mas-http",
|
||||||
|
@ -46,6 +46,7 @@ sentry-tracing = "0.31.3"
|
|||||||
sentry-tower = { version = "0.31.3", features = ["http"] }
|
sentry-tower = { version = "0.31.3", features = ["http"] }
|
||||||
|
|
||||||
mas-config = { path = "../config" }
|
mas-config = { path = "../config" }
|
||||||
|
mas-data-model = { path = "../data-model" }
|
||||||
mas-email = { path = "../email" }
|
mas-email = { path = "../email" }
|
||||||
mas-handlers = { path = "../handlers", default-features = false }
|
mas-handlers = { path = "../handlers", default-features = false }
|
||||||
mas-http = { path = "../http", default-features = false, features = ["axum", "client"] }
|
mas-http = { path = "../http", default-features = false, features = ["axum", "client"] }
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::{Parser, ValueEnum};
|
use clap::{Parser, ValueEnum};
|
||||||
use mas_config::{DatabaseConfig, PasswordsConfig, RootConfig};
|
use mas_config::{DatabaseConfig, PasswordsConfig, RootConfig};
|
||||||
|
use mas_data_model::{Device, TokenType};
|
||||||
use mas_iana::{jose::JsonWebSignatureAlg, oauth::OAuthClientAuthenticationMethod};
|
use mas_iana::{jose::JsonWebSignatureAlg, oauth::OAuthClientAuthenticationMethod};
|
||||||
use mas_router::UrlBuilder;
|
use mas_router::UrlBuilder;
|
||||||
use mas_storage::{
|
use mas_storage::{
|
||||||
|
compat::{CompatAccessTokenRepository, CompatSessionRepository},
|
||||||
oauth2::OAuth2ClientRepository,
|
oauth2::OAuth2ClientRepository,
|
||||||
upstream_oauth2::UpstreamOAuthProviderRepository,
|
upstream_oauth2::UpstreamOAuthProviderRepository,
|
||||||
user::{UserEmailRepository, UserPasswordRepository, UserRepository},
|
user::{UserEmailRepository, UserPasswordRepository, UserRepository},
|
||||||
@ -182,6 +184,20 @@ enum Subcommand {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
client_secret: Option<String>,
|
client_secret: Option<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Issue a compatibility token
|
||||||
|
IssueCompatibilityToken {
|
||||||
|
/// User for which to issue the token
|
||||||
|
username: String,
|
||||||
|
|
||||||
|
/// Device ID to set in the token. If not specified, a random device ID
|
||||||
|
/// will be generated.
|
||||||
|
device_id: Option<String>,
|
||||||
|
|
||||||
|
/// Whether that token should be admin
|
||||||
|
#[arg(long = "yes-i-want-to-grant-synapse-admin-privileges")]
|
||||||
|
admin: bool,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Options {
|
impl Options {
|
||||||
@ -375,6 +391,53 @@ impl Options {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SC::IssueCompatibilityToken {
|
||||||
|
username,
|
||||||
|
admin,
|
||||||
|
device_id,
|
||||||
|
} => {
|
||||||
|
let config: DatabaseConfig = root.load_config()?;
|
||||||
|
let pool = database_from_config(&config).await?;
|
||||||
|
let mut repo = PgRepository::from_pool(&pool).await?.boxed();
|
||||||
|
|
||||||
|
let user = repo
|
||||||
|
.user()
|
||||||
|
.find_by_username(username)
|
||||||
|
.await?
|
||||||
|
.context("User not found")?;
|
||||||
|
|
||||||
|
let device = if let Some(device_id) = device_id {
|
||||||
|
device_id.clone().try_into()?
|
||||||
|
} else {
|
||||||
|
Device::generate(&mut rng)
|
||||||
|
};
|
||||||
|
|
||||||
|
let compat_session = repo
|
||||||
|
.compat_session()
|
||||||
|
.add(&mut rng, &clock, &user, device, *admin)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let token = TokenType::CompatAccessToken.generate(&mut rng);
|
||||||
|
|
||||||
|
let compat_access_token = repo
|
||||||
|
.compat_access_token()
|
||||||
|
.add(&mut rng, &clock, &compat_session, token, None)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
repo.save().await?;
|
||||||
|
|
||||||
|
info!(
|
||||||
|
%compat_access_token.id,
|
||||||
|
%compat_session.id,
|
||||||
|
%compat_session.device,
|
||||||
|
%user.id,
|
||||||
|
%user.username,
|
||||||
|
"Compatibility token issued: {}", compat_access_token.token
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,12 @@ impl TryFrom<String> for Device {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Device {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str(&self.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use oauth2_types::scope::OPENID;
|
use oauth2_types::scope::OPENID;
|
||||||
|
@ -68,6 +68,7 @@ pub struct CompatSession {
|
|||||||
pub user_id: Ulid,
|
pub user_id: Ulid,
|
||||||
pub device: Device,
|
pub device: Device,
|
||||||
pub created_at: DateTime<Utc>,
|
pub created_at: DateTime<Utc>,
|
||||||
|
pub is_synapse_admin: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for CompatSession {
|
impl std::ops::Deref for CompatSession {
|
||||||
|
@ -399,7 +399,7 @@ async fn user_password_login(
|
|||||||
|
|
||||||
let session = repo
|
let session = repo
|
||||||
.compat_session()
|
.compat_session()
|
||||||
.add(&mut rng, clock, &user, device)
|
.add(&mut rng, clock, &user, device, false)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok((session, user))
|
Ok((session, user))
|
||||||
@ -726,7 +726,7 @@ mod tests {
|
|||||||
// Complete the flow by fulfilling it with a session
|
// Complete the flow by fulfilling it with a session
|
||||||
let compat_session = repo
|
let compat_session = repo
|
||||||
.compat_session()
|
.compat_session()
|
||||||
.add(&mut state.rng(), &state.clock, user, device.clone())
|
.add(&mut state.rng(), &state.clock, user, device.clone(), false)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ pub async fn post(
|
|||||||
|
|
||||||
let compat_session = repo
|
let compat_session = repo
|
||||||
.compat_session()
|
.compat_session()
|
||||||
.add(&mut rng, &clock, &session.user, device)
|
.add(&mut rng, &clock, &session.user, device, false)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
repo.compat_sso_login()
|
repo.compat_sso_login()
|
||||||
|
@ -120,6 +120,7 @@ const INACTIVE: IntrospectionResponse = IntrospectionResponse {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const API_SCOPE: ScopeToken = ScopeToken::from_static("urn:matrix:org.matrix.msc2967.client:api:*");
|
const API_SCOPE: ScopeToken = ScopeToken::from_static("urn:matrix:org.matrix.msc2967.client:api:*");
|
||||||
|
const SYNAPSE_ADMIN_SCOPE: ScopeToken = ScopeToken::from_static("urn:synapse:admin:*");
|
||||||
|
|
||||||
#[tracing::instrument(
|
#[tracing::instrument(
|
||||||
name = "handlers.oauth2.introspection.post",
|
name = "handlers.oauth2.introspection.post",
|
||||||
@ -267,8 +268,13 @@ pub(crate) async fn post(
|
|||||||
// XXX: is that the right error to bubble up?
|
// XXX: is that the right error to bubble up?
|
||||||
.ok_or(RouteError::UnknownToken)?;
|
.ok_or(RouteError::UnknownToken)?;
|
||||||
|
|
||||||
|
// Grant the synapse admin scope if the session has the admin flag set.
|
||||||
|
let synapse_admin = session.is_synapse_admin.then_some(SYNAPSE_ADMIN_SCOPE);
|
||||||
let device_scope = session.device.to_scope_token();
|
let device_scope = session.device.to_scope_token();
|
||||||
let scope = [API_SCOPE, device_scope].into_iter().collect();
|
let scope = [API_SCOPE, device_scope]
|
||||||
|
.into_iter()
|
||||||
|
.chain(synapse_admin)
|
||||||
|
.collect();
|
||||||
|
|
||||||
IntrospectionResponse {
|
IntrospectionResponse {
|
||||||
active: true,
|
active: true,
|
||||||
@ -308,8 +314,13 @@ pub(crate) async fn post(
|
|||||||
// XXX: is that the right error to bubble up?
|
// XXX: is that the right error to bubble up?
|
||||||
.ok_or(RouteError::UnknownToken)?;
|
.ok_or(RouteError::UnknownToken)?;
|
||||||
|
|
||||||
|
// Grant the synapse admin scope if the session has the admin flag set.
|
||||||
|
let synapse_admin = session.is_synapse_admin.then_some(SYNAPSE_ADMIN_SCOPE);
|
||||||
let device_scope = session.device.to_scope_token();
|
let device_scope = session.device.to_scope_token();
|
||||||
let scope = [API_SCOPE, device_scope].into_iter().collect();
|
let scope = [API_SCOPE, device_scope]
|
||||||
|
.into_iter()
|
||||||
|
.chain(synapse_admin)
|
||||||
|
.collect();
|
||||||
|
|
||||||
IntrospectionResponse {
|
IntrospectionResponse {
|
||||||
active: true,
|
active: true,
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
-- Copyright 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.
|
||||||
|
-- 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.
|
||||||
|
|
||||||
|
ALTER TABLE compat_sessions
|
||||||
|
ADD COLUMN is_synapse_admin BOOLEAN NOT NULL DEFAULT FALSE;
|
@ -14,6 +14,56 @@
|
|||||||
},
|
},
|
||||||
"query": "\n UPDATE oauth2_authorization_grants\n SET fulfilled_at = $2\n , oauth2_session_id = $3\n WHERE oauth2_authorization_grant_id = $1\n "
|
"query": "\n UPDATE oauth2_authorization_grants\n SET fulfilled_at = $2\n , oauth2_session_id = $3\n WHERE oauth2_authorization_grant_id = $1\n "
|
||||||
},
|
},
|
||||||
|
"0469c1d3ad11fd96febacad33302709c870ead848d6920cdfdb18912d543488e": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "compat_session_id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Uuid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "device_id",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user_id",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Uuid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "created_at",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Timestamptz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "finished_at",
|
||||||
|
"ordinal": 4,
|
||||||
|
"type_info": "Timestamptz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "is_synapse_admin",
|
||||||
|
"ordinal": 5,
|
||||||
|
"type_info": "Bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Uuid"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "\n SELECT compat_session_id\n , device_id\n , user_id\n , created_at\n , finished_at\n , is_synapse_admin\n FROM compat_sessions\n WHERE compat_session_id = $1\n "
|
||||||
|
},
|
||||||
"08d7df347c806ef14b6d0fb031cab041d79ba48528420160e23286369db7af35": {
|
"08d7df347c806ef14b6d0fb031cab041d79ba48528420160e23286369db7af35": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
@ -112,21 +162,6 @@
|
|||||||
},
|
},
|
||||||
"query": "\n SELECT\n upstream_oauth_provider_id,\n issuer,\n scope,\n client_id,\n encrypted_client_secret,\n token_endpoint_signing_alg,\n token_endpoint_auth_method,\n created_at\n FROM upstream_oauth_providers\n "
|
"query": "\n SELECT\n upstream_oauth_provider_id,\n issuer,\n scope,\n client_id,\n encrypted_client_secret,\n token_endpoint_signing_alg,\n token_endpoint_auth_method,\n created_at\n FROM upstream_oauth_providers\n "
|
||||||
},
|
},
|
||||||
"18c3e56c72ef26bd42653c379767ffdd97bb06cb1686dfbf4099f3ad3d7b22c8": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [],
|
|
||||||
"nullable": [],
|
|
||||||
"parameters": {
|
|
||||||
"Left": [
|
|
||||||
"Uuid",
|
|
||||||
"Uuid",
|
|
||||||
"Text",
|
|
||||||
"Timestamptz"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "\n INSERT INTO compat_sessions (compat_session_id, user_id, device_id, created_at)\n VALUES ($1, $2, $3, $4)\n "
|
|
||||||
},
|
|
||||||
"1a8701f5672de052bb766933f60b93249acc7237b996e8b93cd61b9f69c902ff": {
|
"1a8701f5672de052bb766933f60b93249acc7237b996e8b93cd61b9f69c902ff": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
@ -1913,6 +1948,22 @@
|
|||||||
},
|
},
|
||||||
"query": "\n UPDATE oauth2_authorization_grants\n SET exchanged_at = $2\n WHERE oauth2_authorization_grant_id = $1\n "
|
"query": "\n UPDATE oauth2_authorization_grants\n SET exchanged_at = $2\n WHERE oauth2_authorization_grant_id = $1\n "
|
||||||
},
|
},
|
||||||
|
"cff3ac0fff62ffdc5640fce08c2ffabc1d89202561b736c5d03b501dfcd8d886": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Uuid",
|
||||||
|
"Uuid",
|
||||||
|
"Text",
|
||||||
|
"Timestamptz",
|
||||||
|
"Bool"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "\n INSERT INTO compat_sessions (compat_session_id, user_id, device_id, created_at, is_synapse_admin)\n VALUES ($1, $2, $3, $4, $5)\n "
|
||||||
|
},
|
||||||
"d0b403e9c843ef19fa5ad60bec32ebf14a1ba0d01681c3836366d3f55e7851f4": {
|
"d0b403e9c843ef19fa5ad60bec32ebf14a1ba0d01681c3836366d3f55e7851f4": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
@ -2388,50 +2439,6 @@
|
|||||||
},
|
},
|
||||||
"query": "\n SELECT oauth2_session_id\n , user_session_id\n , oauth2_client_id\n , scope\n , created_at\n , finished_at\n FROM oauth2_sessions\n\n WHERE oauth2_session_id = $1\n "
|
"query": "\n SELECT oauth2_session_id\n , user_session_id\n , oauth2_client_id\n , scope\n , created_at\n , finished_at\n FROM oauth2_sessions\n\n WHERE oauth2_session_id = $1\n "
|
||||||
},
|
},
|
||||||
"f3ee06958d827b152c57328caa0a6030c372cb99cdb60e4b75a28afeb5096f45": {
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"name": "compat_session_id",
|
|
||||||
"ordinal": 0,
|
|
||||||
"type_info": "Uuid"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "device_id",
|
|
||||||
"ordinal": 1,
|
|
||||||
"type_info": "Text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "user_id",
|
|
||||||
"ordinal": 2,
|
|
||||||
"type_info": "Uuid"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "created_at",
|
|
||||||
"ordinal": 3,
|
|
||||||
"type_info": "Timestamptz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "finished_at",
|
|
||||||
"ordinal": 4,
|
|
||||||
"type_info": "Timestamptz"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nullable": [
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Left": [
|
|
||||||
"Uuid"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"query": "\n SELECT compat_session_id\n , device_id\n , user_id\n , created_at\n , finished_at\n FROM compat_sessions\n WHERE compat_session_id = $1\n "
|
|
||||||
},
|
|
||||||
"f5edcd4c306ca8179cdf9d4aab59fbba971b54611c91345849920954dd8089b3": {
|
"f5edcd4c306ca8179cdf9d4aab59fbba971b54611c91345849920954dd8089b3": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
|
@ -62,7 +62,7 @@ mod tests {
|
|||||||
let device_str = device.as_str().to_owned();
|
let device_str = device.as_str().to_owned();
|
||||||
let session = repo
|
let session = repo
|
||||||
.compat_session()
|
.compat_session()
|
||||||
.add(&mut rng, &clock, &user, device)
|
.add(&mut rng, &clock, &user, device, false)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(session.user_id, user.id);
|
assert_eq!(session.user_id, user.id);
|
||||||
@ -118,7 +118,7 @@ mod tests {
|
|||||||
let device = Device::generate(&mut rng);
|
let device = Device::generate(&mut rng);
|
||||||
let session = repo
|
let session = repo
|
||||||
.compat_session()
|
.compat_session()
|
||||||
.add(&mut rng, &clock, &user, device)
|
.add(&mut rng, &clock, &user, device, false)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ mod tests {
|
|||||||
let device = Device::generate(&mut rng);
|
let device = Device::generate(&mut rng);
|
||||||
let session = repo
|
let session = repo
|
||||||
.compat_session()
|
.compat_session()
|
||||||
.add(&mut rng, &clock, &user, device)
|
.add(&mut rng, &clock, &user, device, false)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -391,7 +391,7 @@ mod tests {
|
|||||||
let device = Device::generate(&mut rng);
|
let device = Device::generate(&mut rng);
|
||||||
let session = repo
|
let session = repo
|
||||||
.compat_session()
|
.compat_session()
|
||||||
.add(&mut rng, &clock, &user, device)
|
.add(&mut rng, &clock, &user, device, false)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ struct CompatSessionLookup {
|
|||||||
user_id: Uuid,
|
user_id: Uuid,
|
||||||
created_at: DateTime<Utc>,
|
created_at: DateTime<Utc>,
|
||||||
finished_at: Option<DateTime<Utc>>,
|
finished_at: Option<DateTime<Utc>>,
|
||||||
|
is_synapse_admin: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<CompatSessionLookup> for CompatSession {
|
impl TryFrom<CompatSessionLookup> for CompatSession {
|
||||||
@ -67,6 +68,7 @@ impl TryFrom<CompatSessionLookup> for CompatSession {
|
|||||||
user_id: value.user_id.into(),
|
user_id: value.user_id.into(),
|
||||||
device,
|
device,
|
||||||
created_at: value.created_at,
|
created_at: value.created_at,
|
||||||
|
is_synapse_admin: value.is_synapse_admin,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(session)
|
Ok(session)
|
||||||
@ -95,6 +97,7 @@ impl<'c> CompatSessionRepository for PgCompatSessionRepository<'c> {
|
|||||||
, user_id
|
, user_id
|
||||||
, created_at
|
, created_at
|
||||||
, finished_at
|
, finished_at
|
||||||
|
, is_synapse_admin
|
||||||
FROM compat_sessions
|
FROM compat_sessions
|
||||||
WHERE compat_session_id = $1
|
WHERE compat_session_id = $1
|
||||||
"#,
|
"#,
|
||||||
@ -128,6 +131,7 @@ impl<'c> CompatSessionRepository for PgCompatSessionRepository<'c> {
|
|||||||
clock: &dyn Clock,
|
clock: &dyn Clock,
|
||||||
user: &User,
|
user: &User,
|
||||||
device: Device,
|
device: Device,
|
||||||
|
is_synapse_admin: bool,
|
||||||
) -> Result<CompatSession, Self::Error> {
|
) -> Result<CompatSession, Self::Error> {
|
||||||
let created_at = clock.now();
|
let created_at = clock.now();
|
||||||
let id = Ulid::from_datetime_with_source(created_at.into(), rng);
|
let id = Ulid::from_datetime_with_source(created_at.into(), rng);
|
||||||
@ -135,13 +139,14 @@ impl<'c> CompatSessionRepository for PgCompatSessionRepository<'c> {
|
|||||||
|
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
INSERT INTO compat_sessions (compat_session_id, user_id, device_id, created_at)
|
INSERT INTO compat_sessions (compat_session_id, user_id, device_id, created_at, is_synapse_admin)
|
||||||
VALUES ($1, $2, $3, $4)
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
"#,
|
"#,
|
||||||
Uuid::from(id),
|
Uuid::from(id),
|
||||||
Uuid::from(user.id),
|
Uuid::from(user.id),
|
||||||
device.as_str(),
|
device.as_str(),
|
||||||
created_at,
|
created_at,
|
||||||
|
is_synapse_admin,
|
||||||
)
|
)
|
||||||
.traced()
|
.traced()
|
||||||
.execute(&mut *self.conn)
|
.execute(&mut *self.conn)
|
||||||
@ -153,6 +158,7 @@ impl<'c> CompatSessionRepository for PgCompatSessionRepository<'c> {
|
|||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
device,
|
device,
|
||||||
created_at,
|
created_at,
|
||||||
|
is_synapse_admin,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ pub trait CompatSessionRepository: Send + Sync {
|
|||||||
/// * `clock`: The clock used to generate timestamps
|
/// * `clock`: The clock used to generate timestamps
|
||||||
/// * `user`: The user to create the compat session for
|
/// * `user`: The user to create the compat session for
|
||||||
/// * `device`: The device ID of this session
|
/// * `device`: The device ID of this session
|
||||||
|
/// * `is_synapse_admin`: Whether the session is a synapse admin session
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
@ -59,6 +60,7 @@ pub trait CompatSessionRepository: Send + Sync {
|
|||||||
clock: &dyn Clock,
|
clock: &dyn Clock,
|
||||||
user: &User,
|
user: &User,
|
||||||
device: Device,
|
device: Device,
|
||||||
|
is_synapse_admin: bool,
|
||||||
) -> Result<CompatSession, Self::Error>;
|
) -> Result<CompatSession, Self::Error>;
|
||||||
|
|
||||||
/// End a compat session
|
/// End a compat session
|
||||||
@ -89,6 +91,7 @@ repository_impl!(CompatSessionRepository:
|
|||||||
clock: &dyn Clock,
|
clock: &dyn Clock,
|
||||||
user: &User,
|
user: &User,
|
||||||
device: Device,
|
device: Device,
|
||||||
|
is_synapse_admin: bool,
|
||||||
) -> Result<CompatSession, Self::Error>;
|
) -> Result<CompatSession, Self::Error>;
|
||||||
|
|
||||||
async fn finish(
|
async fn finish(
|
||||||
|
Reference in New Issue
Block a user