feat(@desktop/permissions): Use permission-check light functions

Light functions are used first in order to reduce the number of calls to blockchain.
If the permission is not met (user is not a member of community/channel member list),
then normal permissions-check function is used.

Issue #14220
This commit is contained in:
Michal Iskierko 2024-05-10 16:33:18 +02:00 committed by Michał Iskierko
parent 9feebbc354
commit 458fdd4938
8 changed files with 60 additions and 31 deletions

View File

@ -92,14 +92,14 @@ proc getMySectionId*(self: Controller): string =
proc asyncCheckPermissionsToJoin*(self: Controller) = proc asyncCheckPermissionsToJoin*(self: Controller) =
if self.delegate.getPermissionsToJoinCheckOngoing(): if self.delegate.getPermissionsToJoinCheckOngoing():
return return
self.communityService.asyncCheckPermissionsToJoin(self.getMySectionId(), addresses = @[]) self.communityService.asyncCheckPermissionsToJoin(self.getMySectionId(), addresses = @[], fullCheck = false)
self.delegate.setPermissionsToJoinCheckOngoing(true) self.delegate.setPermissionsToJoinCheckOngoing(true)
proc asyncCheckAllChannelsPermissions*(self: Controller) = proc asyncCheckAllChannelsPermissions*(self: Controller) =
if self.allChannelsPermissionCheckOngoing: if self.allChannelsPermissionCheckOngoing:
return return
self.allChannelsPermissionCheckOngoing = true self.allChannelsPermissionCheckOngoing = true
self.chatService.asyncCheckAllChannelsPermissions(self.getMySectionId(), addresses = @[]) self.chatService.asyncCheckAllChannelsPermissions(self.getMySectionId(), addresses = @[], fullCheck = false)
self.delegate.setChannelsPermissionsCheckOngoing(true) self.delegate.setChannelsPermissionsCheckOngoing(true)
proc asyncCheckChannelPermissions*(self: Controller, communityId: string, chatId: string) = proc asyncCheckChannelPermissions*(self: Controller, communityId: string, chatId: string) =

View File

@ -404,11 +404,11 @@ proc authenticate*(self: Controller) =
proc getCommunityPublicKeyFromPrivateKey*(self: Controller, communityPrivateKey: string): string = proc getCommunityPublicKeyFromPrivateKey*(self: Controller, communityPrivateKey: string): string =
result = self.communityService.getCommunityPublicKeyFromPrivateKey(communityPrivateKey) result = self.communityService.getCommunityPublicKeyFromPrivateKey(communityPrivateKey)
proc asyncCheckPermissionsToJoin*(self: Controller, communityId: string, addressesToShare: seq[string]) = proc asyncCheckPermissionsToJoin*(self: Controller, communityId: string, addressesToShare: seq[string], fullCheck: bool) =
self.communityService.asyncCheckPermissionsToJoin(communityId, addressesToShare) self.communityService.asyncCheckPermissionsToJoin(communityId, addressesToShare, fullCheck)
proc asyncCheckAllChannelsPermissions*(self: Controller, communityId: string, sharedAddresses: seq[string]) = proc asyncCheckAllChannelsPermissions*(self: Controller, communityId: string, sharedAddresses: seq[string], fullCheck: bool) =
self.chatService.asyncCheckAllChannelsPermissions(communityId, sharedAddresses) self.chatService.asyncCheckAllChannelsPermissions(communityId, sharedAddresses, fullCheck)
proc asyncGetRevealedAccountsForMember*(self: Controller, communityId, memberPubkey: string) = proc asyncGetRevealedAccountsForMember*(self: Controller, communityId, memberPubkey: string) =
self.communityService.asyncGetRevealedAccountsForMember(communityId, memberPubkey) self.communityService.asyncGetRevealedAccountsForMember(communityId, memberPubkey)

View File

