mirror of
https://github.com/Blah-IM/blahrs.git
synced 2025-05-01 08:41:09 +00:00
remove(types)!: remove members
from CreateGroup
Now a group can only be created with the creator as the only initial member. This forbids group creator from adding other members without their consent. Additional members can join the group later at their own will.
This commit is contained in:
parent
93d779b615
commit
985ea1d68a
5 changed files with 27 additions and 75 deletions
|
@ -353,9 +353,6 @@ pub enum CreateRoomPayload {
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct CreateGroup {
|
pub struct CreateGroup {
|
||||||
pub attrs: RoomAttrs,
|
pub attrs: RoomAttrs,
|
||||||
/// The initial member list. Besides invariants of `RoomMemberList`, this also must include the
|
|
||||||
/// room creator themselves, with the highest permission (-1).
|
|
||||||
pub members: RoomMemberList,
|
|
||||||
pub title: String,
|
pub title: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ use std::{fs, io};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use blah_types::{
|
use blah_types::{
|
||||||
bitflags, get_timestamp, ChatPayload, CreateGroup, CreateRoomPayload, Id, MemberPermission,
|
bitflags, get_timestamp, ChatPayload, CreateGroup, CreateRoomPayload, Id, RichText, RoomAttrs,
|
||||||
RichText, RoomAttrs, RoomMember, RoomMemberList, ServerPermission, Signed, UserKey,
|
ServerPermission, Signed, UserKey,
|
||||||
};
|
};
|
||||||
use ed25519_dalek::pkcs8::spki::der::pem::LineEnding;
|
use ed25519_dalek::pkcs8::spki::der::pem::LineEnding;
|
||||||
use ed25519_dalek::pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey};
|
use ed25519_dalek::pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey};
|
||||||
|
@ -220,12 +220,6 @@ async fn main_api(api_url: Url, command: ApiCommand) -> Result<()> {
|
||||||
let payload = CreateRoomPayload::Group(CreateGroup {
|
let payload = CreateRoomPayload::Group(CreateGroup {
|
||||||
attrs: attrs.unwrap_or_default(),
|
attrs: attrs.unwrap_or_default(),
|
||||||
title,
|
title,
|
||||||
// The CLI does not support passing multiple members because `User` itself is a
|
|
||||||
// disjoint arg-group.
|
|
||||||
members: RoomMemberList(vec![RoomMember {
|
|
||||||
permission: MemberPermission::ALL,
|
|
||||||
user: UserKey(key.verifying_key().to_bytes()),
|
|
||||||
}]),
|
|
||||||
});
|
});
|
||||||
let payload = Signed::sign(&key, get_timestamp(), &mut OsRng, payload)?;
|
let payload = Signed::sign(&key, get_timestamp(), &mut OsRng, payload)?;
|
||||||
|
|
||||||
|
|
|
@ -363,44 +363,34 @@ async fn room_create_group(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let members = &op.members.0;
|
let conn = st.db.get();
|
||||||
if !members
|
let (uid, _perm) = conn
|
||||||
.iter()
|
|
||||||
.any(|m| m.user == user && m.permission == MemberPermission::ALL)
|
|
||||||
{
|
|
||||||
return Err(error_response!(
|
|
||||||
StatusCode::BAD_REQUEST,
|
|
||||||
"deserialization",
|
|
||||||
"invalid initial members",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut conn = st.db.get();
|
|
||||||
let Some(true) = conn
|
|
||||||
.query_row(
|
.query_row(
|
||||||
r"
|
r"
|
||||||
SELECT `permission`
|
SELECT `uid`, `permission`
|
||||||
FROM `user`
|
FROM `user`
|
||||||
WHERE `userkey` = ?
|
WHERE `userkey` = ?
|
||||||
",
|
",
|
||||||
params![user],
|
params![user],
|
||||||
|row| {
|
|row| {
|
||||||
let perm = row.get::<_, ServerPermission>("permission")?;
|
Ok((
|
||||||
Ok(perm.contains(ServerPermission::CREATE_ROOM))
|
row.get::<_, i64>("uid")?,
|
||||||
|
row.get::<_, ServerPermission>("permission")?,
|
||||||
|
))
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.optional()?
|
.optional()?
|
||||||
else {
|
.filter(|(_, perm)| perm.contains(ServerPermission::CREATE_ROOM))
|
||||||
return Err(error_response!(
|
.ok_or_else(|| {
|
||||||
StatusCode::FORBIDDEN,
|
error_response!(
|
||||||
"permission_denied",
|
StatusCode::FORBIDDEN,
|
||||||
"user does not have permission to create room",
|
"permission_denied",
|
||||||
));
|
"the user does not exist or does not have permission to create room",
|
||||||
};
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let txn = conn.transaction()?;
|
|
||||||
let rid = Id::gen();
|
let rid = Id::gen();
|
||||||
txn.execute(
|
conn.execute(
|
||||||
r"
|
r"
|
||||||
INSERT INTO `room` (`rid`, `title`, `attrs`)
|
INSERT INTO `room` (`rid`, `title`, `attrs`)
|
||||||
VALUES (:rid, :title, :attrs)
|
VALUES (:rid, :title, :attrs)
|
||||||
|
@ -411,32 +401,17 @@ async fn room_create_group(
|
||||||
":attrs": op.attrs,
|
":attrs": op.attrs,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
let mut insert_user = txn.prepare(
|
conn.execute(
|
||||||
r"
|
|
||||||
INSERT INTO `user` (`userkey`)
|
|
||||||
VALUES (?)
|
|
||||||
ON CONFLICT (`userkey`) DO NOTHING
|
|
||||||
",
|
|
||||||
)?;
|
|
||||||
let mut insert_member = txn.prepare(
|
|
||||||
r"
|
r"
|
||||||
INSERT INTO `room_member` (`rid`, `uid`, `permission`)
|
INSERT INTO `room_member` (`rid`, `uid`, `permission`)
|
||||||
SELECT :rid, `uid`, :permission
|
VALUES (:rid, :uid, :perm)
|
||||||
FROM `user`
|
|
||||||
WHERE `userkey` = :userkey
|
|
||||||
",
|
",
|
||||||
)?;
|
named_params! {
|
||||||
for member in members {
|
|
||||||
insert_user.execute(params![member.user])?;
|
|
||||||
insert_member.execute(named_params! {
|
|
||||||
":rid": rid,
|
":rid": rid,
|
||||||
":userkey": member.user,
|
":uid": uid,
|
||||||
":permission": member.permission,
|
":perm": MemberPermission::ALL,
|
||||||
})?;
|
},
|
||||||
}
|
)?;
|
||||||
drop(insert_member);
|
|
||||||
drop(insert_user);
|
|
||||||
txn.commit()?;
|
|
||||||
|
|
||||||
Ok(Json(rid))
|
Ok(Json(rid))
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ use std::sync::{Arc, LazyLock};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use blah_types::{
|
use blah_types::{
|
||||||
get_timestamp, AuthPayload, ChatPayload, CreateGroup, CreatePeerChat, CreateRoomPayload, Id,
|
get_timestamp, AuthPayload, ChatPayload, CreateGroup, CreatePeerChat, CreateRoomPayload, Id,
|
||||||
MemberPermission, RichText, RoomAdminOp, RoomAdminPayload, RoomAttrs, RoomMember,
|
MemberPermission, RichText, RoomAdminOp, RoomAdminPayload, RoomAttrs, RoomMetadata,
|
||||||
RoomMemberList, RoomMetadata, ServerPermission, Signed, SignedChatMsg, UserKey, WithMsgId,
|
ServerPermission, Signed, SignedChatMsg, UserKey, WithMsgId,
|
||||||
};
|
};
|
||||||
use blahd::{ApiError, AppState, Database, RoomList, RoomMsgs};
|
use blahd::{ApiError, AppState, Database, RoomList, RoomMsgs};
|
||||||
use ed25519_dalek::SigningKey;
|
use ed25519_dalek::SigningKey;
|
||||||
|
@ -120,10 +120,6 @@ impl Server {
|
||||||
&mut *self.rng.borrow_mut(),
|
&mut *self.rng.borrow_mut(),
|
||||||
CreateRoomPayload::Group(CreateGroup {
|
CreateRoomPayload::Group(CreateGroup {
|
||||||
attrs,
|
attrs,
|
||||||
members: RoomMemberList(vec![RoomMember {
|
|
||||||
permission: MemberPermission::ALL,
|
|
||||||
user: UserKey(key.verifying_key().to_bytes()),
|
|
||||||
}]),
|
|
||||||
title: title.to_string(),
|
title: title.to_string(),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
|
@ -612,16 +612,6 @@ components:
|
||||||
const: 'create_room'
|
const: 'create_room'
|
||||||
title:
|
title:
|
||||||
type: string
|
type: string
|
||||||
members:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
user:
|
|
||||||
type: string
|
|
||||||
permission:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
- type: object
|
- type: object
|
||||||
properties:
|
properties:
|
||||||
typ:
|
typ:
|
||||||
|
|
Loading…
Add table
Reference in a new issue