Privs small refactor
This commit is contained in:
@@ -2,9 +2,6 @@ angular.module('app').directive('infiniteScroll', [
|
|||||||
'$rootScope', '$window', '$timeout', function($rootScope, $window, $timeout) {
|
'$rootScope', '$window', '$timeout', function($rootScope, $window, $timeout) {
|
||||||
return {
|
return {
|
||||||
link: function(scope, elem, attrs) {
|
link: function(scope, elem, attrs) {
|
||||||
// elem.css('overflow-x', 'hidden');
|
|
||||||
// elem.css('height', 'inherit');
|
|
||||||
|
|
||||||
var offset = parseInt(attrs.threshold) || 0;
|
var offset = parseInt(attrs.threshold) || 0;
|
||||||
var e = elem[0]
|
var e = elem[0]
|
||||||
|
|
||||||
|
|||||||
@@ -24,35 +24,41 @@ class PrivilegesAuthModal {
|
|||||||
controller($scope, privilegesManager, $timeout) {
|
controller($scope, privilegesManager, $timeout) {
|
||||||
'ngInject';
|
'ngInject';
|
||||||
|
|
||||||
privilegesManager.requiredCredentialsForAction($scope.action).then((privs) => {
|
$scope.authenticationParameters = {};
|
||||||
|
|
||||||
|
privilegesManager.getPrivileges().then((privileges) => {
|
||||||
$timeout(() => {
|
$timeout(() => {
|
||||||
$scope.privileges = privs;
|
$scope.privileges = privileges;
|
||||||
|
$scope.requiredCredentials = privileges.getCredentialsForAction($scope.action);
|
||||||
})
|
})
|
||||||
})
|
});
|
||||||
|
|
||||||
|
$scope.promptForCredential = function(credential) {
|
||||||
|
return privilegesManager.displayInfoForCredential(credential).prompt;
|
||||||
|
}
|
||||||
|
|
||||||
$scope.cancel = function() {
|
$scope.cancel = function() {
|
||||||
$scope.dismiss();
|
$scope.dismiss();
|
||||||
$scope.onCancel && $scope.onCancel();
|
$scope.onCancel && $scope.onCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.doesPrivHaveFail = function(priv) {
|
$scope.isCredentialInFailureState = function(credential) {
|
||||||
if(!$scope.failedPrivs) {
|
if(!$scope.failedCredentials) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return $scope.failedPrivs.find((failedPriv) => {
|
return $scope.failedCredentials.find((candidate) => {
|
||||||
return failedPriv.name == priv.name;
|
return candidate == credential;
|
||||||
}) != null;
|
}) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.submit = function() {
|
$scope.submit = function() {
|
||||||
privilegesManager.authenticateAction($scope.action, $scope.privileges).then((result) => {
|
privilegesManager.authenticateAction($scope.action, $scope.authenticationParameters).then((result) => {
|
||||||
console.log("Result", result);
|
|
||||||
$timeout(() => {
|
$timeout(() => {
|
||||||
if(result.success) {
|
if(result.success) {
|
||||||
$scope.onSuccess();
|
$scope.onSuccess();
|
||||||
$scope.dismiss();
|
$scope.dismiss();
|
||||||
} else {
|
} else {
|
||||||
$scope.failedPrivs = result.failedPrivs;
|
$scope.failedCredentials = result.failedCredentials;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -17,36 +17,29 @@ class PrivilegesManagementModal {
|
|||||||
controller($scope, privilegesManager, $timeout) {
|
controller($scope, privilegesManager, $timeout) {
|
||||||
'ngInject';
|
'ngInject';
|
||||||
|
|
||||||
$scope.reloadPrivileges = async function() {
|
$scope.dummy = {};
|
||||||
console.log("Reloading privs");
|
|
||||||
$scope.availableActions = privilegesManager.getAvailableActions();
|
|
||||||
$scope.availableCredentials = privilegesManager.getAvailableCredentials();
|
|
||||||
|
|
||||||
let metadata = {};
|
$scope.displayInfoForCredential = function(credential) {
|
||||||
for(let action of $scope.availableActions) {
|
return privilegesManager.displayInfoForCredential(credential).label;
|
||||||
var requiredCreds = await privilegesManager.requiredCredentialsForAction(action);
|
|
||||||
metadata[action] = {
|
|
||||||
displayInfo: privilegesManager.displayInfoForAction(action),
|
|
||||||
requiredCredentials: requiredCreds
|
|
||||||
}
|
|
||||||
|
|
||||||
metadata[action]["credentialValues"] = {};
|
|
||||||
for(var availableCred of $scope.availableCredentials) {
|
|
||||||
metadata[action]["credentialValues"][availableCred] = requiredCreds.includes(availableCred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$timeout(() => {
|
|
||||||
$scope.metadata = metadata;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.checkboxValueChanged = function(action) {
|
$scope.displayInfoForAction = function(action) {
|
||||||
let credentialValues = $scope.metadata[action]["credentialValues"];
|
return privilegesManager.displayInfoForAction(action).label;
|
||||||
let keys = Object.keys(credentialValues).filter((key) => {
|
}
|
||||||
return credentialValues[key] == true;
|
|
||||||
});
|
$scope.isCredentialRequiredForAction = function(action, credential) {
|
||||||
privilegesManager.setCredentialsForAction(action, keys);
|
return $scope.privileges.isCredentialRequiredForAction(action, credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.reloadPrivileges = async function() {
|
||||||
|
$scope.privileges = await privilegesManager.getPrivileges();
|
||||||
|
$scope.availableActions = privilegesManager.getAvailableActions();
|
||||||
|
$scope.availableCredentials = privilegesManager.getAvailableCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.checkboxValueChanged = function(action, credential) {
|
||||||
|
$scope.privileges.toggleCredentialForAction(action, credential);
|
||||||
|
privilegesManager.savePrivileges();
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.reloadPrivileges();
|
$scope.reloadPrivileges();
|
||||||
|
|||||||
34
app/assets/javascripts/app/models/privileges.js
Normal file
34
app/assets/javascripts/app/models/privileges.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
class SNPrivileges extends SFItem {
|
||||||
|
|
||||||
|
setCredentialsForAction(action, credentials) {
|
||||||
|
this.content.desktopPrivileges[action] = credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCredentialsForAction(action) {
|
||||||
|
return this.content.desktopPrivileges[action] || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleCredentialForAction(action, credential) {
|
||||||
|
if(this.isCredentialRequiredForAction(action, credential)) {
|
||||||
|
this.removeCredentialForAction(action, credential);
|
||||||
|
} else {
|
||||||
|
this.addCredentialForAction(action, credential);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeCredentialForAction(action, credential) {
|
||||||
|
_.pull(this.content.desktopPrivileges[action], credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
addCredentialForAction(action, credential) {
|
||||||
|
var credentials = this.getCredentialsForAction(action);
|
||||||
|
credentials.push(credential);
|
||||||
|
this.setCredentialsForAction(action, credentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
isCredentialRequiredForAction(action, credential) {
|
||||||
|
var credentialsRequired = this.getCredentialsForAction(action);
|
||||||
|
return credentialsRequired.includes(credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,7 +7,8 @@ SFModelManager.ContentTypeClassMapping = {
|
|||||||
"SN|Theme" : SNTheme,
|
"SN|Theme" : SNTheme,
|
||||||
"SN|Component" : SNComponent,
|
"SN|Component" : SNComponent,
|
||||||
"SF|Extension" : SNServerExtension,
|
"SF|Extension" : SNServerExtension,
|
||||||
"SF|MFA" : SNMfa
|
"SF|MFA" : SNMfa,
|
||||||
|
"SN|Privileges" : SNPrivileges
|
||||||
};
|
};
|
||||||
|
|
||||||
SFItem.AppDomain = "org.standardnotes.sn";
|
SFItem.AppDomain = "org.standardnotes.sn";
|
||||||
|
|||||||
@@ -74,12 +74,12 @@ class PrivilegesManager {
|
|||||||
this.singletonManager.registerSingleton([contentTypePredicate], (resolvedSingleton) => {
|
this.singletonManager.registerSingleton([contentTypePredicate], (resolvedSingleton) => {
|
||||||
this.privileges = resolvedSingleton;
|
this.privileges = resolvedSingleton;
|
||||||
if(!this.privileges.content.desktopPrivileges) {
|
if(!this.privileges.content.desktopPrivileges) {
|
||||||
this.privileges.content.desktopPrivileges = [];
|
this.privileges.content.desktopPrivileges = {};
|
||||||
}
|
}
|
||||||
resolve(resolvedSingleton);
|
resolve(resolvedSingleton);
|
||||||
}, (valueCallback) => {
|
}, (valueCallback) => {
|
||||||
// Safe to create. Create and return object.
|
// Safe to create. Create and return object.
|
||||||
var privs = new SFItem({content_type: prefsContentType});
|
var privs = new Privilege({content_type: prefsContentType});
|
||||||
this.modelManager.addItem(privs);
|
this.modelManager.addItem(privs);
|
||||||
privs.setDirty(true);
|
privs.setDirty(true);
|
||||||
this.$rootScope.sync();
|
this.$rootScope.sync();
|
||||||
@@ -97,11 +97,6 @@ class PrivilegesManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async requiredCredentialsForAction(action) {
|
|
||||||
let privs = await this.getPrivileges();
|
|
||||||
return privs.content.desktopPrivileges[action] || [];
|
|
||||||
}
|
|
||||||
|
|
||||||
displayInfoForCredential(credential) {
|
displayInfoForCredential(credential) {
|
||||||
let metadata = {}
|
let metadata = {}
|
||||||
|
|
||||||
@@ -132,14 +127,7 @@ class PrivilegesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async actionRequiresPrivilege(action) {
|
async actionRequiresPrivilege(action) {
|
||||||
return (await this.requiredCredentialsForAction(action)).length > 0;
|
return (await this.getPrivileges()).getCredentialsForAction(action).length > 0;
|
||||||
}
|
|
||||||
|
|
||||||
async setCredentialsForAction(action, credentials) {
|
|
||||||
console.log("Setting credentials for action", action, credentials);
|
|
||||||
let privs = await this.getPrivileges();
|
|
||||||
privs.content.desktopPrivileges[action] = credentials;
|
|
||||||
this.savePrivileges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async savePrivileges() {
|
async savePrivileges() {
|
||||||
@@ -148,34 +136,27 @@ class PrivilegesManager {
|
|||||||
this.$rootScope.sync();
|
this.$rootScope.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
async authenticateAction(action, inputPrivs) {
|
async authenticateAction(action, credentialAuthMapping) {
|
||||||
|
var requiredCredentials = (await this.getPrivileges()).getCredentialsForAction(action);
|
||||||
|
var successfulCredentials = [], failedCredentials = [];
|
||||||
|
|
||||||
let findInputPriv = (name) => {
|
for(let requiredCredential of requiredCredentials) {
|
||||||
return inputPrivs.find((priv) => {
|
var passesAuth = await this._verifyAuthenticationParameters(requiredCredential, credentialAuthMapping[requiredCredential]);
|
||||||
return priv.name == name;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var requiredPrivileges = await this.requiredCredentialsForAction(action);
|
|
||||||
var successfulPrivs = [], failedPrivs = [];
|
|
||||||
for(let requiredPriv of requiredPrivileges) {
|
|
||||||
var matchingPriv = findInputPriv(requiredPriv.name);
|
|
||||||
var passesAuth = await this._verifyAuthenticationParameters(matchingPriv);
|
|
||||||
if(passesAuth) {
|
if(passesAuth) {
|
||||||
successfulPrivs.push(matchingPriv);
|
successfulCredentials.push(requiredCredential);
|
||||||
} else {
|
} else {
|
||||||
failedPrivs.push(matchingPriv);
|
failedCredentials.push(requiredCredential);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: failedPrivs.length == 0,
|
success: failedCredentials.length == 0,
|
||||||
successfulPrivs: successfulPrivs,
|
successfulCredentials: successfulCredentials,
|
||||||
failedPrivs: failedPrivs
|
failedCredentials: failedCredentials
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _verifyAuthenticationParameters(parameters) {
|
async _verifyAuthenticationParameters(credential, value) {
|
||||||
|
|
||||||
let verifyAccountPassword = async (password) => {
|
let verifyAccountPassword = async (password) => {
|
||||||
return this.authManager.verifyAccountPassword(password);
|
return this.authManager.verifyAccountPassword(password);
|
||||||
@@ -185,10 +166,10 @@ class PrivilegesManager {
|
|||||||
return this.passcodeManager.verifyPasscode(passcode);
|
return this.passcodeManager.verifyPasscode(passcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(parameters.name == PrivilegesManager.CredentialAccountPassword) {
|
if(credential == PrivilegesManager.CredentialAccountPassword) {
|
||||||
return verifyAccountPassword(parameters.authenticationValue);
|
return verifyAccountPassword(value);
|
||||||
} else if(parameters.name == PrivilegesManager.CredentialLocalPasscode) {
|
} else if(credential == PrivilegesManager.CredentialLocalPasscode) {
|
||||||
return verifyLocalPasscode(parameters.authenticationValue);
|
return verifyLocalPasscode(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
%a.close-button.info{"ng-click" => "cancel()"} Cancel
|
%a.close-button.info{"ng-click" => "cancel()"} Cancel
|
||||||
.content
|
.content
|
||||||
.panel-section
|
.panel-section
|
||||||
.panel-row{"ng-repeat" => "priv in privileges"}
|
.panel-row{"ng-repeat" => "credential in requiredCredentials"}
|
||||||
%p {{priv.prompt}}
|
%p {{promptForCredential(credential)}}
|
||||||
%input{"type" => "password", "ng-model" => "priv.authenticationValue"}
|
%input{"type" => "password", "ng-model" => "authenticationParameters[credential]"}
|
||||||
%label.danger{"ng-if" => "doesPrivHaveFail(priv)"} Invalid authentication. Please try again.
|
%label.danger{"ng-if" => "isCredentialInFailureState(credential)"} Invalid authentication. Please try again.
|
||||||
|
|
||||||
.footer
|
.footer
|
||||||
.button.info.big.block.bold{"ng-click" => "submit()"} Submit
|
.button.info.big.block.bold{"ng-click" => "submit()"} Submit
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
.panel
|
.panel
|
||||||
.header
|
.header
|
||||||
%h1.title Manage Privileges
|
%h1.title Manage Privileges
|
||||||
%a.close-button.info{"ng-click" => "cancel()"} Cancel
|
%a.close-button.info{"ng-click" => "cancel()"} Done
|
||||||
.content
|
.content
|
||||||
.panel-section
|
.panel-section
|
||||||
%table
|
%table
|
||||||
@@ -13,13 +13,10 @@
|
|||||||
%tr
|
%tr
|
||||||
%th
|
%th
|
||||||
%th{"ng-repeat" => "cred in availableCredentials"}
|
%th{"ng-repeat" => "cred in availableCredentials"}
|
||||||
{{cred}}
|
{{displayInfoForCredential(cred)}}
|
||||||
%tbody
|
%tbody
|
||||||
%tr{"ng-repeat" => "action in availableActions"}
|
%tr{"ng-repeat" => "action in availableActions"}
|
||||||
%td
|
%td
|
||||||
%p {{metadata[action].displayInfo.label}}
|
%p {{displayInfoForAction(action)}}
|
||||||
%th{"ng-repeat" => "cred in availableCredentials"}
|
%th{"ng-repeat" => "credential in availableCredentials"}
|
||||||
%input{"type" => "checkbox", "ng-model" => "metadata[action]['credentialValues'][cred]", "ng-change" => "checkboxValueChanged(action)"}
|
%input{"type" => "checkbox", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"}
|
||||||
|
|
||||||
.footer
|
|
||||||
.button.info.big.block.bold{"ng-click" => "submit()"} Save
|
|
||||||
|
|||||||
Reference in New Issue
Block a user