@ -858,11 +858,11 @@ method getCommunityPublicKeyFromPrivateKey*(self: Module, communityPrivateKey: s
method checkPermissions*(self: Module, communityId: string, sharedAddresses: seq[string]) = method checkPermissions*(self: Module, communityId: string, sharedAddresses: seq[string]) =
self.joiningCommunityDetails.communityIdForPermissions = communityId self.joiningCommunityDetails.communityIdForPermissions = communityId
self.controller.asyncCheckPermissionsToJoin(communityId, sharedAddresses) self.controller.asyncCheckPermissionsToJoin(communityId, sharedAddresses, fullCheck = true)
self.view.setJoinPermissionsCheckSuccessful(false) self.view.setJoinPermissionsCheckSuccessful(false)
self.setCheckingPermissionToJoinInProgress(true) self.setCheckingPermissionToJoinInProgress(true)
self.controller.asyncCheckAllChannelsPermissions(communityId, sharedAddresses) self.controller.asyncCheckAllChannelsPermissions(communityId, sharedAddresses, fullCheck = true)
self.view.setChannelsPermissionsCheckSuccessful(false) self.view.setChannelsPermissionsCheckSuccessful(false)
self.checkingAllChannelPermissionsInProgress = true self.checkingAllChannelPermissionsInProgress = true

View File

@ -28,7 +28,11 @@ type
const asyncCheckChannelPermissionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = const asyncCheckChannelPermissionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncCheckChannelPermissionsTaskArg](argEncoded) let arg = decode[AsyncCheckChannelPermissionsTaskArg](argEncoded)
try: try:
let response = status_communities.checkCommunityChannelPermissions(arg.communityId, arg.chatId) var response = status_communities.checkCommunityChannelPermissionsLight(arg.communityId, arg.chatId).result
let channelPermissions = response.toCheckChannelPermissionsResponseDto()
if not channelPermissions.viewOnlyPermissions.satisfied and not channelPermissions.viewAndPostPermissions.satisfied:
response = status_communities.checkCommunityChannelPermissions(arg.communityId, arg.chatId).result
arg.finish(%* { arg.finish(%* {
"response": response, "response": response,
"communityId": arg.communityId, "communityId": arg.communityId,
@ -46,13 +50,19 @@ type
AsyncCheckAllChannelsPermissionsTaskArg = ref object of QObjectTaskArg AsyncCheckAllChannelsPermissionsTaskArg = ref object of QObjectTaskArg
communityId: string communityId: string
addresses: seq[string] addresses: seq[string]
fullCheck: bool
const asyncCheckAllChannelsPermissionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = const asyncCheckAllChannelsPermissionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncCheckAllChannelsPermissionsTaskArg](argEncoded) let arg = decode[AsyncCheckAllChannelsPermissionsTaskArg](argEncoded)
try: try:
let response = status_communities.checkAllCommunityChannelsPermissions(arg.communityId, arg.addresses) var result = JsonNode()
if arg.fullCheck:
result = status_communities.checkAllCommunityChannelsPermissions(arg.communityId, arg.addresses).result
else:
result = status_communities.checkAllCommunityChannelsPermissionsLight(arg.communityId).result
let allChannelsPermissions = result.toCheckAllChannelsPermissionsResponseDto()
arg.finish(%* { arg.finish(%* {
"response": response, "response": allChannelsPermissions,
"communityId": arg.communityId, "communityId": arg.communityId,
"error": "", "error": "",
}) })

View File

@ -680,6 +680,7 @@ QtObject:
communityId: communityId, communityId: communityId,
chatId: chatId chatId: chatId
) )
self.threadpool.start(arg) self.threadpool.start(arg)
proc onAsyncCheckChannelPermissionsDone*(self: Service, rpcResponse: string) {.slot.} = proc onAsyncCheckChannelPermissionsDone*(self: Service, rpcResponse: string) {.slot.} =
@ -692,21 +693,22 @@ QtObject:
let communityId = rpcResponseObj{"communityId"}.getStr() let communityId = rpcResponseObj{"communityId"}.getStr()
let chatId = rpcResponseObj{"chatId"}.getStr() let chatId = rpcResponseObj{"chatId"}.getStr()
let checkChannelPermissionsResponse = rpcResponseObj["response"]["result"].toCheckChannelPermissionsResponseDto() let checkChannelPermissionsResponse = rpcResponseObj["response"].toCheckChannelPermissionsResponseDto()
self.events.emit(SIGNAL_CHECK_CHANNEL_PERMISSIONS_RESPONSE, CheckChannelPermissionsResponseArgs(communityId: communityId, chatId: chatId, checkChannelPermissionsResponse: checkChannelPermissionsResponse)) self.events.emit(SIGNAL_CHECK_CHANNEL_PERMISSIONS_RESPONSE, CheckChannelPermissionsResponseArgs(communityId: communityId, chatId: chatId, checkChannelPermissionsResponse: checkChannelPermissionsResponse))
except Exception as e: except Exception as e:
let errMsg = e.msg let errMsg = e.msg
error "error checking all channel permissions: ", errMsg error "error checking all channel permissions: ", errMsg
proc asyncCheckAllChannelsPermissions*(self: Service, communityId: string, addresses: seq[string]) = proc asyncCheckAllChannelsPermissions*(self: Service, communityId: string, addresses: seq[string], fullCheck: bool) =
let arg = AsyncCheckAllChannelsPermissionsTaskArg( let arg = AsyncCheckAllChannelsPermissionsTaskArg(
tptr: cast[ByteAddress](asyncCheckAllChannelsPermissionsTask), tptr: cast[ByteAddress](asyncCheckAllChannelsPermissionsTask),
vptr: cast[ByteAddress](self.vptr), vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncCheckAllChannelsPermissionsDone", slot: "onAsyncCheckAllChannelsPermissionsDone",
communityId: communityId, communityId: communityId,
addresses: addresses, addresses: addresses,
fullCheck: fullCheck
) )
self.threadpool.start(arg) self.threadpool.start(arg)
proc onAsyncCheckAllChannelsPermissionsDone*(self: Service, rpcResponse: string) {.slot.} = proc onAsyncCheckAllChannelsPermissionsDone*(self: Service, rpcResponse: string) {.slot.} =
@ -716,11 +718,7 @@ QtObject:
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "": if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
raise newException(CatchableError, rpcResponseObj["error"].getStr) raise newException(CatchableError, rpcResponseObj["error"].getStr)
if rpcResponseObj["response"]{"error"}.kind != JNull: let checkAllChannelsPermissionsResponse = rpcResponseObj["response"].toCheckAllChannelsPermissionsResponseDto()
let error = Json.decode(rpcResponseObj["response"]["error"].getStr, RpcError)
raise newException(RpcException, error.message)
let checkAllChannelsPermissionsResponse = rpcResponseObj["response"]["result"].toCheckAllChannelsPermissionsResponseDto()
# TODO save it # TODO save it
self.events.emit(SIGNAL_CHECK_ALL_CHANNELS_PERMISSIONS_RESPONSE, CheckAllChannelsPermissionsResponseArgs(communityId: communityId, checkAllChannelsPermissionsResponse: checkAllChannelsPermissionsResponse)) self.events.emit(SIGNAL_CHECK_ALL_CHANNELS_PERMISSIONS_RESPONSE, CheckAllChannelsPermissionsResponseArgs(communityId: communityId, checkAllChannelsPermissionsResponse: checkAllChannelsPermissionsResponse))
except Exception as e: except Exception as e:

View File

@ -209,11 +209,22 @@ type
AsyncCheckPermissionsToJoinTaskArg = ref object of QObjectTaskArg AsyncCheckPermissionsToJoinTaskArg = ref object of QObjectTaskArg
communityId: string communityId: string
addresses: seq[string] addresses: seq[string]
fullCheck: bool
const asyncCheckPermissionsToJoinTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = const asyncCheckPermissionsToJoinTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncCheckPermissionsToJoinTaskArg](argEncoded) let arg = decode[AsyncCheckPermissionsToJoinTaskArg](argEncoded)
try: try:
let response = status_go.checkPermissionsToJoinCommunity(arg.communityId, arg.addresses) var response = JsonNode()
if not arg.fullCheck:
let hasPermissionToJoin = status_go.checkPermissionsToJoinCommunityLight(arg.communityId, arg.addresses).result.getBool
if hasPermissionToJoin:
let permissionToJoin = CheckPermissionsToJoinResponseDto(satisfied: true)
response = %permissionToJoin
else:
response = status_go.checkPermissionsToJoinCommunity(arg.communityId, arg.addresses).result
else:
response = status_go.checkPermissionsToJoinCommunity(arg.communityId, arg.addresses).result
arg.finish(%* { arg.finish(%* {
"response": response, "response": response,
"communityId": arg.communityId, "communityId": arg.communityId,

View File

@ -242,10 +242,6 @@ const SIGNAL_ACCEPT_REQUEST_TO_JOIN_LOADING* = "acceptRequestToJoinLoading"
const SIGNAL_ACCEPT_REQUEST_TO_JOIN_FAILED* = "acceptRequestToJoinFailed" const SIGNAL_ACCEPT_REQUEST_TO_JOIN_FAILED* = "acceptRequestToJoinFailed"
const SIGNAL_ACCEPT_REQUEST_TO_JOIN_FAILED_NO_PERMISSION* = "acceptRequestToJoinFailedNoPermission" const SIGNAL_ACCEPT_REQUEST_TO_JOIN_FAILED_NO_PERMISSION* = "acceptRequestToJoinFailedNoPermission"
const TOKEN_PERMISSIONS_ADDED = "tokenPermissionsAdded"
const TOKEN_PERMISSIONS_MODIFIED = "tokenPermissionsModified"
const TOKEN_PERMISSIONS_REMOVED = "tokenPermissionsRemoved"
const SIGNAL_CHECK_PERMISSIONS_TO_JOIN_RESPONSE* = "checkPermissionsToJoinResponse" const SIGNAL_CHECK_PERMISSIONS_TO_JOIN_RESPONSE* = "checkPermissionsToJoinResponse"
const SIGNAL_CHECK_PERMISSIONS_TO_JOIN_FAILED* = "checkPermissionsToJoinFailed" const SIGNAL_CHECK_PERMISSIONS_TO_JOIN_FAILED* = "checkPermissionsToJoinFailed"
@ -1617,13 +1613,14 @@ QtObject:
self.events.emit(SIGNAL_COMMUNITY_DATA_IMPORTED, CommunityArgs(community: community)) self.events.emit(SIGNAL_COMMUNITY_DATA_IMPORTED, CommunityArgs(community: community))
self.events.emit(SIGNAL_COMMUNITIES_UPDATE, CommunitiesArgs(communities: @[community])) self.events.emit(SIGNAL_COMMUNITIES_UPDATE, CommunitiesArgs(communities: @[community]))
proc asyncCheckPermissionsToJoin*(self: Service, communityId: string, addresses: seq[string]) = proc asyncCheckPermissionsToJoin*(self: Service, communityId: string, addresses: seq[string], fullCheck: bool) =
let arg = AsyncCheckPermissionsToJoinTaskArg( let arg = AsyncCheckPermissionsToJoinTaskArg(
tptr: cast[ByteAddress](asyncCheckPermissionsToJoinTask), tptr: cast[ByteAddress](asyncCheckPermissionsToJoinTask),
vptr: cast[ByteAddress](self.vptr), vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncCheckPermissionsToJoinDone", slot: "onAsyncCheckPermissionsToJoinDone",
communityId: communityId, communityId: communityId,
addresses: addresses addresses: addresses,
fullCheck: fullCheck
) )
self.threadpool.start(arg) self.threadpool.start(arg)
@ -1634,11 +1631,7 @@ QtObject:
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "": if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
raise newException(CatchableError, rpcResponseObj["error"].getStr) raise newException(CatchableError, rpcResponseObj["error"].getStr)
if rpcResponseObj["response"]{"error"}.kind != JNull: let checkPermissionsToJoinResponse = rpcResponseObj["response"].toCheckPermissionsToJoinResponseDto
let error = Json.decode(rpcResponseObj["response"]["error"].getStr, RpcError)
raise newException(RpcException, error.message)
let checkPermissionsToJoinResponse = rpcResponseObj["response"]["result"].toCheckPermissionsToJoinResponseDto
self.events.emit(SIGNAL_CHECK_PERMISSIONS_TO_JOIN_RESPONSE, CheckPermissionsToJoinResponseArgs( self.events.emit(SIGNAL_CHECK_PERMISSIONS_TO_JOIN_RESPONSE, CheckPermissionsToJoinResponseArgs(
communityId: communityId, communityId: communityId,
checkPermissionsToJoinResponse: checkPermissionsToJoinResponse checkPermissionsToJoinResponse: checkPermissionsToJoinResponse

View File

@ -103,6 +103,12 @@ proc checkPermissionsToJoinCommunity*(communityId: string, addresses: seq[string
"addresses": addresses "addresses": addresses
}]) }])
proc checkPermissionsToJoinCommunityLight*(communityId: string, addresses: seq[string]): RpcResponse[JsonNode] =
result = callPrivateRPC("checkPermissionsToJoinCommunityLight".prefix, %*[{
"communityId": communityId,
"addresses": addresses
}])
proc reevaluateCommunityMembersPermissions*( proc reevaluateCommunityMembersPermissions*(
communityId: string, communityId: string,
): RpcResponse[JsonNode] = ): RpcResponse[JsonNode] =
@ -122,6 +128,17 @@ proc checkAllCommunityChannelsPermissions*(communityId: string, addresses: seq[s
"addresses": addresses, "addresses": addresses,
}]) }])
proc checkCommunityChannelPermissionsLight*(communityId: string, chatId: string): RpcResponse[JsonNode] =
result = callPrivateRPC("checkCommunityChannelPermissionsLight".prefix, %*[{
"communityId": communityId,
"chatId": chatId
}])
proc checkAllCommunityChannelsPermissionsLight*(communityId: string): RpcResponse[JsonNode] =
result = callPrivateRPC("checkAllCommunityChannelsPermissionsLight".prefix, %*[{
"communityId": communityId
}])
proc allNonApprovedCommunitiesRequestsToJoin*(): RpcResponse[JsonNode] = proc allNonApprovedCommunitiesRequestsToJoin*(): RpcResponse[JsonNode] =
result = callPrivateRPC("allNonApprovedCommunitiesRequestsToJoin".prefix) result = callPrivateRPC("allNonApprovedCommunitiesRequestsToJoin".prefix)