refactor: provider pt1 and dapp permissions service

This commit is contained in:
Richard Ramos 2021-10-21 10:46:24 -04:00 committed by Iuri Matias
parent 1d0b20b156
commit c0d87dd063
24 changed files with 387 additions and 52 deletions

View File

@ -11,6 +11,7 @@ import ../../app_service/service/collectible/service as collectible_service
import ../../app_service/service/wallet_account/service as wallet_account_service
import ../../app_service/service/setting/service as setting_service
import ../../app_service/service/bookmarks/service as bookmark_service
import ../../app_service/service/dapp_permissions/service as dapp_permissions_service
import ../core/local_account_settings
import ../../app_service/service/profile/service as profile_service
@ -70,6 +71,7 @@ type
walletAccountService: wallet_account_service.Service
settingService: setting_service.Service
bookmarkService: bookmark_service.Service
dappPermissionsService: dapp_permissions_service.Service
profileService: profile_service.Service
settingsService: settings_service.Service
aboutService: about_service.Service
@ -130,6 +132,7 @@ proc newAppController*(appService: AppService): AppController =
result.profileService = profile_service.newService()
result.settingsService = settings_service.newService()
result.aboutService = about_service.newService()
result.dappPermissionsService = dapp_permissions_service.newService()
# Core
result.localAppSettingsVariant = newQVariant(singletonInstance.localAppSettings)
@ -160,6 +163,7 @@ proc newAppController*(appService: AppService): AppController =
result.settingsService,
result.contactsService,
result.aboutService,
result.dappPermissionsService,
)
#################################################
@ -208,6 +212,7 @@ proc delete*(self: AppController) =
self.settingService.delete
self.walletAccountService.delete
self.aboutService.delete
self.dappPermissionsService.delete
proc startupDidLoad*(self: AppController) =
#################################################
@ -249,6 +254,7 @@ proc load*(self: AppController) =
self.communityService.init()
self.bookmarkService.init()
self.tokenService.init()
self.dappPermissionsService.init()
self.walletAccountService.init()
self.transactionService.init()
self.mainModule.load()

View File

@ -17,7 +17,7 @@ type
moduleLoaded: bool
controller: controller.AccessInterface
proc newModule*(delegate: delegate_interface.AccessInterface, bookmarkService: bookmark_service.Service): Module =
proc newModule*(delegate: delegate_interface.AccessInterface, bookmarkService: bookmark_service.ServiceInterface): Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)

View File

@ -6,7 +6,7 @@ import ../../../core/global_singleton
import provider/module as provider_module
import bookmark/module as bookmark_module
import ../../../../app_service/service/bookmarks/service as bookmark_service
import ../../../../app_service/service/settings/service as settings_service
export io_interface
type
@ -18,13 +18,13 @@ type
providerModule: provider_module.AccessInterface
bookmarkModule: bookmark_module.AccessInterface
proc newModule*(delegate: delegate_interface.AccessInterface, bookmarkService: bookmark_service.Service): Module =
proc newModule*(delegate: delegate_interface.AccessInterface, bookmarkService: bookmark_service.ServiceInterface, settingsService: settings_service.ServiceInterface): Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.moduleLoaded = false
result.providerModule = provider_module.newModule(result)
result.providerModule = provider_module.newModule(result, settingsService)
result.bookmarkModule = bookmark_module.newModule(result, bookmarkService)
method delete*(self: Module) =

View File

@ -0,0 +1,36 @@
import Tables
import result
import controller_interface
import io_interface
import ../../../../../app_service/service/settings/service as settings_service
export controller_interface
type
Controller* = ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface
settingsService: settings_service.ServiceInterface
proc newController*(delegate: io_interface.AccessInterface,
settingsService: settings_service.ServiceInterface):
Controller =
result = Controller()
result.delegate = delegate
result.settingsService = settingsService
method delete*(self: Controller) =
discard
method init*(self: Controller) =
discard
method getDappsAddress*(self: Controller): string =
return self.settingsService.getDappsAddress()
method setDappsAddress*(self: Controller, address: string) =
if self.settingsService.setDappsAddress(address):
self.delegate.onDappAddressChanged(address)
method getCurrentNetworkDetails*(self: Controller): NetworkDetails =
return self.settingsService.getCurrentNetworkDetails()

View File

