Improve permission handling and add new Thing based permission basics
parent
ecea0eae26
commit
e14137296e
|
|
@ -39,6 +39,7 @@ public:
|
||||||
PermissionScopeNone = 0x0000,
|
PermissionScopeNone = 0x0000,
|
||||||
PermissionScopeControlThings = 0x0001,
|
PermissionScopeControlThings = 0x0001,
|
||||||
PermissionScopeConfigureThings = 0x0003,
|
PermissionScopeConfigureThings = 0x0003,
|
||||||
|
PermissionScopeAccessAllThings = 0x0004,
|
||||||
PermissionScopeExecuteRules = 0x0010,
|
PermissionScopeExecuteRules = 0x0010,
|
||||||
PermissionScopeConfigureRules = 0x0030,
|
PermissionScopeConfigureRules = 0x0030,
|
||||||
PermissionScopeAdmin = 0xFFFF,
|
PermissionScopeAdmin = 0xFFFF,
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,8 @@ public:
|
||||||
UserErrorDuplicateUserId,
|
UserErrorDuplicateUserId,
|
||||||
UserErrorBadPassword,
|
UserErrorBadPassword,
|
||||||
UserErrorTokenNotFound,
|
UserErrorTokenNotFound,
|
||||||
UserErrorPermissionDenied
|
UserErrorPermissionDenied,
|
||||||
|
UserErrorInconsistantScopes
|
||||||
};
|
};
|
||||||
Q_ENUM(UserError)
|
Q_ENUM(UserError)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -323,6 +323,7 @@ SettingsPageBase {
|
||||||
title: qsTr("Manage %1").arg(userInfo.username)
|
title: qsTr("Manage %1").arg(userInfo.username)
|
||||||
|
|
||||||
property UserInfo userInfo: null
|
property UserInfo userInfo: null
|
||||||
|
property bool restrictedThingAccess: userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAccessAllThings === 0
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: confirmUserDeletionComponent
|
id: confirmUserDeletionComponent
|
||||||
|
|
@ -382,29 +383,65 @@ SettingsPageBase {
|
||||||
Repeater {
|
Repeater {
|
||||||
model: NymeaUtils.scopesModel
|
model: NymeaUtils.scopesModel
|
||||||
|
|
||||||
delegate: CheckDelegate {
|
delegate: NymeaSwipeDelegate {
|
||||||
Layout.fillWidth: true
|
|
||||||
text: model.text
|
Layout.fillWidth: true
|
||||||
checked: (userDetailsPage.userInfo.scopes & model.scope) === model.scope
|
|
||||||
|
text: model.text
|
||||||
|
subText: model.description
|
||||||
|
progressive: false
|
||||||
|
|
||||||
|
CheckBox {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: app.margins
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
checked: (userDetailsPage.userInfo.scopes & model.scope) === model.scope
|
||||||
|
enabled: {
|
||||||
|
// Prevent an admin to lock himself out as admin
|
||||||
|
if (model.scope === UserInfo.PermissionScopeAdmin && userDetailsPage.userInfo.username == userManager.userInfo.username) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return model.scope === UserInfo.PermissionScopeAdmin || ((userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAdmin) !== UserInfo.PermissionScopeAdmin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enabled: model.scope === UserInfo.PermissionScopeAdmin && userDetailsPage.userInfo.username == userManager.userInfo.username ?
|
|
||||||
false : model.scope === UserInfo.PermissionScopeAdmin ||
|
|
||||||
((userDetailsPage.userInfo.scopes & UserInfo.PermissionScopeAdmin) !== UserInfo.PermissionScopeAdmin)
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
print("scopes:", userDetailsPage.userInfo.scopes)
|
|
||||||
var scopes = userDetailsPage.userInfo.scopes
|
var scopes = userDetailsPage.userInfo.scopes
|
||||||
if (checked) {
|
if (checked) {
|
||||||
scopes |= model.scope
|
scopes |= model.scope
|
||||||
} else {
|
} else {
|
||||||
scopes &= ~model.scope
|
scopes &= ~model.scope
|
||||||
scopes |= model.resetOnUnset
|
|
||||||
}
|
}
|
||||||
print("username:", userDetailsPage.userInfo.username)
|
|
||||||
print("new scopes:", scopes, UserInfo.PermissionScopeAdmin)
|
// make sure the new permissions are consistant before sending them to the core
|
||||||
|
scopes = NymeaUtils.getPermissionScopeAdjustments(model.scope, checked, scopes)
|
||||||
userManager.setUserScopes(userDetailsPage.userInfo.username, scopes)
|
userManager.setUserScopes(userDetailsPage.userInfo.username, scopes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SettingsPageSectionHeader {
|
||||||
|
text: qsTr("Acessable things")
|
||||||
|
visible: userDetailsPage.restrictedThingAccess
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NymeaSwipeDelegate {
|
||||||
|
id: allowedThingsEntry
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Allowed things for this user")
|
||||||
|
visible: userDetailsPage.restrictedThingAccess
|
||||||
|
progressive: true
|
||||||
|
onClicked: {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SettingsPageSectionHeader {
|
SettingsPageSectionHeader {
|
||||||
text: qsTr("Remove")
|
text: qsTr("Remove")
|
||||||
|
|
@ -496,6 +533,7 @@ SettingsPageBase {
|
||||||
text: qsTr("Permissions")
|
text: qsTr("Permissions")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: scopesRepeater
|
id: scopesRepeater
|
||||||
model: NymeaUtils.scopesModel
|
model: NymeaUtils.scopesModel
|
||||||
|
|
@ -510,8 +548,10 @@ SettingsPageBase {
|
||||||
scopes |= model.scope
|
scopes |= model.scope
|
||||||
} else {
|
} else {
|
||||||
scopes &= ~model.scope
|
scopes &= ~model.scope
|
||||||
scopes |= model.resetOnUnset
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure the new permissions are consistant before sending them to the core
|
||||||
|
scopes = NymeaUtils.getPermissionScopeAdjustments(model.scope, checked, scopes)
|
||||||
createUserPage.permissionScopes = scopes
|
createUserPage.permissionScopes = scopes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
function pad(num, size, base) {
|
function pad(num, size, base) {
|
||||||
if (base == undefined) {
|
if (base === undefined) {
|
||||||
base = 10
|
base = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,11 +167,102 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
property ListModel scopesModel: ListModel {
|
property ListModel scopesModel: ListModel {
|
||||||
ListElement { text: qsTr("Admin"); scope: UserInfo.PermissionScopeAdmin; resetOnUnset: UserInfo.PermissionScopeNone }
|
ListElement {
|
||||||
ListElement { text: qsTr("Control things"); scope: UserInfo.PermissionScopeControlThings; resetOnUnset: UserInfo.PermissionScopeNone }
|
text: qsTr("Admin")
|
||||||
ListElement { text: qsTr("Configure things"); scope: UserInfo.PermissionScopeConfigureThings; resetOnUnset: UserInfo.PermissionScopeControlThings }
|
description: qsTr("Full access to the system.")
|
||||||
ListElement { text: qsTr("Execute magic"); scope: UserInfo.PermissionScopeExecuteRules; resetOnUnset: UserInfo.PermissionScopeNone }
|
scope: UserInfo.PermissionScopeAdmin
|
||||||
ListElement { text: qsTr("Configure magic"); scope: UserInfo.PermissionScopeConfigureRules; resetOnUnset: UserInfo.PermissionScopeExecuteRules }
|
}
|
||||||
|
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("Access all things")
|
||||||
|
description: qsTr("Allow to see and use all things of the system.")
|
||||||
|
scope: UserInfo.PermissionScopeAccessAllThings
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPermissionScopeAdjustments(scope, enabled, currentScopes) {
|
||||||
|
|
||||||
|
var adjustedScopes = currentScopes;
|
||||||
|
|
||||||
|
console.warn("Adjust permissions", scope, "->", enabled, currentScopes)
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
|
||||||
|
// Scope has been enabled
|
||||||
|
switch (scope) {
|
||||||
|
case UserInfo.PermissionScopeAdmin:
|
||||||
|
adjustedScopes = UserInfo.PermissionScopeAdmin
|
||||||
|
break;
|
||||||
|
case UserInfo.PermissionScopeControlThings:
|
||||||
|
break;
|
||||||
|
case UserInfo.PermissionScopeConfigureThings:
|
||||||
|
adjustedScopes |= UserInfo.PermissionScopeControlThings
|
||||||
|
adjustedScopes |= UserInfo.PermissionScopeAccessAllThings
|
||||||
|
break;
|
||||||
|
case UserInfo.PermissionScopeAccessAllThings:
|
||||||
|
adjustedScopes |= UserInfo.PermissionScopeControlThings
|
||||||
|
break;
|
||||||
|
case UserInfo.PermissionScopeExecuteRules:
|
||||||
|
adjustedScopes |= UserInfo.PermissionScopeAccessAllThings
|
||||||
|
break;
|
||||||
|
case UserInfo.PermissionScopeConfigureRules:
|
||||||
|
adjustedScopes |= UserInfo.PermissionScopeExecuteRules
|
||||||
|
adjustedScopes |= UserInfo.PermissionScopeAccessAllThings
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Scope has been disabled
|
||||||
|
switch (scope) {
|
||||||
|
case UserInfo.PermissionScopeAdmin:
|
||||||
|
// Set the default permission for non admin
|
||||||
|
adjustedScopes = UserInfo.PermissionScopeAccessAllThings | UserInfo.PermissionScopeControlThings | UserInfo.PermissionScopeExecuteRules
|
||||||
|
break;
|
||||||
|
case UserInfo.PermissionScopeControlThings:
|
||||||
|
adjustedScopes &= ~UserInfo.PermissionScopeConfigureThings
|
||||||
|
break;
|
||||||
|
case UserInfo.PermissionScopeConfigureThings:
|
||||||
|
// Note: PermissionScopeConfigureThings is 3 and unsets therefore also the abbility to control things.
|
||||||
|
adjustedScopes |= UserInfo.PermissionScopeControlThings
|
||||||
|
break;
|
||||||
|
case UserInfo.PermissionScopeAccessAllThings:
|
||||||
|
adjustedScopes &= ~UserInfo.PermissionScopeConfigureThings
|
||||||
|
adjustedScopes &= ~UserInfo.PermissionScopeExecuteRules
|
||||||
|
adjustedScopes &= ~UserInfo.PermissionScopeConfigureRules
|
||||||
|
// Make sure we still can controll those things we added
|
||||||
|
adjustedScopes |= UserInfo.PermissionScopeControlThings
|
||||||
|
break;
|
||||||
|
case UserInfo.PermissionScopeExecuteRules:
|
||||||
|
adjustedScopes &= ~UserInfo.PermissionScopeConfigureRules
|
||||||
|
break;
|
||||||
|
case UserInfo.PermissionScopeConfigureRules:
|
||||||
|
// Note: PermissionScopeConfigureRules constand unsets therefore also the abbility to execute rules (screnes).
|
||||||
|
adjustedScopes |= UserInfo.PermissionScopeExecuteRules
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return adjustedScopes
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasPermissionScope(permissions, requestedScope) {
|
function hasPermissionScope(permissions, requestedScope) {
|
||||||
|
|
@ -202,7 +293,7 @@ Item {
|
||||||
|
|
||||||
function rgb2hsv(r,g,b) {
|
function rgb2hsv(r,g,b) {
|
||||||
var v=Math.max(r,g,b), c=v-Math.min(r,g,b);
|
var v=Math.max(r,g,b), c=v-Math.min(r,g,b);
|
||||||
var h= c && ((v==r) ? (g-b)/c : ((v==g) ? 2+(b-r)/c : 4+(r-g)/c));
|
var h= c && ((v===r) ? (g-b)/c : ((v===g) ? 2+(b-r)/c : 4+(r-g)/c));
|
||||||
return [60*(h<0?h+6:h), v&&c/v, v];
|
return [60*(h<0?h+6:h), v&&c/v, v];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue