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) =
if self.delegate.getPermissionsToJoinCheckOngoing():
return
self.communityService.asyncCheckPermissionsToJoin(self.getMySectionId(), addresses = @[])
self.communityService.asyncCheckPermissionsToJoin(self.getMySectionId(), addresses = @[], fullCheck = false)
self.delegate.setPermissionsToJoinCheckOngoing(true)
proc asyncCheckAllChannelsPermissions*(self: Controller) =
if self.allChannelsPermissionCheckOngoing:
return
self.allChannelsPermissionCheckOngoing = true
self.chatService.asyncCheckAllChannelsPermissions(self.getMySectionId(), addresses = @[])
self.chatService.asyncCheckAllChannelsPermissions(self.getMySectionId(), addresses = @[], fullCheck = false)
self.delegate.setChannelsPermissionsCheckOngoing(true)
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 =
result = self.communityService.getCommunityPublicKeyFromPrivateKey(communityPrivateKey)
proc asyncCheckPermissionsToJoin*(self: Controller, communityId: string, addressesToShare: seq[string]) =
self.communityService.asyncCheckPermissionsToJoin(communityId, addressesToShare)
proc asyncCheckPermissionsToJoin*(self: Controller, communityId: string, addressesToShare: seq[string], fullCheck: bool) =
self.communityService.asyncCheckPermissionsToJoin(communityId, addressesToShare, fullCheck)
proc asyncCheckAllChannelsPermissions*(self: Controller, communityId: string, sharedAddresses: seq[string]) =
self.chatService.asyncCheckAllChannelsPermissions(communityId, sharedAddresses)
proc asyncCheckAllChannelsPermissions*(self: Controller, communityId: string, sharedAddresses: seq[string], fullCheck: bool) =
self.chatService.asyncCheckAllChannelsPermissions(communityId, sharedAddresses, fullCheck)
proc asyncGetRevealedAccountsForMember*(self: Controller, communityId, memberPubkey: string) =
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]) =
self.joiningCommunityDetails.communityIdForPermissions = communityId
self.controller.asyncCheckPermissionsToJoin(communityId, sharedAddresses)
self.controller.asyncCheckPermissionsToJoin(communityId, sharedAddresses, fullCheck = true)
self.view.setJoinPermissionsCheckSuccessful(false)
self.setCheckingPermissionToJoinInProgress(true)
self.controller.asyncCheckAllChannelsPermissions(communityId, sharedAddresses)
self.controller.asyncCheckAllChannelsPermissions(communityId, sharedAddresses, fullCheck = true)
self.view.setChannelsPermissionsCheckSuccessful(false)
self.checkingAllChannelPermissionsInProgress = true

View File

@ -28,7 +28,11 @@ type
const asyncCheckChannelPermissionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncCheckChannelPermissionsTaskArg](argEncoded)
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(%* {
"response": response,
"communityId": arg.communityId,
@ -46,13 +50,19 @@ type
AsyncCheckAllChannelsPermissionsTaskArg = ref object of QObjectTaskArg
communityId: string
addresses: seq[string]
fullCheck: bool
const asyncCheckAllChannelsPermissionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncCheckAllChannelsPermissionsTaskArg](argEncoded)
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(%* {
"response": response,
"response": allChannelsPermissions,
"communityId": arg.communityId,
"error": "",
})

View File

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

View File

@ -209,11 +209,22 @@ type
AsyncCheckPermissionsToJoinTaskArg = ref object of QObjectTaskArg
communityId: string
addresses: seq[string]
fullCheck: bool
const asyncCheckPermissionsToJoinTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncCheckPermissionsToJoinTaskArg](argEncoded)
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(%* {
"response": response,
"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_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_FAILED* = "checkPermissionsToJoinFailed"
@ -1617,13 +1613,14 @@ QtObject:
self.events.emit(SIGNAL_COMMUNITY_DATA_IMPORTED, CommunityArgs(community: 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(
tptr: cast[ByteAddress](asyncCheckPermissionsToJoinTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncCheckPermissionsToJoinDone",
communityId: communityId,
addresses: addresses
addresses: addresses,
fullCheck: fullCheck
)
self.threadpool.start(arg)
@ -1634,11 +1631,7 @@ QtObject:
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
raise newException(CatchableError, rpcResponseObj["error"].getStr)
if rpcResponseObj["response"]{"error"}.kind != JNull:
let error = Json.decode(rpcResponseObj["response"]["error"].getStr, RpcError)
raise newException(RpcException, error.message)
let checkPermissionsToJoinResponse = rpcResponseObj["response"]["result"].toCheckPermissionsToJoinResponseDto
let checkPermissionsToJoinResponse = rpcResponseObj["response"].toCheckPermissionsToJoinResponseDto
self.events.emit(SIGNAL_CHECK_PERMISSIONS_TO_JOIN_RESPONSE, CheckPermissionsToJoinResponseArgs(
communityId: communityId,
checkPermissionsToJoinResponse: checkPermissionsToJoinResponse

View File

@ -103,6 +103,12 @@ proc checkPermissionsToJoinCommunity*(communityId: string, addresses: seq[string
"addresses": addresses
}])
proc checkPermissionsToJoinCommunityLight*(communityId: string, addresses: seq[string]): RpcResponse[JsonNode] =
result = callPrivateRPC("checkPermissionsToJoinCommunityLight".prefix, %*[{
"communityId": communityId,
"addresses": addresses
}])
proc reevaluateCommunityMembersPermissions*(
communityId: string,
): RpcResponse[JsonNode] =
@ -122,6 +128,17 @@ proc checkAllCommunityChannelsPermissions*(communityId: string, addresses: seq[s
"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] =
result = callPrivateRPC("allNonApprovedCommunitiesRequestsToJoin".prefix)