github.com/status-im/status-go@v1.1.0/protocol/communities/roles_authorization.go (about) 1 package communities 2 3 import ( 4 "golang.org/x/exp/slices" 5 6 "github.com/status-im/status-go/protocol/protobuf" 7 ) 8 9 var adminAuthorizedEventTypes = []protobuf.CommunityEvent_EventType{ 10 protobuf.CommunityEvent_COMMUNITY_EDIT, 11 protobuf.CommunityEvent_COMMUNITY_MEMBER_TOKEN_PERMISSION_CHANGE, 12 protobuf.CommunityEvent_COMMUNITY_MEMBER_TOKEN_PERMISSION_DELETE, 13 protobuf.CommunityEvent_COMMUNITY_CATEGORY_CREATE, 14 protobuf.CommunityEvent_COMMUNITY_CATEGORY_DELETE, 15 protobuf.CommunityEvent_COMMUNITY_CATEGORY_EDIT, 16 protobuf.CommunityEvent_COMMUNITY_CHANNEL_CREATE, 17 protobuf.CommunityEvent_COMMUNITY_CHANNEL_DELETE, 18 protobuf.CommunityEvent_COMMUNITY_CHANNEL_EDIT, 19 protobuf.CommunityEvent_COMMUNITY_CATEGORY_REORDER, 20 protobuf.CommunityEvent_COMMUNITY_CHANNEL_REORDER, 21 protobuf.CommunityEvent_COMMUNITY_REQUEST_TO_JOIN_ACCEPT, 22 protobuf.CommunityEvent_COMMUNITY_REQUEST_TO_JOIN_REJECT, 23 protobuf.CommunityEvent_COMMUNITY_MEMBER_KICK, 24 protobuf.CommunityEvent_COMMUNITY_MEMBER_BAN, 25 protobuf.CommunityEvent_COMMUNITY_MEMBER_UNBAN, 26 protobuf.CommunityEvent_COMMUNITY_DELETE_BANNED_MEMBER_MESSAGES, 27 } 28 29 var tokenMasterAuthorizedEventTypes = append(adminAuthorizedEventTypes, []protobuf.CommunityEvent_EventType{ 30 protobuf.CommunityEvent_COMMUNITY_TOKEN_ADD, 31 }...) 32 33 var ownerAuthorizedEventTypes = tokenMasterAuthorizedEventTypes 34 35 var rolesToAuthorizedEventTypes = map[protobuf.CommunityMember_Roles][]protobuf.CommunityEvent_EventType{ 36 protobuf.CommunityMember_ROLE_NONE: []protobuf.CommunityEvent_EventType{}, 37 protobuf.CommunityMember_ROLE_OWNER: ownerAuthorizedEventTypes, 38 protobuf.CommunityMember_ROLE_ADMIN: adminAuthorizedEventTypes, 39 protobuf.CommunityMember_ROLE_TOKEN_MASTER: tokenMasterAuthorizedEventTypes, 40 } 41 42 var adminAuthorizedPermissionTypes = []protobuf.CommunityTokenPermission_Type{ 43 protobuf.CommunityTokenPermission_BECOME_MEMBER, 44 protobuf.CommunityTokenPermission_CAN_VIEW_CHANNEL, 45 protobuf.CommunityTokenPermission_CAN_VIEW_AND_POST_CHANNEL, 46 } 47 48 var tokenMasterAuthorizedPermissionTypes = append(adminAuthorizedPermissionTypes, []protobuf.CommunityTokenPermission_Type{}...) 49 50 var ownerAuthorizedPermissionTypes = append(tokenMasterAuthorizedPermissionTypes, []protobuf.CommunityTokenPermission_Type{ 51 protobuf.CommunityTokenPermission_BECOME_ADMIN, 52 protobuf.CommunityTokenPermission_BECOME_TOKEN_MASTER, 53 }...) 54 55 var rolesToAuthorizedPermissionTypes = map[protobuf.CommunityMember_Roles][]protobuf.CommunityTokenPermission_Type{ 56 protobuf.CommunityMember_ROLE_NONE: []protobuf.CommunityTokenPermission_Type{}, 57 protobuf.CommunityMember_ROLE_OWNER: ownerAuthorizedPermissionTypes, 58 protobuf.CommunityMember_ROLE_ADMIN: adminAuthorizedPermissionTypes, 59 protobuf.CommunityMember_ROLE_TOKEN_MASTER: tokenMasterAuthorizedPermissionTypes, 60 } 61 62 func canRolesPerformEvent(roles []protobuf.CommunityMember_Roles, eventType protobuf.CommunityEvent_EventType) bool { 63 for _, role := range roles { 64 if slices.Contains(rolesToAuthorizedEventTypes[role], eventType) { 65 return true 66 } 67 } 68 return false 69 } 70 71 func canRolesModifyPermission(roles []protobuf.CommunityMember_Roles, permissionType protobuf.CommunityTokenPermission_Type) bool { 72 for _, role := range roles { 73 if slices.Contains(rolesToAuthorizedPermissionTypes[role], permissionType) { 74 return true 75 } 76 } 77 return false 78 } 79 80 func canRolesKickOrBanMember(senderRoles []protobuf.CommunityMember_Roles, memberRoles []protobuf.CommunityMember_Roles) bool { 81 // Owner can kick everyone 82 if slices.Contains(senderRoles, protobuf.CommunityMember_ROLE_OWNER) { 83 return true 84 } 85 86 // TokenMaster can kick normal members and admins 87 if (slices.Contains(senderRoles, protobuf.CommunityMember_ROLE_TOKEN_MASTER)) && 88 !(slices.Contains(memberRoles, protobuf.CommunityMember_ROLE_TOKEN_MASTER) || 89 slices.Contains(memberRoles, protobuf.CommunityMember_ROLE_OWNER)) { 90 return true 91 } 92 93 // Admins can kick normal members 94 if (slices.Contains(senderRoles, protobuf.CommunityMember_ROLE_ADMIN)) && 95 !(slices.Contains(memberRoles, protobuf.CommunityMember_ROLE_ADMIN) || 96 slices.Contains(memberRoles, protobuf.CommunityMember_ROLE_TOKEN_MASTER) || 97 slices.Contains(memberRoles, protobuf.CommunityMember_ROLE_OWNER)) { 98 return true 99 } 100 101 // Normal members can't kick anyone 102 return false 103 } 104 105 func RolesAuthorizedToPerformEvent(senderRoles []protobuf.CommunityMember_Roles, memberRoles []protobuf.CommunityMember_Roles, event *CommunityEvent) bool { 106 if !canRolesPerformEvent(senderRoles, event.Type) { 107 return false 108 } 109 110 if event.Type == protobuf.CommunityEvent_COMMUNITY_MEMBER_TOKEN_PERMISSION_CHANGE || 111 event.Type == protobuf.CommunityEvent_COMMUNITY_MEMBER_TOKEN_PERMISSION_DELETE { 112 return canRolesModifyPermission(senderRoles, event.TokenPermission.Type) 113 } 114 115 if event.Type == protobuf.CommunityEvent_COMMUNITY_MEMBER_BAN || 116 event.Type == protobuf.CommunityEvent_COMMUNITY_MEMBER_KICK || 117 event.Type == protobuf.CommunityEvent_COMMUNITY_MEMBER_UNBAN || 118 event.Type == protobuf.CommunityEvent_COMMUNITY_DELETE_BANNED_MEMBER_MESSAGES { 119 return canRolesKickOrBanMember(senderRoles, memberRoles) 120 } 121 122 return true 123 }