@ -0,0 +1,20 @@
import ../../../../../app_service/service/settings/service as settings_service
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for any input/interaction with this module.
method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method init*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getDappsAddress*(self: AccessInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method setDappsAddress*(self: AccessInterface, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method getCurrentNetworkDetails*(self: AccessInterface): NetworkDetails {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -4,3 +4,6 @@ include ./private_interfaces/module_access_interface
# Defines how this module view communicates with this module
include ./private_interfaces/module_view_delegate_interface
# Defines how this controller communicates with this module
include ./private_interfaces/module_controller_delegate_interface

View File

@ -1,25 +1,46 @@
import io_interface, view
import NimQml
import io_interface
import view
import controller
import ../io_interface as delegate_interface
import ../../../../../app_service/service/settings/service as settings_service
import ../../../../core/global_singleton
export io_interface
type
Module* = ref object of io_interface.AccessInterface
delegate: delegate_interface.AccessInterface
view: View
viewVariant: QVariant
moduleLoaded: bool
controller: controller.AccessInterface
proc newModule*(delegate: delegate_interface.AccessInterface): Module =
proc newModule*(delegate: delegate_interface.AccessInterface, settingsService: settings_service.ServiceInterface): Module =
result = Module()
result.delegate = delegate
result.view = newView(result)
result.viewVariant = newQVariant(result.view)
result.moduleLoaded = false
result.controller = controller.newController(result, settingsService)
method delete*(self: Module) =
self.controller.delete
self.viewVariant.delete
self.view.delete
method load*(self: Module) =
singletonInstance.engine.setRootContextProperty("providerModule", self.viewVariant)
self.view.load()
self.view.dappsAddress = self.controller.getDappsAddress()
self.view.networkId = self.controller.getCurrentNetworkDetails().config.networkId
self.moduleLoaded = true
self.delegate.providerDidLoad()
method isLoaded*(self: Module): bool =
return self.moduleLoaded
method setDappsAddress*(self: Module, value: string) =
self.controller.setDappsAddress(value)
method onDappAddressChanged*(self: Module, value: string) =
self.view.dappsAddress = value

View File

@ -0,0 +1,5 @@
method setDappsAddress*(self: AccessInterface, newDappAddress: string) =
raise newException(ValueError, "No implementation available")
method onDappAddressChanged*(self: AccessInterface, newDappAddress: string) =
raise newException(ValueError, "No implementation available")

View File

@ -6,6 +6,8 @@ QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
dappsAddress: string
networkId: int
proc delete*(self: View) =
self.QObject.delete
@ -14,4 +16,43 @@ QtObject:
new(result, delete)
result.QObject.setup
result.delegate = delegate
proc load*(self: View) =
self.delegate.viewDidLoad()
proc dappsAddressChanged(self: View, value: string) {.signal.}
proc `dappsAddress=`*(self: View, value: string) =
self.dappsAddress = value
self.dappsAddressChanged(value)
proc dappsAddress*(self: View): string {.slot.} =
result = self.dappsAddress
proc setDappsAddress(self: View, value: string) {.slot.} =
self.delegate.setDappsAddress(value)
QtProperty[string] dappsAddress:
read = dappsAddress
write = setDappsAddress
notify = dappsAddressChanged
proc networkIdChanged(self: View, networkId: int) {.signal.}
proc `networkId=`*(self: View, value: int) =
self.networkId = value
self.networkIdChanged(value)
proc networkId*(self: View): int {.slot.} =
result = self.networkId
QtProperty[string] networkId:
read = networkId
notify = networkIdChanged
proc replaceHostByENS*(self: View, url: string, ens: string): string {.slot.} =
result = url_replaceHostAndAddPath(url, ens)
proc getHost*(self: View, url: string): string {.slot.} =
result = url_host(url)

View File

@ -18,6 +18,7 @@ import ../../../app_service/service/collectible/service as collectible_service
import ../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../app_service/service/setting/service as setting_service
import ../../../app_service/service/bookmarks/service as bookmark_service
import ../../../app_service/service/dapp_permissions/service as dapp_permissions_service
import eventemitter
import ../../../app_service/service/profile/service as profile_service
@ -62,12 +63,13 @@ proc newModule*[T](
transactionService: transaction_service.Service,
collectibleService: collectible_service.Service,
walletAccountService: wallet_account_service.Service,
bookmarkService: bookmark_service.Service,
bookmarkService: bookmark_service.ServiceInterface,
settingService: setting_service.Service,
profileService: profile_service.ServiceInterface,
settingsService: settings_service.ServiceInterface,
contactsService: contacts_service.ServiceInterface,
aboutService: about_service.ServiceInterface
aboutService: about_service.ServiceInterface,
dappPermissionsService: dapp_permissions_service.ServiceInterface,
): Module[T] =
result = Module[T]()
result.delegate = delegate
@ -97,7 +99,7 @@ proc newModule*[T](
settingService
)
result.browserSectionModule = browser_section_module.newModule(result, bookmarkService)
result.browserSectionModule = browser_section_module.newModule(result, bookmarkService, settingsService)
result.profileSectionModule = profile_section_module.newModule(result, events, accountsService, settingsService, profileService, contactsService, aboutService)
method delete*[T](self: Module[T]) =

View File

@ -21,4 +21,4 @@ proc delete*(self: Web3ProviderController) =
delete self.view
proc init*(self: Web3ProviderController) =
self.view.init()
discard

View File

@ -11,7 +11,6 @@ logScope:
QtObject:
type Web3ProviderView* = ref object of QObject
status*: Status
dappsAddress*: string
proc setup(self: Web3ProviderView) =
self.QObject.setup
@ -23,7 +22,6 @@ QtObject:
new(result, delete)
result = Web3ProviderView()
result.status = status
result.dappsAddress = ""
result.setup
proc disconnect*(self: Web3ProviderView) {.slot.} =
@ -32,27 +30,6 @@ QtObject:
proc postMessage*(self: Web3ProviderView, message: string): string {.slot.} =
result = self.status.provider.postMessage(message)
proc getNetworkId*(self: Web3ProviderView): int {.slot.} =
self.status.settings.getCurrentNetworkDetails().config.networkId
QtProperty[int] networkId:
read = getNetworkId
proc dappsAddressChanged(self: Web3ProviderView, address: string) {.signal.}
proc getDappsAddress(self: Web3ProviderView): string {.slot.} =
result = self.dappsAddress
proc setDappsAddress(self: Web3ProviderView, address: string) {.slot.} =
self.dappsAddress = address
self.status.saveSetting(Setting.DappsAddress, address)
self.dappsAddressChanged(address)
QtProperty[string] dappsAddress:
read = getDappsAddress
notify = dappsAddressChanged
write = setDappsAddress
proc hasPermission*(self: Web3ProviderView, hostname: string, permission: string): bool {.slot.} =
result = self.status.permissions.hasPermission(hostname, permission.toPermission())
@ -63,11 +40,3 @@ QtObject:
let (url, base, http_scheme, path_prefix, hasContentHash) = self.status.provider.ensResourceURL(ens, url)
result = url_replaceHostAndAddPath(url, (if hasContentHash: base else: url_host(base)), http_scheme, path_prefix)
proc replaceHostByENS*(self: Web3ProviderView, url: string, ens: string): string {.slot.} =
result = url_replaceHostAndAddPath(url, ens)
proc getHost*(self: Web3ProviderView, url: string): string {.slot.} =
result = url_host(url)
proc init*(self: Web3ProviderView) =
self.setDappsAddress(self.status.settings.getSetting[:string](Setting.DappsAddress))

View File

@ -1,4 +1,5 @@
import ./dto/bookmark as bookmark_dto
import results
export bookmark_dto
@ -12,8 +13,6 @@ method delete*(self: ServiceInterface) {.base.} =
method init*(self: ServiceInterface) {.base.} =
raise newException(ValueError, "No implementation available")
import results
type R = Result[BookmarkDto, string]
method getBookmarks*(self: ServiceInterface): seq[BookmarkDto] {.base.} =

View File

@ -0,0 +1,15 @@
import json
import sets
import permission
include ../../../common/json_utils
type Dapp* = object
name*: string
permissions*: HashSet[Permission]
proc toDapp*(jsonObj: JsonNode): Dapp =
result = Dapp()
result.permissions = initHashSet[Permission]()
discard jsonObj.getProp("name", result.name)
for permission in jsonObj["permissions"].getElems():
result.permissions.incl(permission.getStr().toPermission())

View File

@ -0,0 +1,17 @@
import json
import chronicles
import strutils
include ../../../common/json_utils
type
Permission* {.pure.} = enum
Web3 = "web3",
ContactCode = "contact-code"
Unknown = "unknown"
proc toPermission*(value: string): Permission =
result = Permission.Unknown
try:
result = parseEnum[Permission](value)
except:
warn "Unknown permission requested", value

View File

@ -0,0 +1,102 @@
import Tables, json, sequtils, chronicles
import sets
import result
import options
include ../../common/json_utils
import service_interface
import status/statusgo_backend_new/permissions as status_go
import dto/dapp
import dto/permission
export service_interface
logScope:
topics = "dapp-permissions-service"
type
Service* = ref object of ServiceInterface
dapps: Table[string, Dapp]
type R = Result[Dapp, string]
method delete*(self: Service) =
discard
proc newService*(): Service =
result = Service()
result.dapps = initTable[string, Dapp]()
method init*(self: Service) =
try:
let response = status_go.getDappPermissions()
for dapp in response.result.getElems().mapIt(it.toDapp()):
self.dapps[dapp.name] = dapp
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
method getDapps*(self: Service): seq[Dapp] =
return toSeq(self.dapps.values)
method getDapp*(self: Service, dapp: string): Option[Dapp] =
if self.dapps.hasKey(dapp):
return some(self.dapps[dapp])
return none(Dapp)
method clearPermissions*(self: Service, dapp: string): R =
try:
if not self.dapps.hasKey(dapp):
result.err "not found"
return
discard status_go.deleteDappPermissions(dapp)
self.dapps[dapp].permissions.clear()
result.ok self.dapps[dapp]
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
method revoke*(self: Service, permission: Permission): bool =
try:
for dapp in self.dapps.mvalues:
if dapp.permissions.contains(permission):
dapp.permissions.excl(permission)
if dapp.permissions.len > 0:
discard status_go.addDappPermissions(dapp.name, dapp.permissions.toSeq().mapIt($it))
else:
discard status_go.deleteDappPermissions(dapp.name)
return true
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
method revoke*(self: Service, dapp: string, permission: Permission): R =
try:
if not self.dapps.hasKey(dapp):
result.err "not found"
return
if self.dapps[dapp].permissions.contains(permission):
self.dapps[dapp].permissions.excl(permission)
if self.dapps[dapp].permissions.len > 0:
discard status_go.addDappPermissions(dapp, self.dapps[dapp].permissions.toSeq().mapIt($it))
else:
discard status_go.deleteDappPermissions(dapp)
result.ok self.dapps[dapp]
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
result.err errDescription
method addPermission*(self: Service, dapp: string, permission: Permission): R =
try:
if not self.dapps.hasKey(dapp):
result.err "not found"
return
self.dapps[dapp].permissions.incl(permission)
discard status_go.addDappPermissions(dapp, self.dapps[dapp].permissions.toSeq().mapIt($it))
result.ok self.dapps[dapp]
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
result.err errDescription

View File

@ -0,0 +1,37 @@
import dto/dapp
import dto/permission
import results
import options
export dapp
export permission
type R = Result[Dapp, string]
type
ServiceInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for this service access.
method delete*(self: ServiceInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method init*(self: ServiceInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getDapps*(self: ServiceInterface): seq[Dapp] {.base.} =
raise newException(ValueError, "No implementation available")
method getDapp*(self: ServiceInterface, dapp: string): Option[Dapp] {.base.} =
raise newException(ValueError, "No implementation available")
method clearPermissions*(self: ServiceInterface, dapp: string): R {.base.} =
raise newException(ValueError, "No implementation available")
method revoke*(self: ServiceInterface, permission: Permission): bool {.base.} =
raise newException(ValueError, "No implementation available")
method revoke*(self: ServiceInterface, dapp: string, permission: Permission): R {.base.} =
raise newException(ValueError, "No implementation available")
method addPermission*(self: ServiceInterface, dapp: string, permission: Permission): R {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,12 @@
{.used.}
import json_serialization
import node_config
type
NetworkDetails* = object
id*: string
name*: string
etherscanLink* {.serializedFieldName("etherscan-link").}: string
config*: NodeConfig

View File

@ -0,0 +1,9 @@
import json_serialization
import upstream_config
type
NodeConfig* = object
networkId* {.serializedFieldName("NetworkId").}: int
dataDir* {.serializedFieldName("DataDir").}: string
upstreamConfig* {.serializedFieldName("UpstreamConfig").}: UpstreamConfig

View File

@ -0,0 +1,6 @@
import json_serialization
type
UpstreamConfig* = object
enabled* {.serializedFieldName("Enabled").}: bool
url* {.serializedFieldName("URL").}: string

View File

@ -1,5 +1,6 @@
import json, json_serialization, sequtils, chronicles
import json, json_serialization, sugar, sequtils, chronicles
# import status/statusgo_backend_new/custom_tokens as custom_tokens
import json, tables, sugar, sequtils, strutils, atomics, os
import status/statusgo_backend/settings as status_go_settings
import status/statusgo_backend/accounts as status_accounts
@ -7,11 +8,17 @@ from status/types/setting import Setting
import ./service_interface, ./dto
import dto/network_details
import dto/node_config
import dto/upstream_config
export service_interface
logScope:
topics = "settings-service"
const DEFAULT_NETWORK_NAME = "mainnet_rpc"
type
Service* = ref object of ServiceInterface
# profile: Dto
@ -35,7 +42,6 @@ method getPubKey*(self: Service): string=
return status_go_settings.getSetting(Setting.PublicKey, "0x0")
method getNetwork*(self: Service): string =
const DEFAULT_NETWORK_NAME = "mainnet_rpc"
return status_go_settings.getSetting(Setting.Networks_CurrentNetwork, DEFAULT_NETWORK_NAME)
method getAppearance*(self: Service): int =
@ -56,3 +62,17 @@ method getIdentityImage*(self: Service, address: string): IdentityImage =
var obj = status_accounts.getIdentityImage(address)
var identityImage = IdentityImage(thumbnail: obj.thumbnail, large: obj.large)
return identityImage
method getDappsAddress*(self: Service): string =
return status_go_settings.getSetting[string](Setting.DappsAddress)
method setDappsAddress*(self: Service, address: string): bool =
let r = status_go_settings.saveSetting(Setting.DappsAddress, address)
return r.error == ""
method getCurrentNetworkDetails*(self: ServiceInterface): NetworkDetails =
let currNetwork = getSetting[string](Setting.Networks_CurrentNetwork, DEFAULT_NETWORK_NAME)
let networks = getSetting[seq[NetworkDetails]](Setting.Networks_Networks)
for n in networks:
if n.id == currNetwork:
return n

View File

@ -1,6 +1,12 @@
import dto
import dto/network_details
import dto/node_config
import dto/upstream_config
export dto
export network_details
export node_config
export upstream_config
type
ServiceInterface* {.pure inheritable.} = ref object of RootObj
@ -32,3 +38,12 @@ method getCurrentUserStatus*(self: ServiceInterface): int {.base.} =
method getIdentityImage*(self: ServiceInterface, address: string): IdentityImage {.base.} =
raise newException(ValueError, "No implementation available")
method getDappsAddress*(self: ServiceInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method setDappsAddress*(self: ServiceInterface, address: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
method getCurrentNetworkDetails*(self: ServiceInterface): NetworkDetails {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -5,12 +5,12 @@ import QtQuick 2.13
QtObject {
id: root
property var web3ProviderInst: web3Provider
property var web3ProviderInst: providerModule
property var urlENSDictionary: ({})
function determineRealURL(text){
var url = RootStore.getUrlFromUserInput(text);
var host = web3Provider.getHost(url);
var host = providerModule.getHost(url);
if(host.endsWith(".eth")){
var ensResource = web3Provider.ensResourceURL(host, url);
@ -18,7 +18,7 @@ QtObject {
// TODO: populate urlENSDictionary for prettier url instead of swarm-gateway big URL
return ensResource;
} else {
urlENSDictionary[web3Provider.getHost(ensResource)] = host;
urlENSDictionary[providerModule.getHost(ensResource)] = host;
}
url = ensResource;
}
@ -26,7 +26,7 @@ QtObject {
}
function obtainAddress(url) {
var ensAddr = urlENSDictionary[web3Provider.getHost(url)];
return ensAddr ? web3Provider.replaceHostByENS( url, ensAddr) : url;
var ensAddr = urlENSDictionary[providerModule.getHost(url)];
return ensAddr ? providerModule.replaceHostByENS( url, ensAddr) : url;
}
}

2
vendor/status-lib vendored

@ -1 +1 @@
Subproject commit b6a5b7e4ed2bf17eae04d54472a1cf4d0605757c
Subproject commit aea20114ec22d2648d6d1dc30caafc913302ceac