Skip to content

Commit

Permalink
feat: introduce CommunityAdminSettings in CommunityDescription
Browse files Browse the repository at this point in the history
This allows to store community admin settings that are meant to be propagated
to community members (as opposed to the already existing
CommunitySettings which are considered local to every account).

The first setting introduced as part of this commit is one that enables
community admins to configure whether or not members of the community
are allowed to pin messages in community channels.

Prior to this commit, this was not restricted at all on the protocol
level and only enforced by clients via UI (e.g. members don't see an
option to pin messages, although they could).

This config setting now ensures that:

If turned off, members cannot send a pin message
If turned off, pin messages from members are not handled/processed

This is needed by status-im/status-desktop#5662
  • Loading branch information
0x-r4bbit committed May 13, 2022
1 parent 997708b commit 3336b4a
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 121 deletions.
88 changes: 58 additions & 30 deletions protocol/communities/community.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func New(config Config) (*Community, error) {
return community, nil
}

type CommunityAdminSettings struct {
PinMessageAllMembersEnabled bool `json:"pinMessageAllMembersEnabled"`
}

type CommunityChat struct {
ID string `json:"id"`
Name string `json:"name"`
Expand All @@ -84,17 +88,18 @@ func (o *Community) MarshalPublicAPIJSON() ([]byte, error) {
return nil, errors.New("member identity not set")
}
communityItem := struct {
ID types.HexBytes `json:"id"`
Verified bool `json:"verified"`
Chats map[string]CommunityChat `json:"chats"`
Categories map[string]CommunityCategory `json:"categories"`
Name string `json:"name"`
Description string `json:"description"`
Images map[string]images.IdentityImage `json:"images"`
Color string `json:"color"`
MembersCount int `json:"membersCount"`
EnsName string `json:"ensName"`
Link string `json:"link"`
ID types.HexBytes `json:"id"`
Verified bool `json:"verified"`
Chats map[string]CommunityChat `json:"chats"`
Categories map[string]CommunityCategory `json:"categories"`
Name string `json:"name"`
Description string `json:"description"`
Images map[string]images.IdentityImage `json:"images"`
Color string `json:"color"`
MembersCount int `json:"membersCount"`
EnsName string `json:"ensName"`
Link string `json:"link"`
CommunityAdminSettings CommunityAdminSettings `json:"adminSettings"`
}{
ID: o.ID(),
Verified: o.config.Verified,
Expand Down Expand Up @@ -144,6 +149,13 @@ func (o *Community) MarshalPublicAPIJSON() ([]byte, error) {
}
}

communityItem.CommunityAdminSettings = CommunityAdminSettings{
PinMessageAllMembersEnabled: false,
}

if o.config.CommunityDescription.AdminSettings != nil {
communityItem.CommunityAdminSettings.PinMessageAllMembersEnabled = o.config.CommunityDescription.AdminSettings.PinMessageAllMembersEnabled
}
}
return json.Marshal(communityItem)
}
Expand All @@ -153,25 +165,26 @@ func (o *Community) MarshalJSON() ([]byte, error) {
return nil, errors.New("member identity not set")
}
communityItem := struct {
ID types.HexBytes `json:"id"`
Admin bool `json:"admin"`
Verified bool `json:"verified"`
Joined bool `json:"joined"`
RequestedAccessAt int `json:"requestedAccessAt"`
Name string `json:"name"`
Description string `json:"description"`
Chats map[string]CommunityChat `json:"chats"`
Categories map[string]CommunityCategory `json:"categories"`
Images map[string]images.IdentityImage `json:"images"`
Permissions *protobuf.CommunityPermissions `json:"permissions"`
Members map[string]*protobuf.CommunityMember `json:"members"`
CanRequestAccess bool `json:"canRequestAccess"`
CanManageUsers bool `json:"canManageUsers"`
CanJoin bool `json:"canJoin"`
Color string `json:"color"`
RequestedToJoinAt uint64 `json:"requestedToJoinAt,omitempty"`
IsMember bool `json:"isMember"`
Muted bool `json:"muted"`
ID types.HexBytes `json:"id"`
Admin bool `json:"admin"`
Verified bool `json:"verified"`
Joined bool `json:"joined"`
RequestedAccessAt int `json:"requestedAccessAt"`
Name string `json:"name"`
Description string `json:"description"`
Chats map[string]CommunityChat `json:"chats"`
Categories map[string]CommunityCategory `json:"categories"`
Images map[string]images.IdentityImage `json:"images"`
Permissions *protobuf.CommunityPermissions `json:"permissions"`
Members map[string]*protobuf.CommunityMember `json:"members"`
CanRequestAccess bool `json:"canRequestAccess"`
CanManageUsers bool `json:"canManageUsers"`
CanJoin bool `json:"canJoin"`
Color string `json:"color"`
RequestedToJoinAt uint64 `json:"requestedToJoinAt,omitempty"`
IsMember bool `json:"isMember"`
Muted bool `json:"muted"`
CommunityAdminSettings CommunityAdminSettings `json:"adminSettings"`
}{
ID: o.ID(),
Admin: o.IsAdmin(),
Expand Down Expand Up @@ -229,6 +242,13 @@ func (o *Community) MarshalJSON() ([]byte, error) {
}
}

