fix: owner without community private key and token master was not able send all admin events (#3819)
This commit is contained in:
parent
bb942f6c8f
commit
89253ac684
|
@ -813,7 +813,7 @@ func (o *Community) RemoveUserFromOrg(pk *ecdsa.PublicKey) (*protobuf.CommunityD
|
|||
return nil, ErrNotAdmin
|
||||
}
|
||||
|
||||
if allowedToSendEvents && o.IsMemberOwnerOrAdmin(pk) {
|
||||
if !isControlNode && o.IsPrivilegedMember(pk) {
|
||||
return nil, ErrCannotRemoveOwnerOrAdmin
|
||||
}
|
||||
|
||||
|
@ -883,7 +883,7 @@ func (o *Community) BanUserFromCommunity(pk *ecdsa.PublicKey) (*protobuf.Communi
|
|||
return nil, ErrNotAdmin
|
||||
}
|
||||
|
||||
if allowedToSendEvents && o.IsMemberOwnerOrAdmin(pk) {
|
||||
if !isControlNode && o.IsPrivilegedMember(pk) {
|
||||
return nil, ErrCannotBanOwnerOrAdmin
|
||||
}
|
||||
|
||||
|
@ -1151,6 +1151,17 @@ func (o *Community) IsOwnerWithoutCommunityKey() bool {
|
|||
return o.config.PrivateKey == nil && o.IsMemberOwner(o.config.MemberIdentity)
|
||||
}
|
||||
|
||||
func (o *Community) GetPrivilegedMembers() []*ecdsa.PublicKey {
|
||||
privilegedMembers := make([]*ecdsa.PublicKey, 0)
|
||||
members := o.GetMemberPubkeys()
|
||||
for _, member := range members {
|
||||
if o.IsPrivilegedMember(member) {
|
||||
privilegedMembers = append(privilegedMembers, member)
|
||||
}
|
||||
}
|
||||
return privilegedMembers
|
||||
}
|
||||
|
||||
func (o *Community) HasPermissionToSendCommunityEvents() bool {
|
||||
return !o.IsControlNode() && o.hasPermission(o.config.MemberIdentity, manageCommunityRolePermissions())
|
||||
}
|
||||
|
@ -1159,11 +1170,15 @@ func (o *Community) IsMemberOwner(publicKey *ecdsa.PublicKey) bool {
|
|||
return o.hasPermission(publicKey, ownerRolePermission())
|
||||
}
|
||||
|
||||
func (o *Community) IsMemberTokenMaster(publicKey *ecdsa.PublicKey) bool {
|
||||
return o.hasPermission(publicKey, tokenMasterRolePermissions())
|
||||
}
|
||||
|
||||
func (o *Community) IsMemberAdmin(publicKey *ecdsa.PublicKey) bool {
|
||||
return o.hasPermission(publicKey, adminRolePermissions())
|
||||
}
|
||||
|
||||
func (o *Community) IsMemberOwnerOrAdmin(publicKey *ecdsa.PublicKey) bool {
|
||||
func (o *Community) IsPrivilegedMember(publicKey *ecdsa.PublicKey) bool {
|
||||
return o.hasPermission(publicKey, manageCommunityRolePermissions())
|
||||
}
|
||||
|
||||
|
@ -1193,6 +1208,12 @@ func adminRolePermissions() map[protobuf.CommunityMember_Roles]bool {
|
|||
return roles
|
||||
}
|
||||
|
||||
func tokenMasterRolePermissions() map[protobuf.CommunityMember_Roles]bool {
|
||||
roles := make(map[protobuf.CommunityMember_Roles]bool)
|
||||
roles[protobuf.CommunityMember_ROLE_TOKEN_MASTER] = true
|
||||
return roles
|
||||
}
|
||||
|
||||
func (o *Community) MemberRole(pubKey *ecdsa.PublicKey) protobuf.CommunityMember_Roles {
|
||||
if o.IsMemberOwner(pubKey) {
|
||||
return protobuf.CommunityMember_ROLE_OWNER
|
||||
|
@ -1213,17 +1234,6 @@ func canDeleteMessageForEveryonePermissions() map[protobuf.CommunityMember_Roles
|
|||
return roles
|
||||
}
|
||||
|
||||
func (o *Community) GetMemberAdmins() []*ecdsa.PublicKey {
|
||||
admins := make([]*ecdsa.PublicKey, 0)
|
||||
members := o.GetMemberPubkeys()
|
||||
for _, member := range members {
|
||||
if o.IsMemberAdmin(member) {
|
||||
admins = append(admins, member)
|
||||
}
|
||||
}
|
||||
return admins
|
||||
}
|
||||
|
||||
func (o *Community) validateRequestToJoinWithChatID(request *protobuf.CommunityRequestToJoin) error {
|
||||
|
||||
chat, ok := o.config.CommunityDescription.Chats[request.ChatId]
|
||||
|
|
|
@ -341,8 +341,8 @@ func (o *Community) updateCommunityDescriptionByCommunityEvent(communityEvent Co
|
|||
return err
|
||||
}
|
||||
|
||||
if o.IsMemberOwnerOrAdmin(pk) {
|
||||
return errors.New("attempt to kick an owner or admin of the community from the admin side")
|
||||
if !o.IsControlNode() && o.IsPrivilegedMember(pk) {
|
||||
return errors.New("attempt to kick an control node or privileged user from non-control node side")
|
||||
}
|
||||
|
||||
o.removeMemberFromOrg(pk)
|
||||
|
@ -353,8 +353,8 @@ func (o *Community) updateCommunityDescriptionByCommunityEvent(communityEvent Co
|
|||
return err
|
||||
}
|
||||
|
||||
if o.IsMemberOwnerOrAdmin(pk) {
|
||||
return errors.New("attempt to ban an owner or admin of the community from the admin side")
|
||||
if !o.IsControlNode() && o.IsPrivilegedMember(pk) {
|
||||
return errors.New("attempt to ban an control node or privileged user from non-control node side")
|
||||
}
|
||||
o.banUserFromCommunity(pk)
|
||||
|
||||
|
@ -429,6 +429,10 @@ func validateAndGetEventsMessageCommunityDescription(signedDescription []byte, s
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if signer == nil {
|
||||
return nil, errors.New("CommunityDescription does not contain the control node signature")
|
||||
}
|
||||
|
||||
if !signer.Equal(signerPubkey) {
|
||||
return nil, errors.New("CommunityDescription was not signed by an owner")
|
||||
}
|
||||
|
|
|
@ -1327,8 +1327,8 @@ func (m *Manager) HandleCommunityEventsMessage(signer *ecdsa.PublicKey, message
|
|||
return nil, ErrOrgNotFound
|
||||
}
|
||||
|
||||
if !community.IsMemberAdmin(signer) {
|
||||
return nil, errors.New("user is not an admin")
|
||||
if !community.IsPrivilegedMember(signer) {
|
||||
return nil, errors.New("user has not permissions to send events")
|
||||
}
|
||||
|
||||
changes, err := community.UpdateCommunityByEvents(adminMessage)
|
||||
|
@ -2411,13 +2411,13 @@ func (m *Manager) HandleCommunityRequestToJoinResponse(signer *ecdsa.PublicKey,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
isOwnerOrAdminSigner := community.IsMemberOwnerOrAdmin(signer)
|
||||
isPrivilegedUserSigner := community.IsPrivilegedMember(signer)
|
||||
isControlNodeSigner := common.IsPubKeyEqual(community.PublicKey(), signer)
|
||||
if !isControlNodeSigner && !isOwnerOrAdminSigner {
|
||||
if !isControlNodeSigner && !isPrivilegedUserSigner {
|
||||
return nil, ErrNotAuthorized
|
||||
}
|
||||
|
||||
_, err = community.UpdateCommunityDescription(request.Community, appMetadataMsg, isOwnerOrAdminSigner && !isControlNodeSigner)
|
||||
_, err = community.UpdateCommunityDescription(request.Community, appMetadataMsg, isPrivilegedUserSigner && !isControlNodeSigner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -244,7 +244,7 @@ func (s *OwnerWithoutCommunityKeyCommunityEventsSuite) TestOwnerBanOwnerWithoutC
|
|||
testOwnerBanTheSameRole(s, community)
|
||||
}
|
||||
|
||||
func (s *OwnerWithoutCommunityKeyCommunityEventsSuite) TestAdminBanControlNode() {
|
||||
func (s *OwnerWithoutCommunityKeyCommunityEventsSuite) TestOwnerBanControlNode() {
|
||||
community := setUpCommunityAndRoles(s, protobuf.CommunityMember_ROLE_OWNER)
|
||||
testOwnerBanControlNode(s, community)
|
||||
}
|
||||
|
|
|
@ -91,8 +91,8 @@ func setUpCommunityAndRoles(base CommunityEventsTestsInterface, role protobuf.Co
|
|||
|
||||
request := &requests.RequestToJoinCommunity{CommunityID: community.ID()}
|
||||
joinCommunity(suite, community, base.GetControlNode(), base.GetEventSender(), request)
|
||||
refreshMessengerResponses(base)
|
||||
joinCommunity(suite, community, base.GetControlNode(), base.GetMember(), request)
|
||||
|
||||
refreshMessengerResponses(base)
|
||||
|
||||
// grant permissions to the event sender
|
||||
|
@ -344,14 +344,14 @@ func setUpOnRequestCommunityAndRoles(base CommunityEventsTestsInterface, role pr
|
|||
|
||||
// control node creates a community and chat
|
||||
community := createTestCommunity(base, protobuf.CommunityPermissions_ON_REQUEST)
|
||||
refreshMessengerResponses(base)
|
||||
|
||||
advertiseCommunityTo(s, community, base.GetControlNode(), base.GetEventSender())
|
||||
advertiseCommunityTo(s, community, base.GetControlNode(), base.GetMember())
|
||||
|
||||
refreshMessengerResponses(base)
|
||||
|
||||
joinOnRequestCommunity(s, community, base.GetControlNode(), base.GetEventSender())
|
||||
refreshMessengerResponses(base)
|
||||
joinOnRequestCommunity(s, community, base.GetControlNode(), base.GetMember())
|
||||
|
||||
refreshMessengerResponses(base)
|
||||
|
||||
// grant permissions to event sender
|
||||
|
|
|
@ -246,9 +246,20 @@ func joinOnRequestCommunity(s *suite.Suite, community *communities.Community, co
|
|||
"user did not receive request to join response",
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
userCommunity, err := user.GetCommunityByID(community.ID())
|
||||
s.Require().NoError(err)
|
||||
s.Require().True(userCommunity.HasMember(&user.identity.PublicKey))
|
||||
|
||||
// We can't identify which owner is a control node, so owner will receive twice request to join event
|
||||
_, err = WaitOnMessengerResponse(
|
||||
controlNode,
|
||||
func(r *MessengerResponse) bool {
|
||||
return len(r.Communities()) > 0
|
||||
},
|
||||
"user did not receive request to join response",
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func sendChatMessage(s *suite.Suite, sender *Messenger, chatID string, text string) *common.Message {
|
||||
|
@ -270,7 +281,7 @@ func grantPermission(s *suite.Suite, community *communities.Community, controlNo
|
|||
responseAddRole, err := controlNode.AddRoleToMember(&requests.AddRoleToMember{
|
||||
CommunityID: community.ID(),
|
||||
User: common.PubkeyToHexBytes(target.IdentityPublicKey()),
|
||||
Role: protobuf.CommunityMember_ROLE_ADMIN,
|
||||
Role: role,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
|
||||
|
@ -280,14 +291,25 @@ func grantPermission(s *suite.Suite, community *communities.Community, controlNo
|
|||
}
|
||||
rCommunities := response.Communities()
|
||||
s.Require().Len(rCommunities, 1)
|
||||
s.Require().True(rCommunities[0].IsMemberAdmin(target.IdentityPublicKey()))
|
||||
switch role {
|
||||
case protobuf.CommunityMember_ROLE_OWNER:
|
||||
s.Require().True(rCommunities[0].IsMemberOwner(target.IdentityPublicKey()))
|
||||
case protobuf.CommunityMember_ROLE_ADMIN:
|
||||
s.Require().True(rCommunities[0].IsMemberAdmin(target.IdentityPublicKey()))
|
||||
case protobuf.CommunityMember_ROLE_TOKEN_MASTER:
|
||||
s.Require().True(rCommunities[0].IsMemberTokenMaster(target.IdentityPublicKey()))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
checkRole(responseAddRole)
|
||||
s.Require().True(checkRole(responseAddRole))
|
||||
|
||||
_, err = WaitOnMessengerResponse(target, func(response *MessengerResponse) bool {
|
||||
return checkRole(response)
|
||||
response, err := WaitOnMessengerResponse(target, func(response *MessengerResponse) bool {
|
||||
return len(response.Communities()) > 0
|
||||
}, "community description changed message not received")
|
||||
s.Require().NoError(err)
|
||||
s.Require().True(checkRole(response))
|
||||
}
|
||||
|
|
|
@ -935,12 +935,14 @@ func (m *Messenger) RequestToJoinCommunity(request *requests.RequestToJoinCommun
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// send request to join also to community admins
|
||||
communityAdmins := community.GetMemberAdmins()
|
||||
for _, communityAdmin := range communityAdmins {
|
||||
_, err := m.sender.SendPrivate(context.Background(), communityAdmin, &rawMessage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if !community.AcceptRequestToJoinAutomatically() {
|
||||
// send request to join also to community privileged members
|
||||
privilegedMembers := community.GetPrivilegedMembers()
|
||||
for _, privilegedMember := range privilegedMembers {
|
||||
_, err := m.sender.SendPrivate(context.Background(), privilegedMember, &rawMessage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1068,10 +1070,10 @@ func (m *Messenger) EditSharedAddressesForCommunity(request *requests.EditShared
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// send edit message also to community admins
|
||||
communityAdmins := community.GetMemberAdmins()
|
||||
for _, communityAdmin := range communityAdmins {
|
||||
_, err := m.sender.SendPrivate(context.Background(), communityAdmin, &rawMessage)
|
||||
// send edit message also to privileged members
|
||||
privilegedMembers := community.GetPrivilegedMembers()
|
||||
for _, privilegedMember := range privilegedMembers {
|
||||
_, err := m.sender.SendPrivate(context.Background(), privilegedMember, &rawMessage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -2589,10 +2589,10 @@ func (m *Messenger) matchChatEntity(chatEntity common.ChatEntity) (*Chat, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
isMemberOwnerOrAdmin := community.IsMemberOwnerOrAdmin(chatEntity.GetSigPubKey())
|
||||
hasPermission := community.IsPrivilegedMember(chatEntity.GetSigPubKey())
|
||||
pinMessageAllowed := community.AllowsAllMembersToPinMessage()
|
||||
|
||||
if (pinMessage && !isMemberOwnerOrAdmin && !pinMessageAllowed) || (!emojiReaction && !canPost) {
|
||||
if (pinMessage && !hasPermission && !pinMessageAllowed) || (!emojiReaction && !canPost) {
|
||||
return nil, errors.New("user can't post")
|
||||
}
|
||||
|
||||
|
|
|
@ -36,10 +36,10 @@ func (m *Messenger) sendPinMessage(ctx context.Context, message *common.PinMessa
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
isMemberOwnerOrAdmin := community.IsMemberOwnerOrAdmin(&m.identity.PublicKey)
|
||||
hasPermission := community.IsPrivilegedMember(&m.identity.PublicKey)
|
||||
pinMessageAllowed := community.AllowsAllMembersToPinMessage()
|
||||
|
||||
if !pinMessageAllowed && !isMemberOwnerOrAdmin {
|
||||
if !pinMessageAllowed && !hasPermission {
|
||||
return nil, errors.New("member can't pin message")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue