Skip to content

Commit 1696102

Browse files
committed
graphql: add mutation to update device name
1 parent 9a660b2 commit 1696102

File tree

4 files changed

+336
-0
lines changed

4 files changed

+336
-0
lines changed

crates/handlers/src/graphql/mutations/compat_session.rs

+94
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,54 @@ impl EndCompatSessionPayload {
6464
}
6565
}
6666

67+
/// The input of the `setCompatSessionName` mutation.
68+
#[derive(InputObject)]
69+
pub struct SetCompatSessionNameInput {
70+
/// The ID of the session to set the name of.
71+
compat_session_id: ID,
72+
73+
/// The new name of the session.
74+
human_name: String,
75+
}
76+
77+
/// The payload of the `setCompatSessionName` mutation.
78+
pub enum SetCompatSessionNamePayload {
79+
/// The session was not found.
80+
NotFound,
81+
82+
/// The session was updated.
83+
Updated(mas_data_model::CompatSession),
84+
}
85+
86+
/// The status of the `setCompatSessionName` mutation.
87+
#[derive(Enum, Copy, Clone, PartialEq, Eq, Debug)]
88+
enum SetCompatSessionNameStatus {
89+
/// The session was updated.
90+
Updated,
91+
92+
/// The session was not found.
93+
NotFound,
94+
}
95+
96+
#[Object]
97+
impl SetCompatSessionNamePayload {
98+
/// The status of the mutation.
99+
async fn status(&self) -> SetCompatSessionNameStatus {
100+
match self {
101+
Self::Updated(_) => SetCompatSessionNameStatus::Updated,
102+
Self::NotFound => SetCompatSessionNameStatus::NotFound,
103+
}
104+
}
105+
106+
/// The session that was updated.
107+
async fn oauth2_session(&self) -> Option<CompatSession> {
108+
match self {
109+
Self::Updated(session) => Some(CompatSession::new(session.clone())),
110+
Self::NotFound => None,
111+
}
112+
}
113+
}
114+
67115
#[Object]
68116
impl CompatSessionMutations {
69117
async fn end_compat_session(
@@ -105,4 +153,50 @@ impl CompatSessionMutations {
105153

106154
Ok(EndCompatSessionPayload::Ended(Box::new(session)))
107155
}
156+
157+
async fn set_compat_session_name(
158+
&self,
159+
ctx: &Context<'_>,
160+
input: SetCompatSessionNameInput,
161+
) -> Result<SetCompatSessionNamePayload, async_graphql::Error> {
162+
let state = ctx.state();
163+
let compat_session_id = NodeType::CompatSession.extract_ulid(&input.compat_session_id)?;
164+
let requester = ctx.requester();
165+
166+
let mut repo = state.repository().await?;
167+
let homeserver = state.homeserver_connection();
168+
169+
let session = repo.compat_session().lookup(compat_session_id).await?;
170+
let Some(session) = session else {
171+
return Ok(SetCompatSessionNamePayload::NotFound);
172+
};
173+
174+
if !requester.is_owner_or_admin(&session) {
175+
return Ok(SetCompatSessionNamePayload::NotFound);
176+
}
177+
178+
let user = repo
179+
.user()
180+
.lookup(session.user_id)
181+
.await?
182+
.context("User not found")?;
183+
184+
let session = repo
185+
.compat_session()
186+
.set_human_name(session, Some(input.human_name.clone()))
187+
.await?;
188+
189+
// Update the device on the homeserver side
190+
let mxid = homeserver.mxid(&user.username);
191+
if let Some(device) = session.device.as_ref() {
192+
homeserver
193+
.update_device_display_name(&mxid, device.as_str(), &input.human_name)
194+
.await
195+
.context("Failed to provision device")?;
196+
}
197+
198+
repo.save().await?;
199+
200+
Ok(SetCompatSessionNamePayload::Updated(session))
201+
}
108202
}

crates/handlers/src/graphql/mutations/oauth2_session.rs

+98
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,54 @@ impl EndOAuth2SessionPayload {
110110
}
111111
}
112112

