Hide user settings if permission is missing
This commit is contained in:
parent
0c574dff84
commit
3ba0c0405e
@ -372,7 +372,7 @@ void registerQmlTypes() {
|
||||
qmlRegisterType<ScriptAutoSaver>(uri, 1, 0, "ScriptAutoSaver");
|
||||
|
||||
qmlRegisterType<UserManager>(uri, 1, 0, "UserManager");
|
||||
qmlRegisterUncreatableType<UserInfo>(uri, 1, 0, "UserInfo", "Get it from UserManager");
|
||||
qmlRegisterType<UserInfo>(uri, 1, 0, "UserInfo");
|
||||
qmlRegisterUncreatableType<TokenInfo>(uri, 1, 0, "TokenInfo", "Get it from TokenInfos");
|
||||
qmlRegisterUncreatableType<TokenInfos>(uri, 1, 0, "TokenInfos", "Get it from UserManager");
|
||||
qmlRegisterUncreatableType<Users>(uri, 1, 0, "Users", "Get it from UserManager");
|
||||
|
||||
@ -31,18 +31,18 @@
|
||||
class UserInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString username READ username NOTIFY usernameChanged)
|
||||
Q_PROPERTY(QString email READ email NOTIFY emailChanged)
|
||||
Q_PROPERTY(QString displayName READ displayName NOTIFY displayNameChanged)
|
||||
Q_PROPERTY(PermissionScopes scopes READ scopes NOTIFY scopesChanged)
|
||||
Q_PROPERTY(QList<QUuid> allowedThingIds READ allowedThingIds NOTIFY allowedThingIdsChanged)
|
||||
Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged)
|
||||
Q_PROPERTY(QString email READ email WRITE setEmail NOTIFY emailChanged)
|
||||
Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName NOTIFY displayNameChanged)
|
||||
Q_PROPERTY(PermissionScopes scopes READ scopes WRITE setScopes NOTIFY scopesChanged)
|
||||
Q_PROPERTY(QList<QUuid> allowedThingIds READ allowedThingIds WRITE setAllowedThingIds NOTIFY allowedThingIdsChanged)
|
||||
|
||||
public:
|
||||
enum PermissionScope {
|
||||
PermissionScopeNone = 0x0000,
|
||||
PermissionScopeControlThings = 0x0001,
|
||||
PermissionScopeConfigureThings = 0x0003,
|
||||
PermissionScopeAccessAllThings = 0x0004,
|
||||
PermissionScopeAccessAllThings = 0x0004, // Since 8.4
|
||||
PermissionScopeExecuteRules = 0x0010,
|
||||
PermissionScopeConfigureRules = 0x0030,
|
||||
PermissionScopeAdmin = 0xFFFF,
|
||||
|
||||
@ -103,7 +103,14 @@ int UserManager::createUser(const QString &username, const QString &password, co
|
||||
if (m_engine->jsonRpcClient()->ensureServerVersion("6.0")) {
|
||||
params.insert("displayName", displayName);
|
||||
params.insert("email", email);
|
||||
params.insert("scopes", UserInfo::scopesToList((UserInfo::PermissionScopes)permissionScopes));
|
||||
|
||||
// Backports compatibility for pre 8.4
|
||||
UserInfo::PermissionScopes scopes = static_cast<UserInfo::PermissionScopes>(permissionScopes);
|
||||
if (!m_engine->jsonRpcClient()->ensureServerVersion("8.4"))
|
||||
scopes.setFlag(UserInfo::PermissionScopeAccessAllThings, false);
|
||||
|
||||
|
||||
params.insert("scopes", UserInfo::scopesToList(scopes));
|
||||
}
|
||||
|
||||
if (m_engine->jsonRpcClient()->ensureServerVersion("8.4") && !allowedThingIds.isEmpty()) {
|
||||
@ -145,7 +152,14 @@ int UserManager::setUserScopes(const QString &username, int scopes, const QList<
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("username", username);
|
||||
params.insert("scopes", UserInfo::scopesToList((UserInfo::PermissionScopes)scopes));
|
||||
|
||||
// Backports compatibility for pre 8.4
|
||||
UserInfo::PermissionScopes finalScopes = static_cast<UserInfo::PermissionScopes>(scopes);
|
||||
if (!m_engine->jsonRpcClient()->ensureServerVersion("8.4"))
|
||||
finalScopes.setFlag(UserInfo::PermissionScopeAccessAllThings, false);
|
||||
|
||||
params.insert("scopes", UserInfo::scopesToList(finalScopes));
|
||||
|
||||
if (m_engine->jsonRpcClient()->ensureServerVersion("8.4") && !allowedThingIds.isEmpty()) {
|
||||
QVariantList thingIds;
|
||||
foreach (const QUuid &thingId, allowedThingIds)
|
||||
|
||||
@ -98,7 +98,7 @@ SettingsPageBase {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Change password")
|
||||
iconName: "qrc:/icons/key.svg"
|
||||
visible: !engine.jsonRpcClient.pushButtonAuthAvailable
|
||||
visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) && !engine.jsonRpcClient.pushButtonAuthAvailable
|
||||
onClicked: {
|
||||
var page = pageStack.push(changePasswordComponent)
|
||||
page.confirmed.connect(function(newPassword) {
|
||||
@ -112,16 +112,15 @@ SettingsPageBase {
|
||||
text: qsTr("Edit user information")
|
||||
iconName: "qrc:/icons/edit.svg"
|
||||
onClicked: pageStack.push(editUserInfoComponent)
|
||||
visible: !engine.jsonRpcClient.pushButtonAuthAvailable
|
||||
visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) && !engine.jsonRpcClient.pushButtonAuthAvailable
|
||||
}
|
||||
|
||||
NymeaItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Manage authorized devices")
|
||||
iconName: "qrc:/icons/smartphone.svg"
|
||||
onClicked: {
|
||||
pageStack.push(manageTokensComponent)
|
||||
}
|
||||
visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin)
|
||||
onClicked: pageStack.push(manageTokensComponent)
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
@ -134,12 +133,9 @@ SettingsPageBase {
|
||||
text: qsTr("Manage users")
|
||||
visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) && !engine.jsonRpcClient.pushButtonAuthAvailable
|
||||
iconName: "qrc:/icons/contact-group.svg"
|
||||
onClicked: {
|
||||
pageStack.push(manageUsersComponent)
|
||||
}
|
||||
onClicked: pageStack.push(manageUsersComponent)
|
||||
}
|
||||
|
||||
|
||||
Component {
|
||||
id: editUserInfoComponent
|
||||
SettingsPageBase {
|
||||
@ -199,14 +195,16 @@ SettingsPageBase {
|
||||
id: configureAllowedThingsPage
|
||||
|
||||
property UserInfo userInfo: null
|
||||
property bool existingUser: true
|
||||
|
||||
title: qsTr("Accessable things for") + " \"" + userInfo.username + "\""
|
||||
|
||||
header: NymeaHeader {
|
||||
text: root.title
|
||||
text: configureAllowedThingsPage.title
|
||||
backButtonVisible: true
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
title: qsTr("Allowed things for") + " \"" + userInfo.username + "\""
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
@ -236,7 +234,10 @@ SettingsPageBase {
|
||||
checked: configureAllowedThingsPage.userInfo.thingAllowed(thingDelegate.thing.id)
|
||||
onCheckedChanged: {
|
||||
configureAllowedThingsPage.userInfo.allowThingId(thingDelegate.thing.id, checked)
|
||||
userManager.setUserScopes(configureAllowedThingsPage.userInfo.username, configureAllowedThingsPage.userInfo.scopes, configureAllowedThingsPage.userInfo.allowedThingIds)
|
||||
if (configureAllowedThingsPage.existingUser) {
|
||||
// Only update if this user already exists
|
||||
userManager.setUserScopes(configureAllowedThingsPage.userInfo.username, configureAllowedThingsPage.userInfo.scopes, configureAllowedThingsPage.userInfo.allowedThingIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -438,7 +439,7 @@ SettingsPageBase {
|
||||
Repeater {
|
||||
id: permissionRepeater
|
||||
|
||||
model: NymeaUtils.scopesModel
|
||||
model: engine.jsonRpcClient.ensureServerVersion("8.4") ? NymeaUtils.scopesModel : NymeaUtils.scopesModelPre8dot4
|
||||
delegate: NymeaSwipeDelegate {
|
||||
|
||||
Layout.fillWidth: true
|
||||
@ -478,24 +479,22 @@ SettingsPageBase {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Acessable things")
|
||||
visible: (userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings
|
||||
visible: engine.jsonRpcClient.ensureServerVersion("8.4") &&
|
||||
(userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
id: allowedThingsEntry
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Allowed things for this user")
|
||||
subText: userDetailsPage.userInfo.allowedThingIds.length + " " + qsTr("things accessable")
|
||||
visible: (userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings
|
||||
visible: engine.jsonRpcClient.ensureServerVersion("8.4") &&
|
||||
(userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings
|
||||
progressive: true
|
||||
onClicked: {
|
||||
pageStack.push(configureAllowedThingsComponent, {userInfo: userDetailsPage.userInfo})
|
||||
}
|
||||
onClicked: pageStack.push(configureAllowedThingsComponent, {userInfo: userDetailsPage.userInfo})
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
@ -537,7 +536,13 @@ SettingsPageBase {
|
||||
id: createUserPage
|
||||
title: qsTr("Add a user")
|
||||
|
||||
property var permissionScopes: UserInfo.PermissionScopeNone
|
||||
UserInfo {
|
||||
id: newUserInfo
|
||||
username: usernameTextField.text
|
||||
email: emailTextField.text
|
||||
displayName: displayNameTextField.text
|
||||
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("User information")
|
||||
@ -588,30 +593,59 @@ SettingsPageBase {
|
||||
text: qsTr("Permissions")
|
||||
}
|
||||
|
||||
|
||||
Repeater {
|
||||
id: scopesRepeater
|
||||
model: NymeaUtils.scopesModel
|
||||
|
||||
delegate: CheckDelegate {
|
||||
model: engine.jsonRpcClient.ensureServerVersion("8.4") ? NymeaUtils.scopesModel : NymeaUtils.scopesModelPre8dot4
|
||||
|
||||
delegate: NymeaSwipeDelegate {
|
||||
|
||||
Layout.fillWidth: true
|
||||
text: model.text
|
||||
checked: (createUserPage.permissionScopes & model.scope) === model.scope
|
||||
onClicked: {
|
||||
var scopes = createUserPage.permissionScopes
|
||||
if (checked) {
|
||||
scopes |= model.scope
|
||||
} else {
|
||||
scopes &= ~model.scope
|
||||
}
|
||||
|
||||
// make sure the new permissions are consistant before sending them to the core
|
||||
scopes = NymeaUtils.getPermissionScopeAdjustments(model.scope, checked, scopes)
|
||||
createUserPage.permissionScopes = scopes
|
||||
text: model.text
|
||||
subText: model.description
|
||||
progressive: false
|
||||
|
||||
CheckBox {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: app.margins
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
enabled: model.scope === UserInfo.PermissionScopeAdmin || ((newUserInfo.scopes & UserInfo.PermissionScopeAdmin) !== UserInfo.PermissionScopeAdmin)
|
||||
checked: (newUserInfo.scopes & model.scope) === model.scope
|
||||
onClicked: {
|
||||
var scopes = newUserInfo.scopes
|
||||
if (checked) {
|
||||
scopes |= model.scope
|
||||
} else {
|
||||
scopes &= ~model.scope
|
||||
}
|
||||
|
||||
// make sure the new permissions are consistant before sending them to the core
|
||||
scopes = NymeaUtils.getPermissionScopeAdjustments(model.scope, checked, scopes)
|
||||
newUserInfo.scopes = scopes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Acessable things")
|
||||
visible: engine.jsonRpcClient.ensureServerVersion("8.4") &&
|
||||
(newUserInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
id: allowedThingsEntry
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Allowed things for this user")
|
||||
subText: newUserInfo.allowedThingIds.length + " " + qsTr("things accessable")
|
||||
visible: engine.jsonRpcClient.ensureServerVersion("8.4") &&
|
||||
(newUserInfo.scopes & UserInfo.PermissionScopeAccessAllThings) !== UserInfo.PermissionScopeAccessAllThings
|
||||
progressive: true
|
||||
onClicked: pageStack.push(configureAllowedThingsComponent, {userInfo: newUserInfo, existingUser: false})
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("Create new user")
|
||||
Layout.fillWidth: true
|
||||
@ -620,7 +654,7 @@ SettingsPageBase {
|
||||
enabled: usernameTextField.displayText.length >= 3 && passwordTextField.isValid
|
||||
onClicked: {
|
||||
createUserPage.busy = true
|
||||
userManager.createUser(usernameTextField.displayText, passwordTextField.password, displayNameTextField.text, emailTextField.text, createUserPage.permissionScopes)
|
||||
userManager.createUser(usernameTextField.displayText, passwordTextField.password, displayNameTextField.text, emailTextField.text, newUserInfo.scopes, newUserInfo.allowedThingIds)
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
|
||||
@ -166,6 +166,35 @@ Item {
|
||||
return namedIcons[name]
|
||||
}
|
||||
|
||||
property ListModel scopesModelPre8dot4: ListModel {
|
||||
ListElement {
|
||||
text: qsTr("Admin")
|
||||
description: qsTr("Full access to the system.")
|
||||
scope: UserInfo.PermissionScopeAdmin
|
||||
}
|
||||
ListElement {
|
||||
text: qsTr("Control things")
|
||||
description: qsTr("Execute actions and use things and services.")
|
||||
scope: UserInfo.PermissionScopeControlThings
|
||||
}
|
||||
ListElement {
|
||||
text: qsTr("Configure things")
|
||||
description: qsTr("Add new things and change settings.")
|
||||
scope: UserInfo.PermissionScopeConfigureThings
|
||||
}
|
||||
ListElement {
|
||||
text: qsTr("Execute magic")
|
||||
description: qsTr("Execute rules, scenes and scripts.")
|
||||
scope: UserInfo.PermissionScopeExecuteRules
|
||||
}
|
||||
ListElement {
|
||||
text: qsTr("Configure magic")
|
||||
description: qsTr("Create new rules and scripts in the system.")
|
||||
scope: UserInfo.PermissionScopeConfigureRules
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
property ListModel scopesModel: ListModel {
|
||||
ListElement {
|
||||
text: qsTr("Admin")
|
||||
|
||||
Reference in New Issue
Block a user