fix(@desktop/profile): Split account and profile settings

Avoid to reveal which alias own which settings. The only settings
pre-login available is the storeToKeychain

Ideally we should also encrypt the profile settings
This commit is contained in:
Anthony Laibe 2021-09-22 10:10:54 +02:00 committed by Iuri Matias
parent a44822d7f6
commit 22e8c8a7ff
10 changed files with 90 additions and 27 deletions

View File

@ -63,6 +63,8 @@ QtObject:
identityImage: currNodeAcct.identityImage
))
self.status.events.emit("accountChanged", AccountArgs(account: currNodeAcct))
QtProperty[QVariant] currentAccount:
read = getCurrentAccount
write = setCurrentAccount
@ -172,7 +174,7 @@ QtObject:
self.keychainManager.storeDataAsync(username, password)
proc tryToObtainPassword*(self: LoginView) {.slot.} =
let value = self.appService.localSettingsService.getValue(
let value = self.appService.localSettingsService.getAccountValue(
LS_KEY_STORE_TO_KEYCHAIN).stringVal
if (value == LS_VALUE_STORE):
self.keychainManager.readDataAsync(self.currentAccount.username)
@ -189,7 +191,7 @@ QtObject:
return
# We are notifying user only about keychain errors.
self.appService.localSettingsService.removeValue(LS_KEY_STORE_TO_KEYCHAIN)
self.appService.localSettingsService.removeAccountValue(LS_KEY_STORE_TO_KEYCHAIN)
self.obtainingPasswordError(errorDescription)
proc onKeychainManagerSuccess*(self: LoginView, data: string) {.slot.} =

View File

@ -4,6 +4,8 @@ import status/[status, wallet]
import status/types/[rpc_response]
import status/types/account as status_account_type
import views/account_info
import ../../app_service/[main]
type
AccountRoles {.pure.} = enum
@ -101,6 +103,8 @@ QtObject:
proc storeDerivedAndLogin(self: OnboardingView, password: string): string {.slot.} =
let genAcc = self.currentAccount.account
let acc = Account(name: genAcc.name, keyUid: genAcc.keyUid, identicon: genAcc.identicon, identityImage: genAcc.identityImage)
self.status.events.emit("accountChanged", status_account_type.AccountArgs(account: acc))
try:
result = self.status.accounts.storeDerivedAndLogin(self.status.fleet.config, genAcc, password).toJson

View File

@ -209,6 +209,19 @@ QtObject:
read = getSettingsFile
notify = settingsFileChanged
proc accountSettingsFileChanged*(self: ProfileView) {.signal.}
proc setAccountSettingsFile*(self: ProfileView, alias: string) =
self.appService.localSettingsService.updateAccountSettingsFilePath(alias)
self.accountSettingsFileChanged()
proc getAccountSettingsFile*(self: ProfileView): string {.slot.} =
self.appService.localSettingsService.getAccountSettingsFilePath
QtProperty[string] accountSettingsFile:
read = getAccountSettingsFile
notify = accountSettingsFileChanged
proc setSendUserStatus*(self: ProfileView, sendUserStatus: bool) {.slot.} =
if (sendUserStatus == self.profile.sendUserStatus):
return

View File

@ -1,12 +1,13 @@
import NimQml, os, chronicles
import ../../../constants
# Local Settings keys:
# Local Account Settings keys:
const LS_KEY_STORE_TO_KEYCHAIN* = "storeToKeychain"
# Local Settings values:
# Local Account Settings values:
const LS_VALUE_STORE* = "store"
const UNKNOWN_ACCOUNT = "unknownAccount"
const UNKNOWN_PROFILE = "unknownProfile"
logScope:
topics = "local-settings"
@ -15,12 +16,16 @@ QtObject:
type LocalSettingsService* = ref object of QObject
settingsFilePath: string
settings: QSettings
accountSettingsFilePath: string
accountSettings: QSettings
globalSettingsFilePath: string
globalSettings: QSettings
proc setup(self: LocalSettingsService) =
self.settingsFilePath = os.joinPath(DATADIR, "qt", UNKNOWN_ACCOUNT)
self.settingsFilePath = os.joinPath(DATADIR, "qt", UNKNOWN_PROFILE)
self.settings = newQSettings(self.settingsFilePath, QSettingsFormat.IniFormat)
self.accountSettingsFilePath = os.joinPath(DATADIR, "qt", UNKNOWN_ACCOUNT)
self.accountSettings = newQSettings(self.accountSettingsFilePath, QSettingsFormat.IniFormat)
self.globalSettingsFilePath = os.joinPath(DATADIR, "qt", "global")
self.globalSettings = newQSettings(self.globalSettingsFilePath, QSettingsFormat.IniFormat)
self.QObject.setup
@ -37,11 +42,14 @@ QtObject:
proc getGlobalSettingsFilePath*(self: LocalSettingsService): string =
return self.globalSettingsFilePath
proc getAccountSettingsFilePath*(self: LocalSettingsService): string =
return self.accountSettingsFilePath
proc getSettingsFilePath*(self: LocalSettingsService): string =
return self.settingsFilePath
proc updateSettingsFilePath*(self: LocalSettingsService, pubKey: string) =
let unknownSettingsPath = os.joinPath(DATADIR, "qt", UNKNOWN_ACCOUNT)
let unknownSettingsPath = os.joinPath(DATADIR, "qt", UNKNOWN_PROFILE)
if (not unknownSettingsPath.tryRemoveFile):
# Only fails if the file exists and an there was an error removing it
# More info: https://nim-lang.org/docs/os.html#tryRemoveFile%2Cstring
@ -51,6 +59,27 @@ QtObject:
self.settingsFilePath = os.joinPath(DATADIR, "qt", pubKey)
self.settings = newQSettings(self.settingsFilePath, QSettingsFormat.IniFormat)
proc updateAccountSettingsFilePath*(self: LocalSettingsService, alias: string) =
let unknownAccountSettingsPath = os.joinPath(DATADIR, "qt", UNKNOWN_ACCOUNT)
if (not unknownAccountSettingsPath.tryRemoveFile):
# Only fails if the file exists and an there was an error removing it
# More info: https://nim-lang.org/docs/os.html#tryRemoveFile%2Cstring
warn "Failed to remove unused settings file", file=unknownAccountSettingsPath
self.accountSettings.delete
self.accountSettingsFilePath = os.joinPath(DATADIR, "qt", alias)
self.accountSettings = newQSettings(self.accountSettingsFilePath, QSettingsFormat.IniFormat)
proc setAccountValue*(self: LocalSettingsService, key: string, value: QVariant) =
self.accountSettings.setValue(key, value)
proc getAccountValue*(self: LocalSettingsService, key: string,
defaultValue: QVariant = newQVariant()): QVariant =
self.accountSettings.value(key, defaultValue)
proc removeAccountValue*(self: LocalSettingsService, key: string) =
self.accountSettings.remove(key)
proc setValue*(self: LocalSettingsService, key: string, value: QVariant) =
self.settings.setValue(key, value)

View File

@ -7,6 +7,7 @@ import app/node/core as node
import app/utilsView/core as utilsView
import app/browser/core as browserView
import app/profile/core as profile
import app/profile/view
import app/onboarding/core as onboarding
import app/login/core as login
import app/provider/core as provider
@ -192,6 +193,13 @@ proc mainProc() =
var onboarding = onboarding.newController(status)
defer: onboarding.delete()
proc onAccountChanged(account: Account) =
profile.view.setAccountSettingsFile(account.name)
status.events.on("accountChanged") do(a: Args):
var args = AccountArgs(a)
onAccountChanged(args.account)
status.events.once("login") do(a: Args):
var args = AccountArgs(a)
appService.onLoggedIn()
@ -206,7 +214,8 @@ proc mainProc() =
status.events.once("loginCompleted") do(a: Args):
var args = AccountArgs(a)
onAccountChanged(args.account)
status.startMessenger()
profile.init(args.account)
wallet.init()

View File

@ -51,7 +51,7 @@ Item {
text: qsTr("Store pass to Keychain")
visible: Qt.platform.os == "osx" // For now, this is available only on MacOS
currentValue: {
let value = appSettings.storeToKeychain
let value = accountSettings.storeToKeychain
if(value == Constants.storeToKeychainValueStore)
return qsTr("Store")

View File

@ -31,18 +31,18 @@ ModalPopup {
StatusRadioButtonRow {
text: qsTr("Store")
buttonGroup: openLinksWithGroup
checked: appSettings.storeToKeychain === Constants.storeToKeychainValueStore
checked: accountSettings.storeToKeychain === Constants.storeToKeychainValueStore
onRadioCheckedChanged: {
if (checked && appSettings.storeToKeychain !== Constants.storeToKeychainValueStore) {
if (checked && accountSettings.storeToKeychain !== Constants.storeToKeychainValueStore) {
var storePassPopup = openPopup(storePasswordModal)
if(storePassPopup)
{
storePassPopup.closed.connect(function(){
if (appSettings.storeToKeychain === Constants.storeToKeychainValueStore)
if (accountSettings.storeToKeychain === Constants.storeToKeychainValueStore)
popup.close()
else if (appSettings.storeToKeychain === Constants.storeToKeychainValueNotNow)
else if (accountSettings.storeToKeychain === Constants.storeToKeychainValueNotNow)
notNowBtn.checked = true
else if (appSettings.storeToKeychain === Constants.storeToKeychainValueNever)
else if (accountSettings.storeToKeychain === Constants.storeToKeychainValueNever)
neverBtn.checked = true
})
}
@ -54,11 +54,11 @@ ModalPopup {
id: notNowBtn
text: qsTr("Not now")
buttonGroup: openLinksWithGroup
checked: appSettings.storeToKeychain === Constants.storeToKeychainValueNotNow ||
appSettings.storeToKeychain === ""
checked: accountSettings.storeToKeychain === Constants.storeToKeychainValueNotNow ||
accountSettings.storeToKeychain === ""
onRadioCheckedChanged: {
if (checked) {
appSettings.storeToKeychain = Constants.storeToKeychainValueNotNow
accountSettings.storeToKeychain = Constants.storeToKeychainValueNotNow
}
}
}
@ -67,10 +67,10 @@ ModalPopup {
id: neverBtn
text: qsTr("Never")
buttonGroup: openLinksWithGroup
checked: appSettings.storeToKeychain === Constants.storeToKeychainValueNever
checked: accountSettings.storeToKeychain === Constants.storeToKeychainValueNever
onRadioCheckedChanged: {
if (checked) {
appSettings.storeToKeychain = Constants.storeToKeychainValueNever
accountSettings.storeToKeychain = Constants.storeToKeychainValueNever
}
}
}

View File

@ -38,10 +38,16 @@ StatusWindow {
}
}
Settings {
id: accountSettings
fileName: profileModel.accountSettingsFile
property string storeToKeychain: ""
}
Settings {
id: appSettings
fileName: profileModel.settingsFile
property string storeToKeychain: ""
property var chatSplitView
property var walletSplitView
@ -277,11 +283,11 @@ StatusWindow {
{
if(clearStoredValue)
{
appSettings.storeToKeychain = ""
accountSettings.storeToKeychain = ""
}
if(appSettings.storeToKeychain === "" ||
appSettings.storeToKeychain === Constants.storeToKeychainValueNotNow)
if(accountSettings.storeToKeychain === "" ||
accountSettings.storeToKeychain === Constants.storeToKeychainValueNotNow)
{
storeToKeychainConfirmationPopup.password = password
storeToKeychainConfirmationPopup.username = username
@ -310,18 +316,18 @@ StatusWindow {
}
onConfirmButtonClicked: {
appSettings.storeToKeychain = Constants.storeToKeychainValueStore
accountSettings.storeToKeychain = Constants.storeToKeychainValueStore
loginModel.storePassword(username, password)
finish()
}
onRejectButtonClicked: {
appSettings.storeToKeychain = Constants.storeToKeychainValueNotNow
accountSettings.storeToKeychain = Constants.storeToKeychainValueNotNow
finish()
}
onCancelButtonClicked: {
appSettings.storeToKeychain = Constants.storeToKeychainValueNever
accountSettings.storeToKeychain = Constants.storeToKeychainValueNever
finish()
}
}

View File

@ -158,7 +158,7 @@ ModalPopup {
onClicked: {
if (storingPasswordModal)
{
appSettings.storeToKeychain = Constants.storeToKeychainValueStore
accountSettings.storeToKeychain = Constants.storeToKeychainValueStore
loginModel.storePassword(profileModel.profile.username, repeatPasswordField.text)
popup.close()
}

View File

@ -34,7 +34,7 @@ Item {
}
function resetLogin() {
if(appSettings.storeToKeychain === Constants.storeToKeychainValueStore)
if(accountSettings.storeToKeychain === Constants.storeToKeychainValueStore)
{
connection.enabled = true
txtPassword.visible = false