mirror of
https://github.com/status-im/status-go.git
synced 2025-02-16 16:56:53 +00:00
feat_: light, no-network versions of permission checking functions
Light functions are based on the fact that permissions are met if the user is on community/channel member list. If the user is not on the list, permissions will not be met and the client is responsible to use regular permissions-check functions. For all permissions-check functions, corresponding light versions are added: CheckAllChannelsPermissionsLight, CheckChannelPermissionsLight, CheckPermissionToJoinLight. Issue #14220
This commit is contained in:
parent
20d3a7b69b
commit
6f1b82966a
@ -2527,6 +2527,17 @@ func (m *Manager) CheckPermissionToJoin(id []byte, addresses []gethcommon.Addres
|
|||||||
return m.PermissionChecker.CheckPermissionToJoin(community, addresses)
|
return m.PermissionChecker.CheckPermissionToJoin(community, addresses)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Light version of CheckPermissionToJoin, which does not use network requests.
|
||||||
|
// Instead of checking wallet balances it checks if there is an access to a member list of the community.
|
||||||
|
func (m *Manager) CheckPermissionToJoinLight(id []byte) (bool, error) {
|
||||||
|
community, err := m.GetByID(id)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
meAsMember := community.GetMember(&m.identity.PublicKey)
|
||||||
|
return meAsMember != nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) accountsSatisfyPermissionsToJoin(
|
func (m *Manager) accountsSatisfyPermissionsToJoin(
|
||||||
communityPermissionsPreParsedData map[protobuf.CommunityTokenPermission_Type]*PreParsedCommunityPermissionsData,
|
communityPermissionsPreParsedData map[protobuf.CommunityTokenPermission_Type]*PreParsedCommunityPermissionsData,
|
||||||
accountsAndChainIDs []*AccountChainIDsCombination) (bool, protobuf.CommunityMember_Roles, error) {
|
accountsAndChainIDs []*AccountChainIDsCombination) (bool, protobuf.CommunityMember_Roles, error) {
|
||||||
@ -3099,6 +3110,59 @@ func (m *Manager) CheckChannelPermissions(communityID types.HexBytes, chatID str
|
|||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Manager) checkChannelPermissionsLight(community *Community, communityChat *protobuf.CommunityChat, channelID string) *CheckChannelPermissionsResponse {
|
||||||
|
|
||||||
|
viewOnlyPermissions := community.ChannelTokenPermissionsByType(community.IDString()+channelID, protobuf.CommunityTokenPermission_CAN_VIEW_CHANNEL)
|
||||||
|
viewAndPostPermissions := community.ChannelTokenPermissionsByType(community.IDString()+channelID, protobuf.CommunityTokenPermission_CAN_VIEW_AND_POST_CHANNEL)
|
||||||
|
|
||||||
|
hasViewOnlyPermissions := len(viewOnlyPermissions) > 0
|
||||||
|
hasViewAndPostPermissions := len(viewAndPostPermissions) > 0
|
||||||
|
|
||||||
|
meAsMember := communityChat.Members[common.PubkeyToHex(&m.identity.PublicKey)]
|
||||||
|
|
||||||
|
viewSatisfied := !hasViewOnlyPermissions || (meAsMember != nil && meAsMember.GetChannelRole() == protobuf.CommunityMember_CHANNEL_ROLE_VIEWER)
|
||||||
|
postSatisfied := !hasViewAndPostPermissions || (meAsMember != nil && meAsMember.GetChannelRole() == protobuf.CommunityMember_CHANNEL_ROLE_POSTER)
|
||||||
|
|
||||||
|
finalViewSatisfied := m.computeViewOnlySatisfied(hasViewOnlyPermissions, hasViewAndPostPermissions, viewSatisfied, postSatisfied)
|
||||||
|
finalPostSatisfied := m.computeViewAndPostSatisfied(hasViewOnlyPermissions, hasViewAndPostPermissions, postSatisfied)
|
||||||
|
|
||||||
|
return &CheckChannelPermissionsResponse{
|
||||||
|
ViewOnlyPermissions: &CheckChannelViewOnlyPermissionsResult{
|
||||||
|
Satisfied: finalViewSatisfied,
|
||||||
|
Permissions: make(map[string]*PermissionTokenCriteriaResult),
|
||||||
|
},
|
||||||
|
ViewAndPostPermissions: &CheckChannelViewAndPostPermissionsResult{
|
||||||
|
Satisfied: finalPostSatisfied,
|
||||||
|
Permissions: make(map[string]*PermissionTokenCriteriaResult),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Light version of CheckChannelPermissions, which does not use network requests.
|
||||||
|
// Instead of checking wallet balances it checks if there is an access to a member list of the chat.
|
||||||
|
func (m *Manager) CheckChannelPermissionsLight(communityID types.HexBytes, chatID string) (*CheckChannelPermissionsResponse, error) {
|
||||||
|
community, err := m.GetByID(communityID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove communityID prefix from chatID if exists
|
||||||
|
if strings.HasPrefix(chatID, communityID.String()) {
|
||||||
|
chatID = strings.TrimPrefix(chatID, communityID.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if chatID == "" {
|
||||||
|
return nil, errors.New(fmt.Sprintf("couldn't check channel permissions, invalid chat id: %s", chatID))
|
||||||
|
}
|
||||||
|
|
||||||
|
communityChat, err := community.GetChat(chatID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.checkChannelPermissionsLight(community, communityChat, chatID), nil
|
||||||
|
}
|
||||||
|
|
||||||
type CheckChannelPermissionsResponse struct {
|
type CheckChannelPermissionsResponse struct {
|
||||||
ViewOnlyPermissions *CheckChannelViewOnlyPermissionsResult `json:"viewOnlyPermissions"`
|
ViewOnlyPermissions *CheckChannelViewOnlyPermissionsResult `json:"viewOnlyPermissions"`
|
||||||
ViewAndPostPermissions *CheckChannelViewAndPostPermissionsResult `json:"viewAndPostPermissions"`
|
ViewAndPostPermissions *CheckChannelViewAndPostPermissionsResult `json:"viewAndPostPermissions"`
|
||||||
@ -3114,6 +3178,22 @@ type CheckChannelViewAndPostPermissionsResult struct {
|
|||||||
Permissions map[string]*PermissionTokenCriteriaResult `json:"permissions"`
|
Permissions map[string]*PermissionTokenCriteriaResult `json:"permissions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Manager) computeViewOnlySatisfied(hasViewOnlyPermissions bool, hasViewAndPostPermissions bool, checkedViewOnlySatisfied bool, checkedViewAndPostSatisified bool) bool {
|
||||||
|
if (hasViewAndPostPermissions && !hasViewOnlyPermissions) || (hasViewOnlyPermissions && hasViewAndPostPermissions && checkedViewAndPostSatisified) {
|
||||||
|
return checkedViewAndPostSatisified
|
||||||
|
} else {
|
||||||
|
return checkedViewOnlySatisfied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) computeViewAndPostSatisfied(hasViewOnlyPermissions bool, hasViewAndPostPermissions bool, checkedViewAndPostSatisified bool) bool {
|
||||||
|
if hasViewOnlyPermissions && !hasViewAndPostPermissions {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return checkedViewAndPostSatisified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) checkChannelPermissions(viewOnlyPreParsedPermissions *PreParsedCommunityPermissionsData, viewAndPostPreParsedPermissions *PreParsedCommunityPermissionsData, accountsAndChainIDs []*AccountChainIDsCombination, shortcircuit bool) (*CheckChannelPermissionsResponse, error) {
|
func (m *Manager) checkChannelPermissions(viewOnlyPreParsedPermissions *PreParsedCommunityPermissionsData, viewAndPostPreParsedPermissions *PreParsedCommunityPermissionsData, accountsAndChainIDs []*AccountChainIDsCombination, shortcircuit bool) (*CheckChannelPermissionsResponse, error) {
|
||||||
|
|
||||||
response := &CheckChannelPermissionsResponse{
|
response := &CheckChannelPermissionsResponse{
|
||||||
@ -3140,18 +3220,10 @@ func (m *Manager) checkChannelPermissions(viewOnlyPreParsedPermissions *PreParse
|
|||||||
hasViewOnlyPermissions := viewOnlyPreParsedPermissions != nil
|
hasViewOnlyPermissions := viewOnlyPreParsedPermissions != nil
|
||||||
hasViewAndPostPermissions := viewAndPostPreParsedPermissions != nil
|
hasViewAndPostPermissions := viewAndPostPreParsedPermissions != nil
|
||||||
|
|
||||||
if (hasViewAndPostPermissions && !hasViewOnlyPermissions) || (hasViewOnlyPermissions && hasViewAndPostPermissions && viewAndPostPermissionsResponse.Satisfied) {
|
response.ViewOnlyPermissions.Satisfied = m.computeViewOnlySatisfied(hasViewOnlyPermissions, hasViewAndPostPermissions, viewOnlyPermissionsResponse.Satisfied, viewAndPostPermissionsResponse.Satisfied)
|
||||||
response.ViewOnlyPermissions.Satisfied = viewAndPostPermissionsResponse.Satisfied
|
|
||||||
} else {
|
|
||||||
response.ViewOnlyPermissions.Satisfied = viewOnlyPermissionsResponse.Satisfied
|
|
||||||
}
|
|
||||||
response.ViewOnlyPermissions.Permissions = viewOnlyPermissionsResponse.Permissions
|
response.ViewOnlyPermissions.Permissions = viewOnlyPermissionsResponse.Permissions
|
||||||
|
|
||||||
if hasViewOnlyPermissions && !hasViewAndPostPermissions {
|
response.ViewAndPostPermissions.Satisfied = m.computeViewAndPostSatisfied(hasViewOnlyPermissions, hasViewAndPostPermissions, viewAndPostPermissionsResponse.Satisfied)
|
||||||
response.ViewAndPostPermissions.Satisfied = false
|
|
||||||
} else {
|
|
||||||
response.ViewAndPostPermissions.Satisfied = viewAndPostPermissionsResponse.Satisfied
|
|
||||||
}
|
|
||||||
response.ViewAndPostPermissions.Permissions = viewAndPostPermissionsResponse.Permissions
|
response.ViewAndPostPermissions.Permissions = viewAndPostPermissionsResponse.Permissions
|
||||||
|
|
||||||
return response, nil
|
return response, nil
|
||||||
@ -3194,6 +3266,27 @@ func (m *Manager) CheckAllChannelsPermissions(communityID types.HexBytes, addres
|
|||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Light version of CheckAllChannelsPermissionsLight, which does not use network requests.
|
||||||
|
// Instead of checking wallet balances it checks if there is an access to a member list of chats.
|
||||||
|
func (m *Manager) CheckAllChannelsPermissionsLight(communityID types.HexBytes) (*CheckAllChannelsPermissionsResponse, error) {
|
||||||
|
|
||||||
|
community, err := m.GetByID(communityID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &CheckAllChannelsPermissionsResponse{
|
||||||
|
Channels: make(map[string]*CheckChannelPermissionsResponse),
|
||||||
|
}
|
||||||
|
|
||||||
|
channels := community.Chats()
|
||||||
|
|
||||||
|
for channelID, channel := range channels {
|
||||||
|
response.Channels[community.IDString()+channelID] = m.checkChannelPermissionsLight(community, channel, channelID)
|
||||||
|
}
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) GetCheckChannelPermissionResponses(communityID types.HexBytes) (*CheckAllChannelsPermissionsResponse, error) {
|
func (m *Manager) GetCheckChannelPermissionResponses(communityID types.HexBytes) (*CheckAllChannelsPermissionsResponse, error) {
|
||||||
|
|
||||||
response, err := m.persistence.GetCheckChannelPermissionResponses(communityID.String())
|
response, err := m.persistence.GetCheckChannelPermissionResponses(communityID.String())
|
||||||
|
@ -4322,6 +4322,14 @@ func (m *Messenger) CheckPermissionsToJoinCommunity(request *requests.CheckPermi
|
|||||||
return m.communitiesManager.CheckPermissionToJoin(request.CommunityID, addresses)
|
return m.communitiesManager.CheckPermissionToJoin(request.CommunityID, addresses)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) CheckPermissionsToJoinCommunityLight(request *requests.CheckPermissionToJoinCommunity) (bool, error) {
|
||||||
|
if err := request.Validate(); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.communitiesManager.CheckPermissionToJoinLight(request.CommunityID)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Messenger) getSharedAddresses(communityID types.HexBytes, requestAddresses []string) ([]gethcommon.Address, error) {
|
func (m *Messenger) getSharedAddresses(communityID types.HexBytes, requestAddresses []string) ([]gethcommon.Address, error) {
|
||||||
addressesMap := make(map[string]struct{})
|
addressesMap := make(map[string]struct{})
|
||||||
|
|
||||||
@ -4385,6 +4393,22 @@ func (m *Messenger) CheckAllCommunityChannelsPermissions(request *requests.Check
|
|||||||
return m.communitiesManager.CheckAllChannelsPermissions(request.CommunityID, addresses)
|
return m.communitiesManager.CheckAllChannelsPermissions(request.CommunityID, addresses)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) CheckCommunityChannelPermissionsLight(request *requests.CheckCommunityChannelPermissions) (*communities.CheckChannelPermissionsResponse, error) {
|
||||||
|
if err := request.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.communitiesManager.CheckChannelPermissionsLight(request.CommunityID, request.ChatID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) CheckAllCommunityChannelsPermissionsLight(request *requests.CheckAllCommunityChannelsPermissions) (*communities.CheckAllChannelsPermissionsResponse, error) {
|
||||||
|
if err := request.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.communitiesManager.CheckAllChannelsPermissionsLight(request.CommunityID)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Messenger) GetCommunityCheckChannelPermissionResponses(communityID types.HexBytes) (*communities.CheckAllChannelsPermissionsResponse, error) {
|
func (m *Messenger) GetCommunityCheckChannelPermissionResponses(communityID types.HexBytes) (*communities.CheckAllChannelsPermissionsResponse, error) {
|
||||||
return m.communitiesManager.GetCheckChannelPermissionResponses(communityID)
|
return m.communitiesManager.GetCheckChannelPermissionResponses(communityID)
|
||||||
}
|
}
|
||||||
|
@ -1590,14 +1590,26 @@ func (api *PublicAPI) CheckPermissionsToJoinCommunity(request *requests.CheckPer
|
|||||||
return api.service.messenger.CheckPermissionsToJoinCommunity(request)
|
return api.service.messenger.CheckPermissionsToJoinCommunity(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *PublicAPI) CheckPermissionsToJoinCommunityLight(request *requests.CheckPermissionToJoinCommunity) (bool, error) {
|
||||||
|
return api.service.messenger.CheckPermissionsToJoinCommunityLight(request)
|
||||||
|
}
|
||||||
|
|
||||||
func (api *PublicAPI) CheckCommunityChannelPermissions(request *requests.CheckCommunityChannelPermissions) (*communities.CheckChannelPermissionsResponse, error) {
|
func (api *PublicAPI) CheckCommunityChannelPermissions(request *requests.CheckCommunityChannelPermissions) (*communities.CheckChannelPermissionsResponse, error) {
|
||||||
return api.service.messenger.CheckCommunityChannelPermissions(request)
|
return api.service.messenger.CheckCommunityChannelPermissions(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *PublicAPI) CheckCommunityChannelPermissionsLight(request *requests.CheckCommunityChannelPermissions) (*communities.CheckChannelPermissionsResponse, error) {
|
||||||
|
return api.service.messenger.CheckCommunityChannelPermissionsLight(request)
|
||||||
|
}
|
||||||
|
|
||||||
func (api *PublicAPI) CheckAllCommunityChannelsPermissions(request *requests.CheckAllCommunityChannelsPermissions) (*communities.CheckAllChannelsPermissionsResponse, error) {
|
func (api *PublicAPI) CheckAllCommunityChannelsPermissions(request *requests.CheckAllCommunityChannelsPermissions) (*communities.CheckAllChannelsPermissionsResponse, error) {
|
||||||
return api.service.messenger.CheckAllCommunityChannelsPermissions(request)
|
return api.service.messenger.CheckAllCommunityChannelsPermissions(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *PublicAPI) CheckAllCommunityChannelsPermissionsLight(request *requests.CheckAllCommunityChannelsPermissions) (*communities.CheckAllChannelsPermissionsResponse, error) {
|
||||||
|
return api.service.messenger.CheckAllCommunityChannelsPermissionsLight(request)
|
||||||
|
}
|
||||||
|
|
||||||
func (api *PublicAPI) CollectCommunityMetrics(request *requests.CommunityMetricsRequest) (*protocol.CommunityMetricsResponse, error) {
|
func (api *PublicAPI) CollectCommunityMetrics(request *requests.CommunityMetricsRequest) (*protocol.CommunityMetricsResponse, error) {
|
||||||
return api.service.messenger.CollectCommunityMetrics(request)
|
return api.service.messenger.CollectCommunityMetrics(request)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user