feat: make any member able to add new users to group chat
closes: #2823, #2825
This commit is contained in:
parent
eee112738b
commit
c01316524c
|
@ -255,3 +255,12 @@ func buildContact(publicKeyString string, publicKey *ecdsa.PublicKey) (*Contact,
|
||||||
func contactIDFromPublicKey(key *ecdsa.PublicKey) string {
|
func contactIDFromPublicKey(key *ecdsa.PublicKey) string {
|
||||||
return types.EncodeHex(crypto.FromECDSAPub(key))
|
return types.EncodeHex(crypto.FromECDSAPub(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func contactIDFromPublicKeyString(key string) (string, error) {
|
||||||
|
pubKey, err := common.HexToPubkey(key)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return contactIDFromPublicKey(pubKey), nil
|
||||||
|
}
|
||||||
|
|
|
@ -379,6 +379,8 @@ func (s *MessengerEditMessageSuite) TestEditGroupChatMessage() {
|
||||||
err = s.m.SaveChat(ourChat)
|
err = s.m.SaveChat(ourChat)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
|
||||||
|
s.Require().NoError(makeMutualContact(s.m, &theirMessenger.identity.PublicKey))
|
||||||
|
|
||||||
members := []string{common.PubkeyToHex(&theirMessenger.identity.PublicKey)}
|
members := []string{common.PubkeyToHex(&theirMessenger.identity.PublicKey)}
|
||||||
_, err = s.m.AddMembersToGroupChat(context.Background(), ourChat.ID, members)
|
_, err = s.m.AddMembersToGroupChat(context.Background(), ourChat.ID, members)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
|
|
@ -153,6 +153,8 @@ func (s *MessengerEmojiSuite) TestEmojiPrivateGroup() {
|
||||||
response, err := bob.CreateGroupChatWithMembers(context.Background(), "test", []string{})
|
response, err := bob.CreateGroupChatWithMembers(context.Background(), "test", []string{})
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
|
||||||
|
s.Require().NoError(makeMutualContact(bob, &alice.identity.PublicKey))
|
||||||
|
|
||||||
chat := response.Chats()[0]
|
chat := response.Chats()[0]
|
||||||
members := []string{types.EncodeHex(crypto.FromECDSAPub(&alice.identity.PublicKey))}
|
members := []string{types.EncodeHex(crypto.FromECDSAPub(&alice.identity.PublicKey))}
|
||||||
_, err = bob.AddMembersToGroupChat(context.Background(), chat.ID, members)
|
_, err = bob.AddMembersToGroupChat(context.Background(), chat.ID, members)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package protocol
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -15,7 +16,28 @@ import (
|
||||||
v1protocol "github.com/status-im/status-go/protocol/v1"
|
v1protocol "github.com/status-im/status-go/protocol/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrGroupChatAddedContacts = errors.New("group-chat: can't add members who are not mutual contacts")
|
||||||
|
|
||||||
|
func (m *Messenger) validateAddedGroupMembers(members []string) error {
|
||||||
|
for _, memberPubkey := range members {
|
||||||
|
contactID, err := contactIDFromPublicKeyString(memberPubkey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
contact, _ := m.allContacts.Load(contactID)
|
||||||
|
if contact == nil || !(contact.Added && contact.HasAddedUs) {
|
||||||
|
return ErrGroupChatAddedContacts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Messenger) CreateGroupChatWithMembers(ctx context.Context, name string, members []string) (*MessengerResponse, error) {
|
func (m *Messenger) CreateGroupChatWithMembers(ctx context.Context, name string, members []string) (*MessengerResponse, error) {
|
||||||
|
if err := m.validateAddedGroupMembers(members); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var response MessengerResponse
|
var response MessengerResponse
|
||||||
logger := m.logger.With(zap.String("site", "CreateGroupChatWithMembers"))
|
logger := m.logger.With(zap.String("site", "CreateGroupChatWithMembers"))
|
||||||
logger.Info("Creating group chat", zap.String("name", name), zap.Any("members", members))
|
logger.Info("Creating group chat", zap.String("name", name), zap.Any("members", members))
|
||||||
|
@ -147,6 +169,10 @@ func (m *Messenger) RemoveMemberFromGroupChat(ctx context.Context, chatID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Messenger) AddMembersToGroupChat(ctx context.Context, chatID string, members []string) (*MessengerResponse, error) {
|
func (m *Messenger) AddMembersToGroupChat(ctx context.Context, chatID string, members []string) (*MessengerResponse, error) {
|
||||||
|
if err := m.validateAddedGroupMembers(members); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var response MessengerResponse
|
var response MessengerResponse
|
||||||
logger := m.logger.With(zap.String("site", "AddMembersFromGroupChat"))
|
logger := m.logger.With(zap.String("site", "AddMembersFromGroupChat"))
|
||||||
logger.Info("Adding members form group chat", zap.String("chatID", chatID), zap.Any("members", members))
|
logger.Info("Adding members form group chat", zap.String("chatID", chatID), zap.Any("members", members))
|
||||||
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
|
||||||
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
"github.com/status-im/status-go/protocol/common"
|
||||||
|
"github.com/status-im/status-go/protocol/tt"
|
||||||
|
"github.com/status-im/status-go/waku"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGroupChatSuite(t *testing.T) {
|
||||||
|
suite.Run(t, new(MessengerGroupChatSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessengerGroupChatSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
|
||||||
|
// If one wants to send messages between different instances of Messenger,
|
||||||
|
// a single Waku service should be shared.
|
||||||
|
shh types.Waku
|
||||||
|
logger *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) newMessenger() *Messenger {
|
||||||
|
privateKey, err := crypto.GenerateKey()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
messenger, err := newMessengerWithKey(s.shh, privateKey, s.logger, []Option{})
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
return messenger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) startNewMessenger() *Messenger {
|
||||||
|
messenger := s.newMessenger()
|
||||||
|
|
||||||
|
_, err := messenger.Start()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
return messenger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) SetupTest() {
|
||||||
|
s.logger = tt.MustCreateTestLogger()
|
||||||
|
|
||||||
|
config := waku.DefaultConfig
|
||||||
|
config.MinimumAcceptedPoW = 0
|
||||||
|
shh := waku.New(&config, s.logger)
|
||||||
|
s.shh = gethbridge.NewGethWakuWrapper(shh)
|
||||||
|
s.Require().NoError(shh.Start())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) TearDownTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) createGroupChat(creator *Messenger, name string, members []string) *Chat {
|
||||||
|
response, err := creator.CreateGroupChatWithMembers(context.Background(), name, members)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(response.Chats(), 1)
|
||||||
|
|
||||||
|
chat := response.Chats()[0]
|
||||||
|
err = creator.SaveChat(chat)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
return chat
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) createEmptyGroupChat(creator *Messenger, name string) *Chat {
|
||||||
|
return s.createGroupChat(creator, name, []string{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) verifyGroupChatCreated(member *Messenger, expectedChatActive bool) {
|
||||||
|
response, err := WaitOnMessengerResponse(
|
||||||
|
member,
|
||||||
|
func(r *MessengerResponse) bool { return len(r.Chats()) > 0 },
|
||||||
|
"chat invitation not received",
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(response.Chats(), 1)
|
||||||
|
s.Require().True(response.Chats()[0].Active == expectedChatActive)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeMutualContact(origin *Messenger, contactPubkey *ecdsa.PublicKey) error {
|
||||||
|
contact, err := BuildContactFromPublicKey(contactPubkey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
contact.Added = true
|
||||||
|
contact.HasAddedUs = true
|
||||||
|
origin.allContacts.Store(contact.ID, contact)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) makeContact(origin *Messenger, toAdd *Messenger) {
|
||||||
|
s.Require().NoError(makeMutualContact(origin, &toAdd.identity.PublicKey))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) TestGroupChatCreation() {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
creatorAddedMemberAsContact bool
|
||||||
|
memberAddedCreatorAsContact bool
|
||||||
|
expectedCreationSuccess bool
|
||||||
|
expectedAddedMemberChatActive bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "not added - not added",
|
||||||
|
creatorAddedMemberAsContact: false,
|
||||||
|
memberAddedCreatorAsContact: false,
|
||||||
|
expectedCreationSuccess: false,
|
||||||
|
expectedAddedMemberChatActive: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "added - not added",
|
||||||
|
creatorAddedMemberAsContact: true,
|
||||||
|
memberAddedCreatorAsContact: false,
|
||||||
|
expectedCreationSuccess: true,
|
||||||
|
expectedAddedMemberChatActive: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not added - added",
|
||||||
|
creatorAddedMemberAsContact: false,
|
||||||
|
memberAddedCreatorAsContact: true,
|
||||||
|
expectedCreationSuccess: false,
|
||||||
|
expectedAddedMemberChatActive: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "added - added",
|
||||||
|
creatorAddedMemberAsContact: true,
|
||||||
|
memberAddedCreatorAsContact: true,
|
||||||
|
expectedCreationSuccess: true,
|
||||||
|
expectedAddedMemberChatActive: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
creator := s.startNewMessenger()
|
||||||
|
member := s.startNewMessenger()
|
||||||
|
members := []string{common.PubkeyToHex(&member.identity.PublicKey)}
|
||||||
|
|
||||||
|
if testCase.creatorAddedMemberAsContact {
|
||||||
|
s.makeContact(creator, member)
|
||||||
|
}
|
||||||
|
if testCase.memberAddedCreatorAsContact {
|
||||||
|
s.makeContact(member, creator)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := creator.CreateGroupChatWithMembers(context.Background(), fmt.Sprintf("test_group_chat_%d", i), members)
|
||||||
|
if testCase.creatorAddedMemberAsContact {
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.verifyGroupChatCreated(member, testCase.expectedAddedMemberChatActive)
|
||||||
|
} else {
|
||||||
|
s.Require().EqualError(err, "group-chat: can't add members who are not mutual contacts")
|
||||||
|
}
|
||||||
|
|
||||||
|
defer creator.Shutdown()
|
||||||
|
defer member.Shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) TestGroupChatMembersAddition() {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
inviterAddedMemberAsContact bool
|
||||||
|
memberAddedInviterAsContact bool
|
||||||
|
expectedAdditionSuccess bool
|
||||||
|
expectedAddedMemberChatActive bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "not added - not added",
|
||||||
|
inviterAddedMemberAsContact: false,
|
||||||
|
memberAddedInviterAsContact: false,
|
||||||
|
expectedAdditionSuccess: false,
|
||||||
|
expectedAddedMemberChatActive: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "added - not added",
|
||||||
|
inviterAddedMemberAsContact: true,
|
||||||
|
memberAddedInviterAsContact: false,
|
||||||
|
expectedAdditionSuccess: true,
|
||||||
|
expectedAddedMemberChatActive: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not added - added",
|
||||||
|
inviterAddedMemberAsContact: false,
|
||||||
|
memberAddedInviterAsContact: true,
|
||||||
|
expectedAdditionSuccess: false,
|
||||||
|
expectedAddedMemberChatActive: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "added - added",
|
||||||
|
inviterAddedMemberAsContact: true,
|
||||||
|
memberAddedInviterAsContact: true,
|
||||||
|
expectedAdditionSuccess: true,
|
||||||
|
expectedAddedMemberChatActive: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
admin := s.startNewMessenger()
|
||||||
|
inviter := s.startNewMessenger()
|
||||||
|
member := s.startNewMessenger()
|
||||||
|
members := []string{common.PubkeyToHex(&member.identity.PublicKey)}
|
||||||
|
|
||||||
|
if testCase.inviterAddedMemberAsContact {
|
||||||
|
s.makeContact(inviter, member)
|
||||||
|
}
|
||||||
|
if testCase.memberAddedInviterAsContact {
|
||||||
|
s.makeContact(member, inviter)
|
||||||
|
}
|
||||||
|
|
||||||
|
for j, inviterIsAlsoGroupCreator := range []bool{true, false} {
|
||||||
|
var groupChat *Chat
|
||||||
|
if inviterIsAlsoGroupCreator {
|
||||||
|
groupChat = s.createEmptyGroupChat(inviter, fmt.Sprintf("test_group_chat_%d_%d", i, j))
|
||||||
|
} else {
|
||||||
|
s.makeContact(admin, inviter)
|
||||||
|
groupChat = s.createGroupChat(admin, fmt.Sprintf("test_group_chat_%d_%d", i, j), []string{common.PubkeyToHex(&inviter.identity.PublicKey)})
|
||||||
|
err := inviter.SaveChat(groupChat)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := inviter.AddMembersToGroupChat(context.Background(), groupChat.ID, members)
|
||||||
|
if testCase.inviterAddedMemberAsContact {
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.verifyGroupChatCreated(member, testCase.expectedAddedMemberChatActive)
|
||||||
|
} else {
|
||||||
|
s.Require().EqualError(err, "group-chat: can't add members who are not mutual contacts")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer admin.Shutdown()
|
||||||
|
defer inviter.Shutdown()
|
||||||
|
defer member.Shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerGroupChatSuite) TestGroupChatEdit() {
|
||||||
|
|
||||||
|
}
|
|
@ -499,6 +499,9 @@ func (s *MessengerSuite) TestSendPrivateGroup() {
|
||||||
chat := response.Chats()[0]
|
chat := response.Chats()[0]
|
||||||
key, err := crypto.GenerateKey()
|
key, err := crypto.GenerateKey()
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
|
||||||
|
s.Require().NoError(makeMutualContact(s.m, &key.PublicKey))
|
||||||
|
|
||||||
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&key.PublicKey))}
|
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&key.PublicKey))}
|
||||||
_, err = s.m.AddMembersToGroupChat(context.Background(), chat.ID, members)
|
_, err = s.m.AddMembersToGroupChat(context.Background(), chat.ID, members)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
@ -906,6 +909,8 @@ func (s *MessengerSuite) TestRetrieveTheirPrivateGroupChat() {
|
||||||
err = s.m.SaveChat(ourChat)
|
err = s.m.SaveChat(ourChat)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
|
||||||
|
s.Require().NoError(makeMutualContact(s.m, &theirMessenger.identity.PublicKey))
|
||||||
|
|
||||||
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))}
|
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))}
|
||||||
_, err = s.m.AddMembersToGroupChat(context.Background(), ourChat.ID, members)
|
_, err = s.m.AddMembersToGroupChat(context.Background(), ourChat.ID, members)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
@ -972,6 +977,8 @@ func (s *MessengerSuite) TestChangeNameGroupChat() {
|
||||||
err = s.m.SaveChat(ourChat)
|
err = s.m.SaveChat(ourChat)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
|
||||||
|
s.Require().NoError(makeMutualContact(s.m, &theirMessenger.identity.PublicKey))
|
||||||
|
|
||||||
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))}
|
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))}
|
||||||
_, err = s.m.AddMembersToGroupChat(context.Background(), ourChat.ID, members)
|
_, err = s.m.AddMembersToGroupChat(context.Background(), ourChat.ID, members)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
@ -1027,6 +1034,8 @@ func (s *MessengerSuite) TestReInvitedToGroupChat() {
|
||||||
err = s.m.SaveChat(ourChat)
|
err = s.m.SaveChat(ourChat)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
|
||||||
|
s.Require().NoError(makeMutualContact(s.m, &theirMessenger.identity.PublicKey))
|
||||||
|
|
||||||
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))}
|
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))}
|
||||||
_, err = s.m.AddMembersToGroupChat(context.Background(), ourChat.ID, members)
|
_, err = s.m.AddMembersToGroupChat(context.Background(), ourChat.ID, members)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
|
@ -1486,6 +1495,11 @@ func (s *MessengerSuite) TestSharedSecretHandler() {
|
||||||
|
|
||||||
func (s *MessengerSuite) TestCreateGroupChatWithMembers() {
|
func (s *MessengerSuite) TestCreateGroupChatWithMembers() {
|
||||||
members := []string{testPK}
|
members := []string{testPK}
|
||||||
|
|
||||||
|
pubKey, err := common.HexToPubkey(testPK)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NoError(makeMutualContact(s.m, pubKey))
|
||||||
|
|
||||||
response, err := s.m.CreateGroupChatWithMembers(context.Background(), "test", members)
|
response, err := s.m.CreateGroupChatWithMembers(context.Background(), "test", members)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
s.Require().Len(response.Chats(), 1)
|
s.Require().Len(response.Chats(), 1)
|
||||||
|
@ -1510,6 +1524,8 @@ func (s *MessengerSuite) TestAddMembersToChat() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&key.PublicKey))}
|
members := []string{"0x" + hex.EncodeToString(crypto.FromECDSAPub(&key.PublicKey))}
|
||||||
|
|
||||||
|
s.Require().NoError(makeMutualContact(s.m, &key.PublicKey))
|
||||||
|
|
||||||
response, err = s.m.AddMembersToGroupChat(context.Background(), chat.ID, members)
|
response, err = s.m.AddMembersToGroupChat(context.Background(), chat.ID, members)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().Len(response.Chats(), 1)
|
s.Require().Len(response.Chats(), 1)
|
||||||
|
|
|
@ -506,7 +506,8 @@ func (g Group) validateEvent(event MembershipUpdateEvent) bool {
|
||||||
case protobuf.MembershipUpdateEvent_IMAGE_CHANGED:
|
case protobuf.MembershipUpdateEvent_IMAGE_CHANGED:
|
||||||
return g.admins.Has(event.From) && len(event.Image) > 0
|
return g.admins.Has(event.From) && len(event.Image) > 0
|
||||||
case protobuf.MembershipUpdateEvent_MEMBERS_ADDED:
|
case protobuf.MembershipUpdateEvent_MEMBERS_ADDED:
|
||||||
return g.admins.Has(event.From)
|
// Admins and members can add new members
|
||||||
|
return g.admins.Has(event.From) || g.members.Has(event.From)
|
||||||
case protobuf.MembershipUpdateEvent_MEMBER_JOINED:
|
case protobuf.MembershipUpdateEvent_MEMBER_JOINED:
|
||||||
return g.members.Has(event.From)
|
return g.members.Has(event.From)
|
||||||
case protobuf.MembershipUpdateEvent_MEMBER_REMOVED:
|
case protobuf.MembershipUpdateEvent_MEMBER_REMOVED:
|
||||||
|
|
Loading…
Reference in New Issue