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

Add a GraphQL mutation to allow cross-signing reset

This commit is contained in:
Quentin Gliech
2023-11-22 18:25:47 +01:00
parent 5957112ff6
commit f8d745d308
4 changed files with 147 additions and 0 deletions

View File

@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use anyhow::Context as _;
use async_graphql::{Context, Description, Enum, InputObject, Object, ID}; use async_graphql::{Context, Description, Enum, InputObject, Object, ID};
use mas_storage::{ use mas_storage::{
job::{DeactivateUserJob, JobRepositoryExt, ProvisionUserJob}, job::{DeactivateUserJob, JobRepositoryExt, ProvisionUserJob},
@@ -22,6 +23,7 @@ use tracing::info;
use crate::{ use crate::{
model::{NodeType, User}, model::{NodeType, User},
state::ContextExt, state::ContextExt,
UserId,
}; };
#[derive(Default)] #[derive(Default)]
@@ -157,6 +159,34 @@ impl SetCanRequestAdminPayload {
} }
} }
/// The input for the `allowUserCrossSigningReset` mutation.
#[derive(InputObject)]
struct AllowUserCrossSigningResetInput {
/// The ID of the user to update.
user_id: ID,
}
/// The payload for the `allowUserCrossSigningReset` mutation.
#[derive(Description)]
enum AllowUserCrossSigningResetPayload {
/// The user was updated.
Allowed(mas_data_model::User),
/// The user was not found.
NotFound,
}
#[Object(use_type_description)]
impl AllowUserCrossSigningResetPayload {
/// The user that was updated.
async fn user(&self) -> Option<User> {
match self {
Self::Allowed(user) => Some(User(user.clone())),
Self::NotFound => None,
}
}
}
fn valid_username_character(c: char) -> bool { fn valid_username_character(c: char) -> bool {
c.is_ascii_lowercase() c.is_ascii_lowercase()
|| c.is_ascii_digit() || c.is_ascii_digit()
@@ -296,4 +326,36 @@ impl UserMutations {
Ok(SetCanRequestAdminPayload::Updated(user)) Ok(SetCanRequestAdminPayload::Updated(user))
} }
/// Temporarily allow user to reset their cross-signing keys.
async fn allow_user_cross_signing_reset(
&self,
ctx: &Context<'_>,
input: AllowUserCrossSigningResetInput,
) -> Result<AllowUserCrossSigningResetPayload, async_graphql::Error> {
let state = ctx.state();
let user_id = NodeType::User.extract_ulid(&input.user_id)?;
let requester = ctx.requester();
if !requester.is_owner_or_admin(&UserId(user_id)) {
return Err(async_graphql::Error::new("Unauthorized"));
}
let mut repo = state.repository().await?;
let user = repo.user().lookup(user_id).await?;
repo.cancel().await?;
let Some(user) = user else {
return Ok(AllowUserCrossSigningResetPayload::NotFound);
};
let conn = state.homeserver_connection();
let mxid = conn.mxid(&user.username);
conn.allow_cross_signing_reset(&mxid)
.await
.context("Failed to allow cross-signing reset")?;
Ok(AllowUserCrossSigningResetPayload::Allowed(user))
}
} }

View File

@@ -106,6 +106,26 @@ enum AddUserStatus {
INVALID INVALID
} }
"""
The input for the `allowUserCrossSigningReset` mutation.
"""
input AllowUserCrossSigningResetInput {
"""
The ID of the user to update.
"""
userId: ID!
}
"""
The payload for the `allowUserCrossSigningReset` mutation.
"""
type AllowUserCrossSigningResetPayload {
"""
The user that was updated.
"""
user: User
}
type Anonymous implements Node { type Anonymous implements Node {
id: ID! id: ID!
} }
@@ -650,6 +670,12 @@ type Mutation {
input: SetCanRequestAdminInput! input: SetCanRequestAdminInput!
): SetCanRequestAdminPayload! ): SetCanRequestAdminPayload!
""" """
Temporarily allow user to reset their cross-signing keys.
"""
allowUserCrossSigningReset(
input: AllowUserCrossSigningResetInput!
): AllowUserCrossSigningResetPayload!
"""
Create a new arbitrary OAuth 2.0 Session. Create a new arbitrary OAuth 2.0 Session.
Only available for administrators. Only available for administrators.

View File

@@ -99,6 +99,19 @@ export enum AddUserStatus {
Invalid = "INVALID", Invalid = "INVALID",
} }
/** The input for the `allowUserCrossSigningReset` mutation. */
export type AllowUserCrossSigningResetInput = {
/** The ID of the user to update. */
userId: Scalars["ID"]["input"];
};
/** The payload for the `allowUserCrossSigningReset` mutation. */
export type AllowUserCrossSigningResetPayload = {
__typename?: "AllowUserCrossSigningResetPayload";
/** The user that was updated. */
user?: Maybe<User>;
};
export type Anonymous = Node & { export type Anonymous = Node & {
__typename?: "Anonymous"; __typename?: "Anonymous";
id: Scalars["ID"]["output"]; id: Scalars["ID"]["output"];
@@ -421,6 +434,8 @@ export type Mutation = {
addEmail: AddEmailPayload; addEmail: AddEmailPayload;
/** Add a user. This is only available to administrators. */ /** Add a user. This is only available to administrators. */
addUser: AddUserPayload; addUser: AddUserPayload;
/** Temporarily allow user to reset their cross-signing keys. */
allowUserCrossSigningReset: AllowUserCrossSigningResetPayload;
/** /**
* Create a new arbitrary OAuth 2.0 Session. * Create a new arbitrary OAuth 2.0 Session.
* *
@@ -459,6 +474,11 @@ export type MutationAddUserArgs = {
input: AddUserInput; input: AddUserInput;
}; };
/** The mutations root of the GraphQL interface. */
export type MutationAllowUserCrossSigningResetArgs = {
input: AllowUserCrossSigningResetInput;
};
/** The mutations root of the GraphQL interface. */ /** The mutations root of the GraphQL interface. */
export type MutationCreateOauth2SessionArgs = { export type MutationCreateOauth2SessionArgs = {
input: CreateOAuth2SessionInput; input: CreateOAuth2SessionInput;

View File

@@ -86,6 +86,22 @@ export default {
], ],
interfaces: [], interfaces: [],
}, },
{
kind: "OBJECT",
name: "AllowUserCrossSigningResetPayload",
fields: [
{
name: "user",
type: {
kind: "OBJECT",
name: "User",
ofType: null,
},
args: [],
},
],
interfaces: [],
},
{ {
kind: "OBJECT", kind: "OBJECT",
name: "Anonymous", name: "Anonymous",
@@ -1100,6 +1116,29 @@ export default {
}, },
], ],
}, },
{
name: "allowUserCrossSigningReset",
type: {
kind: "NON_NULL",
ofType: {
kind: "OBJECT",
name: "AllowUserCrossSigningResetPayload",
ofType: null,
},
},
args: [
{
name: "input",
type: {
kind: "NON_NULL",
ofType: {
kind: "SCALAR",
name: "Any",
},
},
},
],
},
{ {
name: "createOauth2Session", name: "createOauth2Session",
type: { type: {