feat(webapi): include member_permission in RoomMetadata

This is currently only included by `room_list` endpoint with
authentication.
This commit is contained in:
oxalica 2024-09-10 09:33:59 -04:00
parent 5eeb12c294
commit 4f48b390f7
3 changed files with 23 additions and 7 deletions

View file

@ -329,6 +329,8 @@ pub struct RoomMetadata {
/// This may or may not be a precise number. /// This may or may not be a precise number.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub unseen_cnt: Option<u64>, pub unseen_cnt: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub member_permission: Option<MemberPermission>,
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]

View file

@ -212,6 +212,7 @@ async fn room_list(
let last_seen_cid = let last_seen_cid =
Some(row.get::<_, Id>("last_seen_cid")?).filter(|cid| cid.0 != 0); Some(row.get::<_, Id>("last_seen_cid")?).filter(|cid| cid.0 != 0);
let unseen_cnt = row.get("unseen_cnt").ok(); let unseen_cnt = row.get("unseen_cnt").ok();
let member_permission = row.get("member_perm").ok();
Ok(RoomMetadata { Ok(RoomMetadata {
rid, rid,
title, title,
@ -219,6 +220,7 @@ async fn room_list(
last_item, last_item,
last_seen_cid, last_seen_cid,
unseen_cnt, unseen_cnt,
member_permission,
}) })
})? })?
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
@ -252,7 +254,7 @@ async fn room_list(
query( query(
r" r"
SELECT SELECT
`rid`, `title`, `attrs`, `last_seen_cid`, `rid`, `title`, `attrs`, `last_seen_cid`, `room_member`.`permission` AS `member_perm`,
`cid`, `last_author`.`userkey`, `timestamp`, `nonce`, `sig`, `rich_text` `cid`, `last_author`.`userkey`, `timestamp`, `nonce`, `sig`, `rich_text`
FROM `user` FROM `user`
JOIN `room_member` USING (`uid`) JOIN `room_member` USING (`uid`)
@ -277,7 +279,7 @@ async fn room_list(
query( query(
r" r"
SELECT SELECT
`rid`, `title`, `attrs`, `last_seen_cid`, `rid`, `title`, `attrs`, `last_seen_cid`, `room_member`.`permission` AS `member_perm`,
`cid`, `last_author`.`userkey`, `timestamp`, `nonce`, `sig`, `rich_text`, `cid`, `last_author`.`userkey`, `timestamp`, `nonce`, `sig`, `rich_text`,
(SELECT COUNT(*) (SELECT COUNT(*)
FROM `room_item` AS `unseen_item` FROM `room_item` AS `unseen_item`
@ -456,6 +458,7 @@ async fn room_get_metadata(
last_item: None, last_item: None,
last_seen_cid: None, last_seen_cid: None,
unseen_cnt: None, unseen_cnt: None,
member_permission: None,
})) }))
} }

View file

@ -265,6 +265,7 @@ async fn room_create_get(server: Server, ref mut rng: impl RngCore, #[case] publ
last_item: None, last_item: None,
last_seen_cid: None, last_seen_cid: None,
unseen_cnt: None, unseen_cnt: None,
member_permission: None,
}; };
// Alice has permission. // Alice has permission.
@ -300,8 +301,15 @@ async fn room_create_get(server: Server, ref mut rng: impl RngCore, #[case] publ
} }
// The room appears in public list only when it is public. // The room appears in public list only when it is public.
let expect_list = |has: bool| RoomList { let expect_list = |has: bool, perm: Option<MemberPermission>| RoomList {
rooms: has.then(|| room_meta.clone()).into_iter().collect(), rooms: if has {
vec![RoomMetadata {
member_permission: perm,
..room_meta.clone()
}]
} else {
Vec::new()
},
skip_token: None, skip_token: None,
}; };
assert_eq!( assert_eq!(
@ -309,7 +317,7 @@ async fn room_create_get(server: Server, ref mut rng: impl RngCore, #[case] publ
.get::<RoomList>("/room?filter=public", None) .get::<RoomList>("/room?filter=public", None)
.await .await
.unwrap(), .unwrap(),
expect_list(public), expect_list(public, None),
); );
// Joined rooms endpoint always require authentication. // Joined rooms endpoint always require authentication.
@ -321,13 +329,13 @@ async fn room_create_get(server: Server, ref mut rng: impl RngCore, #[case] publ
.get::<RoomList>("/room?filter=joined", Some(&auth(&ALICE_PRIV, rng))) .get::<RoomList>("/room?filter=joined", Some(&auth(&ALICE_PRIV, rng)))
.await .await
.unwrap(); .unwrap();
assert_eq!(got_joined, expect_list(true)); assert_eq!(got_joined, expect_list(true, Some(MemberPermission::ALL)));
let got_joined = server let got_joined = server
.get::<RoomList>("/room?filter=joined", Some(&auth(&BOB_PRIV, rng))) .get::<RoomList>("/room?filter=joined", Some(&auth(&BOB_PRIV, rng)))
.await .await
.unwrap(); .unwrap();
assert_eq!(got_joined, expect_list(false)); assert_eq!(got_joined, expect_list(false, None));
} }
#[rstest] #[rstest]
@ -551,6 +559,7 @@ async fn room_item_post_read(server: Server, ref mut rng: impl RngCore) {
async fn last_seen_item(server: Server, ref mut rng: impl RngCore) { async fn last_seen_item(server: Server, ref mut rng: impl RngCore) {
let title = "public room"; let title = "public room";
let attrs = RoomAttrs::PUBLIC_READABLE | RoomAttrs::PUBLIC_JOINABLE; let attrs = RoomAttrs::PUBLIC_READABLE | RoomAttrs::PUBLIC_JOINABLE;
let member_perm = MemberPermission::ALL;
let rid = server.create_room(&ALICE_PRIV, attrs, title).await.unwrap(); let rid = server.create_room(&ALICE_PRIV, attrs, title).await.unwrap();
server server
.join_room(rid, &BOB_PRIV, MemberPermission::MAX_SELF_ADD) .join_room(rid, &BOB_PRIV, MemberPermission::MAX_SELF_ADD)
@ -575,6 +584,7 @@ async fn last_seen_item(server: Server, ref mut rng: impl RngCore) {
last_item: Some(alice_chat2.clone()), last_item: Some(alice_chat2.clone()),
last_seen_cid: None, last_seen_cid: None,
unseen_cnt: Some(2), unseen_cnt: Some(2),
member_permission: Some(member_perm),
}], }],
skip_token: None, skip_token: None,
} }
@ -607,6 +617,7 @@ async fn last_seen_item(server: Server, ref mut rng: impl RngCore) {
last_item: Some(alice_chat2.clone()), last_item: Some(alice_chat2.clone()),
last_seen_cid: Some(alice_chat1.cid), last_seen_cid: Some(alice_chat1.cid),
unseen_cnt: Some(1), unseen_cnt: Some(1),
member_permission: Some(member_perm),
}], }],
skip_token: None, skip_token: None,
} }