113+
/// The input of the `setOauth2SessionName` mutation.
114+
#[derive(InputObject)]
115+
pub struct SetOAuth2SessionNameInput {
116+
/// The ID of the session to set the name of.
117+
oauth2_session_id: ID,
118+
119+
/// The new name of the session.
120+
human_name: String,
121+
}
122+
123+
/// The payload of the `setOauth2SessionName` mutation.
124+
pub enum SetOAuth2SessionNamePayload {
125+
/// The session was not found.
126+
NotFound,
127+
128+
/// The session was updated.
129+
Updated(mas_data_model::Session),
130+
}
131+
132+
/// The status of the `setOauth2SessionName` mutation.
133+
#[derive(Enum, Copy, Clone, PartialEq, Eq, Debug)]
134+
enum SetOAuth2SessionNameStatus {
135+
/// The session was updated.
136+
Updated,
137+
138+
/// The session was not found.
139+
NotFound,
140+
}
141+
142+
#[Object]
143+
impl SetOAuth2SessionNamePayload {
144+
/// The status of the mutation.
145+
async fn status(&self) -> SetOAuth2SessionNameStatus {
146+
match self {
147+
Self::Updated(_) => SetOAuth2SessionNameStatus::Updated,
148+
Self::NotFound => SetOAuth2SessionNameStatus::NotFound,
149+
}
150+
}
151+
152+
/// The session that was updated.
153+
async fn oauth2_session(&self) -> Option<OAuth2Session> {
154+
match self {
155+
Self::Updated(session) => Some(OAuth2Session(session.clone())),
156+
Self::NotFound => None,
157+
}
158+
}
159+
}
160+
113161
#[Object]
114162
impl OAuth2SessionMutations {
115163
/// Create a new arbitrary OAuth 2.0 Session.
@@ -247,4 +295,54 @@ impl OAuth2SessionMutations {
247295

248296
Ok(EndOAuth2SessionPayload::Ended(session))
249297
}
298+
299+
async fn set_oauth2_session_name(
300+
&self,
301+
ctx: &Context<'_>,
302+
input: SetOAuth2SessionNameInput,
303+
) -> Result<SetOAuth2SessionNamePayload, async_graphql::Error> {
304+
let state = ctx.state();
305+
let oauth2_session_id = NodeType::OAuth2Session.extract_ulid(&input.oauth2_session_id)?;
306+
let requester = ctx.requester();
307+
308+
let mut repo = state.repository().await?;
309+
let homeserver = state.homeserver_connection();
310+
311+
let session = repo.oauth2_session().lookup(oauth2_session_id).await?;
312+
let Some(session) = session else {
313+
return Ok(SetOAuth2SessionNamePayload::NotFound);
314+
};
315+
316+
if !requester.is_owner_or_admin(&session) {
317+
return Ok(SetOAuth2SessionNamePayload::NotFound);
318+
}
319+
320+
let user_id = session.user_id.context("Session has no user")?;
321+
322+
let user = repo
323+
.user()
324+
.lookup(user_id)
325+
.await?
326+
.context("User not found")?;
327+
328+
let session = repo
329+
.oauth2_session()
330+
.set_human_name(session, Some(input.human_name.clone()))
331+
.await?;
332+
333+
// Update the device on the homeserver side
334+
let mxid = homeserver.mxid(&user.username);
335+
for scope in &*session.scope {
336+
if let Some(device) = Device::from_scope_token(scope) {
337+
homeserver
338+
.update_device_display_name(&mxid, device.as_str(), &input.human_name)
339+
.await
340+
.context("Failed to provision device")?;
341+
}
342+
}
343+
344+
repo.save().await?;
345+
346+
Ok(SetOAuth2SessionNamePayload::Updated(session))
347+
}
250348
}

frontend/schema.graphql

+84
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,13 @@ type Mutation {
941941
input: CreateOAuth2SessionInput!
942942
): CreateOAuth2SessionPayload!
943943
endOauth2Session(input: EndOAuth2SessionInput!): EndOAuth2SessionPayload!
944+
setOauth2SessionName(
945+
input: SetOAuth2SessionNameInput!
946+
): SetOAuth2SessionNamePayload!
944947
endCompatSession(input: EndCompatSessionInput!): EndCompatSessionPayload!
948+
setCompatSessionName(
949+
input: SetCompatSessionNameInput!
950+
): SetCompatSessionNamePayload!
945951
endBrowserSession(input: EndBrowserSessionInput!): EndBrowserSessionPayload!
946952
"""
947953
Set the display name of a user
@@ -1434,6 +1440,45 @@ type SetCanRequestAdminPayload {
14341440
user: User
14351441
}
14361442

1443+
"""
1444+
The input of the `setCompatSessionName` mutation.
1445+
"""
1446+
input SetCompatSessionNameInput {
1447+
"""
1448+
The ID of the session to set the name of.
1449+
"""
1450+
compatSessionId: ID!
1451+
"""
1452+
The new name of the session.
1453+
"""
1454+
humanName: String!
1455+
}
1456+
1457+
type SetCompatSessionNamePayload {
1458+
"""
1459+
The status of the mutation.
1460+
"""
1461+
status: SetCompatSessionNameStatus!
1462+
"""
1463+
The session that was updated.
1464+
"""
1465+
oauth2Session: CompatSession
1466+
}
1467+
1468+
"""
1469+
The status of the `setCompatSessionName` mutation.
1470+
"""
1471+
enum SetCompatSessionNameStatus {
1472+
"""
1473+
The session was updated.
1474+
"""
1475+
UPDATED
1476+
"""
1477+
The session was not found.
1478+
"""
1479+
NOT_FOUND
1480+
}
1481+
14371482
"""
14381483
The input for the `addEmail` mutation
14391484
"""
@@ -1476,6 +1521,45 @@ enum SetDisplayNameStatus {
14761521
INVALID
14771522
}
14781523

1524+
"""
1525+
The input of the `setOauth2SessionName` mutation.
1526+
"""
1527+
input SetOAuth2SessionNameInput {
1528+
"""
1529+
The ID of the session to set the name of.
1530+
"""
1531+
oauth2SessionId: ID!
1532+
"""
1533+
The new name of the session.
1534+
"""
1535+
humanName: String!
1536+
}
1537+
1538+
type SetOAuth2SessionNamePayload {
1539+
"""
1540+
The status of the mutation.
1541+
"""
1542+
status: SetOAuth2SessionNameStatus!
1543+
"""
1544+
The session that was updated.
1545+
"""
1546+
oauth2Session: Oauth2Session
1547+
}
1548+
1549+
"""
1550+
The status of the `setOauth2SessionName` mutation.
1551+
"""
1552+
enum SetOAuth2SessionNameStatus {
1553+
"""
1554+
The session was updated.
1555+
"""
1556+
UPDATED
1557+
"""
1558+
The session was not found.
1559+
"""
1560+
NOT_FOUND
1561+
}
1562+
14791563
"""
14801564
The input for the `setPasswordByRecovery` mutation.
14811565
"""

0 commit comments

Comments
 (0)