mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Better permission handling in editor
This commit is contained in:
parent
bb168d35a8
commit
1204cf1ba0
@ -104,6 +104,7 @@
|
||||
}
|
||||
if (notificationId === "runtime-state") {
|
||||
if (msg.error === "credentials_load_failed") {
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Setup credentials",
|
||||
@ -112,7 +113,9 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else if (msg.error === "missing_flow_file") {
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Setup project files",
|
||||
@ -123,7 +126,9 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else if (msg.error === "project_empty") {
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "No thanks",
|
||||
@ -142,6 +147,7 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!persistentNotifications.hasOwnProperty(notificationId)) {
|
||||
persistentNotifications[notificationId] = RED.notify(text,options);
|
||||
} else {
|
||||
|
@ -63,7 +63,7 @@ RED.settings = (function () {
|
||||
if (!hasLocalStorage()) {
|
||||
return;
|
||||
}
|
||||
if (key === "auth_tokens") {
|
||||
if (key === "auth-tokens") {
|
||||
localStorage.removeItem(key);
|
||||
} else {
|
||||
delete userSettings[key];
|
||||
@ -161,6 +161,7 @@ RED.settings = (function () {
|
||||
}
|
||||
|
||||
function saveUserSettings() {
|
||||
if (RED.user.hasPermission("settings.write")) {
|
||||
if (pendingSave) {
|
||||
clearTimeout(pendingSave);
|
||||
}
|
||||
@ -179,6 +180,7 @@ RED.settings = (function () {
|
||||
});
|
||||
},300);
|
||||
}
|
||||
}
|
||||
|
||||
function theme(property,defaultValue) {
|
||||
if (!RED.settings.editorTheme) {
|
||||
|
@ -286,6 +286,10 @@ RED.deploy = (function() {
|
||||
|
||||
function save(skipValidation,force) {
|
||||
if (!$("#btn-deploy").hasClass("disabled")) {
|
||||
if (!RED.user.hasPermission("flows.write")) {
|
||||
RED.notify(RED._("user.errors.deploy"),"error");
|
||||
return;
|
||||
}
|
||||
if (!skipValidation) {
|
||||
var hasUnknown = false;
|
||||
var hasInvalid = false;
|
||||
|
@ -40,6 +40,11 @@ RED.projects.settings = (function() {
|
||||
if (settingsVisible) {
|
||||
return;
|
||||
}
|
||||
if (!RED.user.hasPermission("projects.write")) {
|
||||
RED.notify(RED._("user.errors.notAuthorized"),"error");
|
||||
return;
|
||||
}
|
||||
|
||||
settingsVisible = true;
|
||||
var tabContainer;
|
||||
|
||||
@ -226,12 +231,14 @@ RED.projects.settings = (function() {
|
||||
var summary = $('<div style="position: relative">').appendTo(pane);
|
||||
var summaryContent = $('<div></div>',{style:"color: #999"}).appendTo(summary);
|
||||
updateProjectSummary(activeProject.summary, summaryContent);
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
$('<button class="editor-button editor-button-small" style="float: right;">edit</button>')
|
||||
.prependTo(summary)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
editSummary(activeProject, activeProject.summary, summaryContent);
|
||||
});
|
||||
}
|
||||
$('<hr>').appendTo(pane);
|
||||
|
||||
var description = $('<div class="node-help" style="position: relative"></div>').appendTo(pane);
|
||||
@ -239,13 +246,14 @@ RED.projects.settings = (function() {
|
||||
|
||||
updateProjectDescription(activeProject, descriptionContent);
|
||||
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
$('<button class="editor-button editor-button-small" style="float: right;">edit</button>')
|
||||
.prependTo(description)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
editDescription(activeProject, descriptionContent);
|
||||
});
|
||||
|
||||
}
|
||||
return pane;
|
||||
}
|
||||
function updateProjectDependencies(activeProject,depsList) {
|
||||
@ -349,12 +357,14 @@ RED.projects.settings = (function() {
|
||||
|
||||
function createDependenciesPane(activeProject) {
|
||||
var pane = $('<div id="project-settings-tab-deps" class="project-settings-tab-pane node-help"></div>');
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
$('<button class="editor-button editor-button-small" style="margin-top:10px;float: right;">edit</button>')
|
||||
.appendTo(pane)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
editDependencies(activeProject,null,pane,depsList)
|
||||
});
|
||||
}
|
||||
var depsList = $("<ol>",{style:"position: absolute;top: 60px;bottom: 20px;left: 20px;right: 20px;"}).appendTo(pane);
|
||||
depsList.editableList({
|
||||
addButton: false,
|
||||
@ -368,6 +378,7 @@ RED.projects.settings = (function() {
|
||||
row.parent().addClass("palette-module-section");
|
||||
}
|
||||
headerRow.text(entry.label);
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
if (entry.index === 1) {
|
||||
var addButton = $('<button class="editor-button editor-button-small palette-module-button">add to project</button>').appendTo(headerRow).click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@ -391,6 +402,7 @@ RED.projects.settings = (function() {
|
||||
editDependencies(activeProject,JSON.stringify(deps,"",4),pane,depsList);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
headerRow.addClass("palette-module-header");
|
||||
headerRow.toggleClass("palette-module-unused",entry.count === 0);
|
||||
@ -630,6 +642,7 @@ RED.projects.settings = (function() {
|
||||
function createFilesSection(activeProject,pane) {
|
||||
var title = $('<h3></h3>').text("Files").appendTo(pane);
|
||||
var filesContainer = $('<div class="user-settings-section"></div>').appendTo(pane);
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
var editFilesButton = $('<button class="editor-button editor-button-small" style="float: right;">edit</button>')
|
||||
.appendTo(title)
|
||||
.click(function(evt) {
|
||||
@ -649,7 +662,7 @@ RED.projects.settings = (function() {
|
||||
credentialFormRows.hide();
|
||||
credentialSecretButtons.show();
|
||||
});
|
||||
|
||||
}
|
||||
var row;
|
||||
|
||||
// Flow files
|
||||
|
@ -1753,6 +1753,10 @@ RED.projects = (function() {
|
||||
} else if (!activeProject.empty) {
|
||||
throw new Error("Cannot create default file set on a non-empty project");
|
||||
}
|
||||
if (!RED.user.hasPermission("projects.write")) {
|
||||
RED.notify(RED._("user.errors.notAuthorized"),"error");
|
||||
return;
|
||||
}
|
||||
createProjectOptions = {};
|
||||
show('default-files',{existingProject: true});
|
||||
// var payload = {
|
||||
@ -1805,11 +1809,18 @@ RED.projects = (function() {
|
||||
|
||||
return {
|
||||
init: init,
|
||||
_show: show,
|
||||
showStartup: function() {
|
||||
if (!RED.user.hasPermission("projects.write")) {
|
||||
RED.notify(RED._("user.errors.notAuthorized"),"error");
|
||||
return;
|
||||
}
|
||||
show('welcome');
|
||||
},
|
||||
newProject: function() {
|
||||
if (!RED.user.hasPermission("projects.write")) {
|
||||
RED.notify(RED._("user.errors.notAuthorized"),"error");
|
||||
return;
|
||||
}
|
||||
if (!activeProject) {
|
||||
show('welcome');
|
||||
} else {
|
||||
@ -1817,15 +1828,31 @@ RED.projects = (function() {
|
||||
}
|
||||
},
|
||||
selectProject: function() {
|
||||
if (!RED.user.hasPermission("projects.write")) {
|
||||
RED.notify(RED._("user.errors.notAuthorized"),"error");
|
||||
return;
|
||||
}
|
||||
show('open')
|
||||
},
|
||||
deleteProject: function() {
|
||||
if (!RED.user.hasPermission("projects.write")) {
|
||||
RED.notify(RED._("user.errors.notAuthorized"),"error");
|
||||
return;
|
||||
}
|
||||
show('delete')
|
||||
},
|
||||
showCredentialsPrompt: function() { //TODO: rename this function
|
||||
if (!RED.user.hasPermission("projects.write")) {
|
||||
RED.notify(RED._("user.errors.notAuthorized"),"error");
|
||||
return;
|
||||
}
|
||||
RED.projects.settings.show('settings');
|
||||
},
|
||||
showFilesPrompt: function() { //TODO: rename this function
|
||||
if (!RED.user.hasPermission("projects.write")) {
|
||||
RED.notify(RED._("user.errors.notAuthorized"),"error");
|
||||
return;
|
||||
}
|
||||
RED.projects.settings.show('settings');
|
||||
},
|
||||
createDefaultFileSet: createDefaultFileSet,
|
||||
|
@ -283,7 +283,10 @@ RED.sidebar.versionControl = (function() {
|
||||
refreshFiles(result);
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
RED.events.on("login",function() {
|
||||
refresh(true);
|
||||
});
|
||||
sidebarContent = $('<div>', {class:"sidebar-version-control"});
|
||||
var stackContainer = $("<div>",{class:"sidebar-version-control-stack"}).appendTo(sidebarContent);
|
||||
sections = RED.stack.create({
|
||||
@ -1175,6 +1178,10 @@ RED.sidebar.versionControl = (function() {
|
||||
stagedChangesList.editableList('empty');
|
||||
unmergedChangesList.editableList('empty');
|
||||
}
|
||||
if (!RED.user.hasPermission("projects.write")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
refreshInProgress = true;
|
||||
refreshLocalCommits();
|
||||
|
@ -29,6 +29,10 @@ RED.userSettings = (function() {
|
||||
if (settingsVisible) {
|
||||
return;
|
||||
}
|
||||
if (!RED.user.hasPermission("settings.write")) {
|
||||
RED.notify(RED._("user.errors.settings"),"error");
|
||||
return;
|
||||
}
|
||||
settingsVisible = true;
|
||||
var tabContainer;
|
||||
|
||||
|
@ -188,6 +188,7 @@ RED.user = (function() {
|
||||
RED.settings.load(function() {
|
||||
RED.notify(RED._("user.loggedInAs",{name:RED.settings.user.username}),"success");
|
||||
updateUserMenu();
|
||||
RED.events.emit("login",RED.settings.user.username);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -230,10 +231,66 @@ RED.user = (function() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var readRE = /^((.+)\.)?read$/
|
||||
var writeRE = /^((.+)\.)?write$/
|
||||
|
||||
function hasPermission(permission) {
|
||||
if (permission === "") {
|
||||
return true;
|
||||
}
|
||||
if (!RED.settings.user) {
|
||||
return true;
|
||||
}
|
||||
return checkPermission(RED.settings.user.permissions||"",permission);
|
||||
}
|
||||
function checkPermission(userScope,permission) {
|
||||
if (permission === "") {
|
||||
return true;
|
||||
}
|
||||
var i;
|
||||
|
||||
if (Array.isArray(permission)) {
|
||||
// Multiple permissions requested - check each one
|
||||
for (i=0;i<permission.length;i++) {
|
||||
if (!checkPermission(userScope,permission[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// All permissions check out
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Array.isArray(userScope)) {
|
||||
if (userScope.length === 0) {
|
||||
return false;
|
||||
}
|
||||
for (i=0;i<userScope.length;i++) {
|
||||
if (checkPermission(userScope[i],permission)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (userScope === "*" || userScope === permission) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userScope === "read" || userScope === "*.read") {
|
||||
return readRE.test(permission);
|
||||
} else if (userScope === "write" || userScope === "*.write") {
|
||||
return writeRE.test(permission);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
init: init,
|
||||
login: login,
|
||||
logout: logout
|
||||
logout: logout,
|
||||
hasPermission: hasPermission
|
||||
}
|
||||
|
||||
})();
|
||||
|
@ -23,6 +23,10 @@
|
||||
#project-settings-tab-settings {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.sidebar-version-control-shade {
|
||||
background: #f3f3f3;
|
||||
}
|
||||
|
||||
.projects-edit-form form {
|
||||
margin: 0;
|
||||
.form-row {
|
||||
|
@ -76,7 +76,12 @@
|
||||
"password": "Password",
|
||||
"login": "Login",
|
||||
"loginFailed": "Login failed",
|
||||
"notAuthorized": "Not authorized"
|
||||
"notAuthorized": "Not authorized",
|
||||
"errors": {
|
||||
"settings": "You must be logged in to access settings",
|
||||
"deploy": "You must be logged in to deploy changes",
|
||||
"notAuthorized": "You must be logged in to perform this action"
|
||||
}
|
||||
},
|
||||
"notification": {
|
||||
"warning": "<strong>Warning</strong>: __message__",
|
||||
|
Loading…
Reference in New Issue
Block a user