communityItem.CommunityAdminSettings = CommunityAdminSettings{
PinMessageAllMembersEnabled: false,
}

if o.config.CommunityDescription.AdminSettings != nil {
communityItem.CommunityAdminSettings.PinMessageAllMembersEnabled = o.config.CommunityDescription.AdminSettings.PinMessageAllMembersEnabled
}
}
return json.Marshal(communityItem)
}
Expand Down Expand Up @@ -664,6 +684,10 @@ func (o *Community) Edit(description *protobuf.CommunityDescription) {
o.config.CommunityDescription.Identity.Color = description.Identity.Color
o.config.CommunityDescription.Identity.Emoji = description.Identity.Emoji
o.config.CommunityDescription.Identity.Images = description.Identity.Images
if o.config.CommunityDescription.AdminSettings == nil {
o.config.CommunityDescription.AdminSettings = &protobuf.CommunityAdminSettings{}
}
o.config.CommunityDescription.AdminSettings.PinMessageAllMembersEnabled = description.AdminSettings.PinMessageAllMembersEnabled
o.increaseClock()
}

Expand Down Expand Up @@ -1297,6 +1321,10 @@ func (o *Community) ChatIDs() (chatIDs []string) {
return chatIDs
}

func (o *Community) AllowsAllMembersToPinMessage() bool {
return o.config.CommunityDescription.AdminSettings != nil && o.config.CommunityDescription.AdminSettings.PinMessageAllMembersEnabled
}

func emptyCommunityChanges() *CommunityChanges {
return &CommunityChanges{
MembersAdded: make(map[string]*protobuf.CommunityMember),
Expand Down
14 changes: 13 additions & 1 deletion protocol/messenger_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1369,17 +1369,29 @@ func (m *Messenger) matchChatEntity(chatEntity common.ChatEntity) (*Chat, error)
}

var emojiReaction bool
var pinMessage bool
// We allow emoji reactions from anyone
switch chatEntity.(type) {
case *EmojiReaction:
emojiReaction = true
case *common.PinMessage:
pinMessage = true
}

canPost, err := m.communitiesManager.CanPost(chatEntity.GetSigPubKey(), chat.CommunityID, chat.CommunityChatID(), chatEntity.GetGrant())
if err != nil {
return nil, err
}
if !emojiReaction && !canPost {

community, err := m.communitiesManager.GetByIDString(chat.CommunityID)
if err != nil {
return nil, err
}

isMemberAdmin := community.IsMemberAdmin(chatEntity.GetSigPubKey())
pinMessageAllowed := community.AllowsAllMembersToPinMessage()

if (pinMessage && !isMemberAdmin && !pinMessageAllowed) || (!emojiReaction && !canPost) {
return nil, errors.New("user can't post")
}

Expand Down
13 changes: 13 additions & 0 deletions protocol/messenger_pin_messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ func (m *Messenger) sendPinMessage(ctx context.Context, message *common.PinMessa
return nil, errors.New("chat not found")
}

if chat.CommunityChat() {
community, err := m.communitiesManager.GetByIDString(chat.CommunityID)
if err != nil {
return nil, err
}
isMemberAdmin := community.IsMemberAdmin(&m.identity.PublicKey)
pinMessageAllowed := community.AllowsAllMembersToPinMessage()

if !pinMessageAllowed && !isMemberAdmin {
return nil, errors.New("member can't pin message")
}
}

err := m.handleStandaloneChatIdentity(chat)
if err != nil {
return nil, err
Expand Down
Loading

0 comments on commit 3336b4a

Please sign in to comment.