refactor: simplify community requests logic
With the recent introduction of pending states, the community requests logic became more complex. This commit simplifies the flow and appropriately delegates logic to its corresponding abstraction levels: messenger, manager and community. Additionally, it eliminates redundancies in notifications and request-saving mechanism.
This commit is contained in:
parent
b932cc97bb
commit
a9cde06e44
|
@ -1021,12 +1021,19 @@ func (o *Community) ValidateRequestToJoin(signer *ecdsa.PublicKey, request *prot
|
||||||
o.mutex.Lock()
|
o.mutex.Lock()
|
||||||
defer o.mutex.Unlock()
|
defer o.mutex.Unlock()
|
||||||
|
|
||||||
// If we are not admin, fuggetaboutit
|
if o.IsControlNode() {
|
||||||
if !o.IsControlNode() && !o.HasPermissionToSendCommunityEvents() {
|
// TODO: Enable this once mobile supports revealed addresses.
|
||||||
|
// if len(request.RevealedAccounts) == 0 {
|
||||||
|
// return errors.New("no addresses revealed")
|
||||||
|
// }
|
||||||
|
} else if o.HasPermissionToSendCommunityEvents() {
|
||||||
|
if o.AcceptRequestToJoinAutomatically() {
|
||||||
|
return errors.New("auto-accept community requests can only be processed by the control node")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return ErrNotAdmin
|
return ErrNotAdmin
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the org is ens name only, then reject if not present
|
|
||||||
if o.config.CommunityDescription.Permissions.EnsOnly && len(request.EnsName) == 0 {
|
if o.config.CommunityDescription.Permissions.EnsOnly && len(request.EnsName) == 0 {
|
||||||
return ErrCantRequestAccess
|
return ErrCantRequestAccess
|
||||||
}
|
}
|
||||||
|
@ -1040,6 +1047,19 @@ func (o *Community) ValidateRequestToJoin(signer *ecdsa.PublicKey, request *prot
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if o.isBanned(signer) {
|
||||||
|
return ErrCantRequestAccess
|
||||||
|
}
|
||||||
|
|
||||||
|
timeNow := uint64(time.Now().Unix())
|
||||||
|
requestTimeOutClock, err := AddTimeoutToRequestToJoinClock(request.Clock)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if timeNow >= requestTimeOutClock {
|
||||||
|
return errors.New("request is expired")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,21 +338,25 @@ func (s *CommunitySuite) TestValidateRequestToJoin() {
|
||||||
request := &protobuf.CommunityRequestToJoin{
|
request := &protobuf.CommunityRequestToJoin{
|
||||||
EnsName: "donvanvliet.stateofus.eth",
|
EnsName: "donvanvliet.stateofus.eth",
|
||||||
CommunityId: s.communityID,
|
CommunityId: s.communityID,
|
||||||
|
Clock: uint64(time.Now().Unix()),
|
||||||
}
|
}
|
||||||
|
|
||||||
requestWithChatID := &protobuf.CommunityRequestToJoin{
|
requestWithChatID := &protobuf.CommunityRequestToJoin{
|
||||||
EnsName: "donvanvliet.stateofus.eth",
|
EnsName: "donvanvliet.stateofus.eth",
|
||||||
CommunityId: s.communityID,
|
CommunityId: s.communityID,
|
||||||
ChatId: testChatID1,
|
ChatId: testChatID1,
|
||||||
|
Clock: uint64(time.Now().Unix()),
|
||||||
}
|
}
|
||||||
|
|
||||||
requestWithoutENS := &protobuf.CommunityRequestToJoin{
|
requestWithoutENS := &protobuf.CommunityRequestToJoin{
|
||||||
CommunityId: s.communityID,
|
CommunityId: s.communityID,
|
||||||
|
Clock: uint64(time.Now().Unix()),
|
||||||
}
|
}
|
||||||
|
|
||||||
requestWithChatWithoutENS := &protobuf.CommunityRequestToJoin{
|
requestWithChatWithoutENS := &protobuf.CommunityRequestToJoin{
|
||||||
CommunityId: s.communityID,
|
CommunityId: s.communityID,
|
||||||
ChatId: testChatID1,
|
ChatId: testChatID1,
|
||||||
|
Clock: uint64(time.Now().Unix()),
|
||||||
}
|
}
|
||||||
|
|
||||||
// MATRIX
|
// MATRIX
|
||||||
|
|
|
@ -2308,25 +2308,17 @@ func (m *Manager) DeclineRequestToJoin(dbRequest *RequestToJoin) (*Community, er
|
||||||
return community, nil
|
return community, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) isUserRejectedFromCommunity(signer *ecdsa.PublicKey, community *Community, requestClock uint64) (bool, error) {
|
func (m *Manager) shouldUserRetainDeclined(signer *ecdsa.PublicKey, community *Community, requestClock uint64) (bool, error) {
|
||||||
declinedRequestsToJoin, err := m.persistence.DeclinedRequestsToJoinForCommunity(community.ID())
|
requestID := CalculateRequestID(common.PubkeyToHex(signer), types.HexBytes(community.IDString()))
|
||||||
|
request, err := m.persistence.GetRequestToJoin(requestID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
if err == sql.ErrNoRows {
|
||||||
}
|
|
||||||
|
|
||||||
for _, req := range declinedRequestsToJoin {
|
|
||||||
if req.PublicKey == common.PubkeyToHex(signer) {
|
|
||||||
dbRequestTimeOutClock, err := AddTimeoutToRequestToJoinClock(req.Clock)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if requestClock < dbRequestTimeOutClock {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false, nil
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return request.ShouldRetainDeclined(requestClock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) HandleCommunityCancelRequestToJoin(signer *ecdsa.PublicKey, request *protobuf.CommunityCancelRequestToJoin) (*RequestToJoin, error) {
|
func (m *Manager) HandleCommunityCancelRequestToJoin(signer *ecdsa.PublicKey, request *protobuf.CommunityCancelRequestToJoin) (*RequestToJoin, error) {
|
||||||
|
@ -2338,11 +2330,11 @@ func (m *Manager) HandleCommunityCancelRequestToJoin(signer *ecdsa.PublicKey, re
|
||||||
return nil, ErrOrgNotFound
|
return nil, ErrOrgNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
isUserRejected, err := m.isUserRejectedFromCommunity(signer, community, request.Clock)
|
retainDeclined, err := m.shouldUserRetainDeclined(signer, community, request.Clock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if isUserRejected {
|
if retainDeclined {
|
||||||
return nil, ErrCommunityRequestAlreadyRejected
|
return nil, ErrCommunityRequestAlreadyRejected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2359,41 +2351,18 @@ func (m *Manager) HandleCommunityCancelRequestToJoin(signer *ecdsa.PublicKey, re
|
||||||
return requestToJoin, nil
|
return requestToJoin, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, receiver *ecdsa.PublicKey, request *protobuf.CommunityRequestToJoin) (*RequestToJoin, error) {
|
func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, receiver *ecdsa.PublicKey, request *protobuf.CommunityRequestToJoin) (*Community, *RequestToJoin, error) {
|
||||||
community, err := m.persistence.GetByID(&m.identity.PublicKey, request.CommunityId)
|
community, err := m.persistence.GetByID(&m.identity.PublicKey, request.CommunityId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
if community == nil {
|
if community == nil {
|
||||||
return nil, ErrOrgNotFound
|
return nil, nil, ErrOrgNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't process request as admin if community is configured as auto-accept
|
err = community.ValidateRequestToJoin(signer, request)
|
||||||
if !community.IsControlNode() && community.AcceptRequestToJoinAutomatically() {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// control node must receive requests to join only on community address
|
|
||||||
// ignore duplicate messages sent to control node pubKey
|
|
||||||
if community.IsControlNode() && receiver.Equal(m.identity) {
|
|
||||||
return nil, errors.New("duplicate msg sent to the owner")
|
|
||||||
}
|
|
||||||
|
|
||||||
isUserRejected, err := m.isUserRejectedFromCommunity(signer, community, request.Clock)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
|
||||||
if isUserRejected {
|
|
||||||
return nil, ErrCommunityRequestAlreadyRejected
|
|
||||||
}
|
|
||||||
|
|
||||||
// Banned member can't request to join community
|
|
||||||
if community.isBanned(signer) {
|
|
||||||
return nil, ErrCantRequestAccess
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := community.ValidateRequestToJoin(signer, request); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
requestToJoin := &RequestToJoin{
|
requestToJoin := &RequestToJoin{
|
||||||
|
@ -2404,33 +2373,38 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, receiver
|
||||||
State: RequestToJoinStatePending,
|
State: RequestToJoinStatePending,
|
||||||
RevealedAccounts: request.RevealedAccounts,
|
RevealedAccounts: request.RevealedAccounts,
|
||||||
}
|
}
|
||||||
|
|
||||||
requestToJoin.CalculateID()
|
requestToJoin.CalculateID()
|
||||||
|
|
||||||
existingRequestToJoin, err := m.persistence.GetRequestToJoin(requestToJoin.ID)
|
existingRequestToJoin, err := m.persistence.GetRequestToJoin(requestToJoin.ID)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if existingRequestToJoin == nil || existingRequestToJoin.State == RequestToJoinStateCanceled {
|
if existingRequestToJoin == nil {
|
||||||
if err := m.persistence.SaveRequestToJoin(requestToJoin); err != nil {
|
err = m.SaveRequestToJoin(requestToJoin)
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
retainDeclined, err := existingRequestToJoin.ShouldRetainDeclined(request.Clock)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if retainDeclined {
|
||||||
|
return nil, nil, ErrCommunityRequestAlreadyRejected
|
||||||
|
}
|
||||||
|
|
||||||
|
switch existingRequestToJoin.State {
|
||||||
|
case RequestToJoinStatePending, RequestToJoinStateDeclined, RequestToJoinStateCanceled:
|
||||||
|
// Another request have been received, save request back to pending state
|
||||||
|
err = m.SaveRequestToJoin(requestToJoin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if community.IsControlNode() {
|
if community.IsControlNode() {
|
||||||
// request to join was already processed by an admin and waits to get
|
|
||||||
// confirmation for its decision
|
|
||||||
//
|
|
||||||
// we're only interested in immediately declining any declined/pending
|
|
||||||
// requests here, because if it's accepted/pending, we still need to perform
|
|
||||||
// some checks
|
|
||||||
if existingRequestToJoin != nil && existingRequestToJoin.State == RequestToJoinStateDeclinedPending {
|
|
||||||
requestToJoin.State = RequestToJoinStateDeclined
|
|
||||||
return requestToJoin, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(request.RevealedAccounts) > 0 {
|
|
||||||
// verify if revealed addresses indeed belong to requester
|
// verify if revealed addresses indeed belong to requester
|
||||||
for _, revealedAccount := range request.RevealedAccounts {
|
for _, revealedAccount := range request.RevealedAccounts {
|
||||||
recoverParams := account.RecoverParams{
|
recoverParams := account.RecoverParams{
|
||||||
|
@ -2440,13 +2414,13 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, receiver
|
||||||
|
|
||||||
matching, err := m.accountsManager.CanRecover(recoverParams, types.HexToAddress(revealedAccount.Address))
|
matching, err := m.accountsManager.CanRecover(recoverParams, types.HexToAddress(revealedAccount.Address))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
if !matching {
|
if !matching {
|
||||||
// if ownership of only one wallet address cannot be verified,
|
// if ownership of only one wallet address cannot be verified,
|
||||||
// we mark the request as cancelled and stop
|
// we mark the request as cancelled and stop
|
||||||
requestToJoin.State = RequestToJoinStateDeclined
|
requestToJoin.State = RequestToJoinStateDeclined
|
||||||
return requestToJoin, nil
|
return community, requestToJoin, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2454,7 +2428,18 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, receiver
|
||||||
// to the control node's local table of known revealed addresses
|
// to the control node's local table of known revealed addresses
|
||||||
err = m.persistence.SaveRequestToJoinRevealedAddresses(requestToJoin.ID, requestToJoin.RevealedAccounts)
|
err = m.persistence.SaveRequestToJoinRevealedAddresses(requestToJoin.ID, requestToJoin.RevealedAccounts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if existingRequestToJoin != nil {
|
||||||
|
// request to join was already processed by privileged user
|
||||||
|
// and waits to get confirmation for its decision
|
||||||
|
if existingRequestToJoin.State == RequestToJoinStateDeclinedPending {
|
||||||
|
requestToJoin.State = RequestToJoinStateDeclined
|
||||||
|
return community, requestToJoin, nil
|
||||||
|
} else if existingRequestToJoin.State == RequestToJoinStateAcceptedPending {
|
||||||
|
requestToJoin.State = RequestToJoinStateAccepted
|
||||||
|
return community, requestToJoin, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2462,23 +2447,15 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, receiver
|
||||||
// It may happen when member removes itself from community and then tries to rejoin
|
// It may happen when member removes itself from community and then tries to rejoin
|
||||||
// More specifically, CommunityRequestToLeave may be delivered later than CommunityRequestToJoin, or not delivered at all
|
// More specifically, CommunityRequestToLeave may be delivered later than CommunityRequestToJoin, or not delivered at all
|
||||||
acceptAutomatically := community.AcceptRequestToJoinAutomatically() || community.HasMember(signer)
|
acceptAutomatically := community.AcceptRequestToJoinAutomatically() || community.HasMember(signer)
|
||||||
// If the request to join was already accepted by another admin,
|
if acceptAutomatically {
|
||||||
// we mark it as accepted so it won't be in pending state, even if the community
|
|
||||||
// is not set to auto-accept
|
|
||||||
acceptedByAdmin := existingRequestToJoin != nil && existingRequestToJoin.State == RequestToJoinStateAcceptedPending
|
|
||||||
if acceptAutomatically || acceptedByAdmin {
|
|
||||||
err = m.markRequestToJoinAsAccepted(signer, community)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Don't check permissions here,
|
// Don't check permissions here,
|
||||||
// it will be done further in the processing pipeline.
|
// it will be done further in the processing pipeline.
|
||||||
requestToJoin.State = RequestToJoinStateAccepted
|
requestToJoin.State = RequestToJoinStateAccepted
|
||||||
return requestToJoin, nil
|
return community, requestToJoin, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return requestToJoin, nil
|
return community, requestToJoin, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) HandleCommunityEditSharedAddresses(signer *ecdsa.PublicKey, request *protobuf.CommunityEditSharedAddresses) error {
|
func (m *Manager) HandleCommunityEditSharedAddresses(signer *ecdsa.PublicKey, request *protobuf.CommunityEditSharedAddresses) error {
|
||||||
|
|
|
@ -74,6 +74,19 @@ func (r *RequestToJoin) Empty() bool {
|
||||||
return len(r.ID)+len(r.PublicKey)+int(r.Clock)+len(r.ENSName)+len(r.ChatID)+len(r.CommunityID)+int(r.State) == 0
|
return len(r.ID)+len(r.PublicKey)+int(r.Clock)+len(r.ENSName)+len(r.ChatID)+len(r.CommunityID)+int(r.State) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *RequestToJoin) ShouldRetainDeclined(clock uint64) (bool, error) {
|
||||||
|
if r.State != RequestToJoinStateDeclined {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
declineExpiryClock, err := AddTimeoutToRequestToJoinClock(r.Clock)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return clock < declineExpiryClock, nil
|
||||||
|
}
|
||||||
|
|
||||||
func AddTimeoutToRequestToJoinClock(clock uint64) (uint64, error) {
|
func AddTimeoutToRequestToJoinClock(clock uint64) (uint64, error) {
|
||||||
requestToJoinClock, err := strconv.ParseInt(fmt.Sprint(clock), 10, 64)
|
requestToJoinClock, err := strconv.ParseInt(fmt.Sprint(clock), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1500,16 +1500,7 @@ func (m *Messenger) CancelRequestToJoinCommunity(request *requests.CancelRequest
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Messenger) AcceptRequestToJoinCommunity(request *requests.AcceptRequestToJoinCommunity) (*MessengerResponse, error) {
|
func (m *Messenger) acceptRequestToJoinCommunity(requestToJoin *communities.RequestToJoin) (*MessengerResponse, error) {
|
||||||
if err := request.Validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
requestToJoin, err := m.communitiesManager.GetRequestToJoin(request.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
community, err := m.communitiesManager.AcceptRequestToJoin(requestToJoin)
|
community, err := m.communitiesManager.AcceptRequestToJoin(requestToJoin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1577,12 +1568,11 @@ func (m *Messenger) AcceptRequestToJoinCommunity(request *requests.AcceptRequest
|
||||||
response.AddCommunity(community)
|
response.AddCommunity(community)
|
||||||
response.AddRequestToJoinCommunity(requestToJoin)
|
response.AddRequestToJoinCommunity(requestToJoin)
|
||||||
|
|
||||||
// Activity Center notification
|
// Update existing notification
|
||||||
notification, err := m.persistence.GetActivityCenterNotificationByID(request.ID)
|
notification, err := m.persistence.GetActivityCenterNotificationByID(requestToJoin.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if notification != nil {
|
if notification != nil {
|
||||||
notification.MembershipStatus = ActivityCenterMembershipStatusAccepted
|
notification.MembershipStatus = ActivityCenterMembershipStatusAccepted
|
||||||
if community.HasPermissionToSendCommunityEvents() {
|
if community.HasPermissionToSendCommunityEvents() {
|
||||||
|
@ -1602,17 +1592,21 @@ func (m *Messenger) AcceptRequestToJoinCommunity(request *requests.AcceptRequest
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Messenger) DeclineRequestToJoinCommunity(request *requests.DeclineRequestToJoinCommunity) (*MessengerResponse, error) {
|
func (m *Messenger) AcceptRequestToJoinCommunity(request *requests.AcceptRequestToJoinCommunity) (*MessengerResponse, error) {
|
||||||
if err := request.Validate(); err != nil {
|
if err := request.Validate(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dbRequest, err := m.communitiesManager.GetRequestToJoin(request.ID)
|
requestToJoin, err := m.communitiesManager.GetRequestToJoin(request.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
community, err := m.communitiesManager.DeclineRequestToJoin(dbRequest)
|
return m.acceptRequestToJoinCommunity(requestToJoin)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) declineRequestToJoinCommunity(requestToJoin *communities.RequestToJoin) (*MessengerResponse, error) {
|
||||||
|
community, err := m.communitiesManager.DeclineRequestToJoin(requestToJoin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1620,9 +1614,9 @@ func (m *Messenger) DeclineRequestToJoinCommunity(request *requests.DeclineReque
|
||||||
if community.IsControlNode() {
|
if community.IsControlNode() {
|
||||||
// Notify privileged members that request to join was rejected
|
// Notify privileged members that request to join was rejected
|
||||||
// Send request to join without revealed addresses
|
// Send request to join without revealed addresses
|
||||||
dbRequest.RevealedAccounts = make([]*protobuf.RevealedAccount, 0)
|
requestToJoin.RevealedAccounts = make([]*protobuf.RevealedAccount, 0)
|
||||||
declinedRequestsToJoin := make(map[string]*protobuf.CommunityRequestToJoin)
|
declinedRequestsToJoin := make(map[string]*protobuf.CommunityRequestToJoin)
|
||||||
declinedRequestsToJoin[dbRequest.PublicKey] = dbRequest.ToCommunityRequestToJoinProtobuf()
|
declinedRequestsToJoin[requestToJoin.PublicKey] = requestToJoin.ToCommunityRequestToJoinProtobuf()
|
||||||
|
|
||||||
syncMsg := &protobuf.CommunityPrivilegedUserSyncMessage{
|
syncMsg := &protobuf.CommunityPrivilegedUserSyncMessage{
|
||||||
Type: protobuf.CommunityPrivilegedUserSyncMessage_CONTROL_NODE_REJECT_REQUEST_TO_JOIN,
|
Type: protobuf.CommunityPrivilegedUserSyncMessage_CONTROL_NODE_REJECT_REQUEST_TO_JOIN,
|
||||||
|
@ -1654,25 +1648,16 @@ func (m *Messenger) DeclineRequestToJoinCommunity(request *requests.DeclineReque
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activity Center notification
|
|
||||||
notification, err := m.persistence.GetActivityCenterNotificationByID(request.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &MessengerResponse{}
|
response := &MessengerResponse{}
|
||||||
dbRequest, err = m.communitiesManager.GetRequestToJoin(request.ID)
|
response.AddCommunity(community)
|
||||||
response.AddRequestToJoinCommunity(dbRequest)
|
response.AddRequestToJoinCommunity(requestToJoin)
|
||||||
|
|
||||||
|
// Update existing notification
|
||||||
|
notification, err := m.persistence.GetActivityCenterNotificationByID(requestToJoin.ID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if notification != nil {
|
if notification != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
community, err := m.communitiesManager.GetByID(dbRequest.CommunityID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
notification.MembershipStatus = ActivityCenterMembershipStatusDeclined
|
notification.MembershipStatus = ActivityCenterMembershipStatusDeclined
|
||||||
if community.HasPermissionToSendCommunityEvents() {
|
if community.HasPermissionToSendCommunityEvents() {
|
||||||
notification.MembershipStatus = ActivityCenterMembershipStatusDeclinedPending
|
notification.MembershipStatus = ActivityCenterMembershipStatusDeclinedPending
|
||||||
|
@ -1691,6 +1676,19 @@ func (m *Messenger) DeclineRequestToJoinCommunity(request *requests.DeclineReque
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) DeclineRequestToJoinCommunity(request *requests.DeclineRequestToJoinCommunity) (*MessengerResponse, error) {
|
||||||
|
if err := request.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
requestToJoin, err := m.communitiesManager.GetRequestToJoin(request.ID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.declineRequestToJoinCommunity(requestToJoin)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Messenger) LeaveCommunity(communityID types.HexBytes) (*MessengerResponse, error) {
|
func (m *Messenger) LeaveCommunity(communityID types.HexBytes) (*MessengerResponse, error) {
|
||||||
notifications, err := m.persistence.DismissAllActivityCenterNotificationsFromCommunity(communityID.String(), m.getCurrentTimeInMillis())
|
notifications, err := m.persistence.DismissAllActivityCenterNotificationsFromCommunity(communityID.String(), m.getCurrentTimeInMillis())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1465,68 +1465,15 @@ func (m *Messenger) HandleCommunityCancelRequestToJoin(state *ReceivedMessageSta
|
||||||
|
|
||||||
// HandleCommunityRequestToJoin handles an community request to join
|
// HandleCommunityRequestToJoin handles an community request to join
|
||||||
func (m *Messenger) HandleCommunityRequestToJoin(state *ReceivedMessageState, requestToJoinProto *protobuf.CommunityRequestToJoin, statusMessage *v1protocol.StatusMessage) error {
|
func (m *Messenger) HandleCommunityRequestToJoin(state *ReceivedMessageState, requestToJoinProto *protobuf.CommunityRequestToJoin, statusMessage *v1protocol.StatusMessage) error {
|
||||||
if requestToJoinProto.CommunityId == nil {
|
|
||||||
return ErrInvalidCommunityID
|
|
||||||
}
|
|
||||||
|
|
||||||
timeNow := uint64(time.Now().Unix())
|
|
||||||
|
|
||||||
requestTimeOutClock, err := communities.AddTimeoutToRequestToJoinClock(requestToJoinProto.Clock)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if timeNow >= requestTimeOutClock {
|
|
||||||
return errors.New("request is expired")
|
|
||||||
}
|
|
||||||
|
|
||||||
signer := state.CurrentMessageState.PublicKey
|
signer := state.CurrentMessageState.PublicKey
|
||||||
receiver := statusMessage.Dst
|
community, requestToJoin, err := m.communitiesManager.HandleCommunityRequestToJoin(signer, statusMessage.Dst, requestToJoinProto)
|
||||||
requestToJoin, err := m.communitiesManager.HandleCommunityRequestToJoin(signer, receiver, requestToJoinProto)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// not interested, stop further processing
|
|
||||||
if requestToJoin == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if requestToJoin.State == communities.RequestToJoinStateAccepted {
|
|
||||||
accept := &requests.AcceptRequestToJoinCommunity{
|
|
||||||
ID: requestToJoin.ID,
|
|
||||||
}
|
|
||||||
_, err = m.AcceptRequestToJoinCommunity(accept)
|
|
||||||
if err != nil {
|
|
||||||
if err == communities.ErrNoPermissionToJoin {
|
|
||||||
// only control node will end up here as it's the only one that
|
|
||||||
// performed token permission checks
|
|
||||||
requestToJoin.State = communities.RequestToJoinStateDeclined
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if requestToJoin.State == communities.RequestToJoinStateDeclined {
|
|
||||||
cancel := &requests.DeclineRequestToJoinCommunity{
|
|
||||||
ID: requestToJoin.ID,
|
|
||||||
}
|
|
||||||
_, err = m.DeclineRequestToJoinCommunity(cancel)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
community, err := m.communitiesManager.GetByID(requestToJoinProto.CommunityId)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
contactID := contactIDFromPublicKey(signer)
|
switch requestToJoin.State {
|
||||||
|
case communities.RequestToJoinStatePending:
|
||||||
contact, _ := state.AllContacts.Load(contactID)
|
contact, _ := state.AllContacts.Load(contactIDFromPublicKey(signer))
|
||||||
|
|
||||||
if len(requestToJoinProto.DisplayName) != 0 {
|
if len(requestToJoinProto.DisplayName) != 0 {
|
||||||
contact.DisplayName = requestToJoinProto.DisplayName
|
contact.DisplayName = requestToJoinProto.DisplayName
|
||||||
state.ModifiedContacts.Store(contact.ID, true)
|
state.ModifiedContacts.Store(contact.ID, true)
|
||||||
|
@ -1534,7 +1481,6 @@ func (m *Messenger) HandleCommunityRequestToJoin(state *ReceivedMessageState, re
|
||||||
state.ModifiedContacts.Store(contact.ID, true)
|
state.ModifiedContacts.Store(contact.ID, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if requestToJoin.State == communities.RequestToJoinStatePending {
|
|
||||||
if state.Response.RequestsToJoinCommunity == nil {
|
if state.Response.RequestsToJoinCommunity == nil {
|
||||||
state.Response.RequestsToJoinCommunity = make([]*communities.RequestToJoin, 0)
|
state.Response.RequestsToJoinCommunity = make([]*communities.RequestToJoin, 0)
|
||||||
}
|
}
|
||||||
|
@ -1553,32 +1499,52 @@ func (m *Messenger) HandleCommunityRequestToJoin(state *ReceivedMessageState, re
|
||||||
Deleted: false,
|
Deleted: false,
|
||||||
UpdatedAt: m.getCurrentTimeInMillis(),
|
UpdatedAt: m.getCurrentTimeInMillis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = m.addActivityCenterNotification(state.Response, notification)
|
err = m.addActivityCenterNotification(state.Response, notification)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.logger.Error("failed to save notification", zap.Error(err))
|
m.logger.Error("failed to save notification", zap.Error(err))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Activity Center notification, updating existing for accepted/declined
|
case communities.RequestToJoinStateDeclined:
|
||||||
notification, err := m.persistence.GetActivityCenterNotificationByID(requestToJoin.ID)
|
response, err := m.declineRequestToJoinCommunity(requestToJoin)
|
||||||
|
if err == nil {
|
||||||
|
err := state.Response.Merge(response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if notification != nil {
|
case communities.RequestToJoinStateAccepted:
|
||||||
if requestToJoin.State == communities.RequestToJoinStateAccepted {
|
response, err := m.acceptRequestToJoinCommunity(requestToJoin)
|
||||||
notification.MembershipStatus = ActivityCenterMembershipStatusAccepted
|
if err == nil {
|
||||||
} else {
|
err := state.Response.Merge(response) // new member has been added
|
||||||
notification.MembershipStatus = ActivityCenterMembershipStatusDeclined
|
|
||||||
}
|
|
||||||
notification.UpdatedAt = m.getCurrentTimeInMillis()
|
|
||||||
err = m.addActivityCenterNotification(state.Response, notification)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.logger.Error("failed to save notification", zap.Error(err))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else if err == communities.ErrNoPermissionToJoin {
|
||||||
|
// only control node will end up here as it's the only one that
|
||||||
|
// performed token permission checks
|
||||||
|
response, err = m.declineRequestToJoinCommunity(requestToJoin)
|
||||||
|
if err == nil {
|
||||||
|
err := state.Response.Merge(response)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
case communities.RequestToJoinStateCanceled:
|
||||||
|
// cancellation is handled by separate message
|
||||||
|
fallthrough
|
||||||
|
case communities.RequestToJoinStateAcceptedPending, communities.RequestToJoinStateDeclinedPending:
|
||||||
|
// request can be marked as pending only manually
|
||||||
|
return errors.New("invalid request state")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue