diff --git a/editor/js/main.js b/editor/js/main.js
index 9352cd18d..b6b06b1a8 100644
--- a/editor/js/main.js
+++ b/editor/js/main.js
@@ -104,42 +104,48 @@
}
if (notificationId === "runtime-state") {
if (msg.error === "credentials_load_failed") {
- options.buttons = [
- {
- text: "Setup credentials",
- click: function() {
- RED.projects.showCredentialsPrompt();
+ if (RED.user.hasPermission("projects.write")) {
+ options.buttons = [
+ {
+ text: "Setup credentials",
+ click: function() {
+ RED.projects.showCredentialsPrompt();
+ }
}
- }
- ]
+ ]
+ }
} else if (msg.error === "missing_flow_file") {
- options.buttons = [
- {
- text: "Setup project files",
- click: function() {
- persistentNotifications[notificationId].close();
- delete persistentNotifications[notificationId];
- RED.projects.showFilesPrompt();
+ if (RED.user.hasPermission("projects.write")) {
+ options.buttons = [
+ {
+ text: "Setup project files",
+ click: function() {
+ persistentNotifications[notificationId].close();
+ delete persistentNotifications[notificationId];
+ RED.projects.showFilesPrompt();
+ }
}
- }
- ]
+ ]
+ }
} else if (msg.error === "project_empty") {
- options.buttons = [
- {
- text: "No thanks",
- click: function() {
- persistentNotifications[notificationId].close();
- delete persistentNotifications[notificationId];
+ if (RED.user.hasPermission("projects.write")) {
+ options.buttons = [
+ {
+ text: "No thanks",
+ click: function() {
+ persistentNotifications[notificationId].close();
+ delete persistentNotifications[notificationId];
+ }
+ }, {
+ text: "Create default project files",
+ click: function() {
+ persistentNotifications[notificationId].close();
+ delete persistentNotifications[notificationId];
+ RED.projects.createDefaultFileSet();
+ }
}
- }, {
- text: "Create default project files",
- click: function() {
- persistentNotifications[notificationId].close();
- delete persistentNotifications[notificationId];
- RED.projects.createDefaultFileSet();
- }
- }
- ]
+ ]
+ }
}
}
if (!persistentNotifications.hasOwnProperty(notificationId)) {
diff --git a/editor/js/settings.js b/editor/js/settings.js
index 19a385166..9594bec43 100644
--- a/editor/js/settings.js
+++ b/editor/js/settings.js
@@ -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,23 +161,25 @@ RED.settings = (function () {
}
function saveUserSettings() {
- if (pendingSave) {
- clearTimeout(pendingSave);
+ if (RED.user.hasPermission("settings.write")) {
+ if (pendingSave) {
+ clearTimeout(pendingSave);
+ }
+ pendingSave = setTimeout(function() {
+ pendingSave = null;
+ $.ajax({
+ method: 'POST',
+ contentType: 'application/json',
+ url: 'settings/user',
+ data: JSON.stringify(userSettings),
+ success: function (data) {
+ },
+ error: function(jqXHR,textStatus,errorThrown) {
+ console.log("Unexpected error saving user settings:",jqXHR.status,textStatus);
+ }
+ });
+ },300);
}
- pendingSave = setTimeout(function() {
- pendingSave = null;
- $.ajax({
- method: 'POST',
- contentType: 'application/json',
- url: 'settings/user',
- data: JSON.stringify(userSettings),
- success: function (data) {
- },
- error: function(jqXHR,textStatus,errorThrown) {
- console.log("Unexpected error saving user settings:",jqXHR.status,textStatus);
- }
- });
- },300);
}
function theme(property,defaultValue) {
diff --git a/editor/js/ui/deploy.js b/editor/js/ui/deploy.js
index 956742c56..b967f4db8 100644
--- a/editor/js/ui/deploy.js
+++ b/editor/js/ui/deploy.js
@@ -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;
diff --git a/editor/js/ui/projects/projectSettings.js b/editor/js/ui/projects/projectSettings.js
index a4221205b..5bf4a3d18 100644
--- a/editor/js/ui/projects/projectSettings.js
+++ b/editor/js/ui/projects/projectSettings.js
@@ -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 = $('
').appendTo(pane);
var summaryContent = $('
',{style:"color: #999"}).appendTo(summary);
updateProjectSummary(activeProject.summary, summaryContent);
- $('
')
- .prependTo(summary)
- .click(function(evt) {
- evt.preventDefault();
- editSummary(activeProject, activeProject.summary, summaryContent);
- });
+ if (RED.user.hasPermission("projects.write")) {
+ $('
')
+ .prependTo(summary)
+ .click(function(evt) {
+ evt.preventDefault();
+ editSummary(activeProject, activeProject.summary, summaryContent);
+ });
+ }
$('
').appendTo(pane);
var description = $('
').appendTo(pane);
@@ -239,13 +246,14 @@ RED.projects.settings = (function() {
updateProjectDescription(activeProject, descriptionContent);
- $('
')
- .prependTo(description)
- .click(function(evt) {
- evt.preventDefault();
- editDescription(activeProject, descriptionContent);
- });
-
+ if (RED.user.hasPermission("projects.write")) {
+ $('
')
+ .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 = $('
');
- $('
')
- .appendTo(pane)
- .click(function(evt) {
- evt.preventDefault();
- editDependencies(activeProject,null,pane,depsList)
- });
+ if (RED.user.hasPermission("projects.write")) {
+ $('
')
+ .appendTo(pane)
+ .click(function(evt) {
+ evt.preventDefault();
+ editDependencies(activeProject,null,pane,depsList)
+ });
+ }
var depsList = $("
",{style:"position: absolute;top: 60px;bottom: 20px;left: 20px;right: 20px;"}).appendTo(pane);
depsList.editableList({
addButton: false,
@@ -368,28 +378,30 @@ RED.projects.settings = (function() {
row.parent().addClass("palette-module-section");
}
headerRow.text(entry.label);
- if (entry.index === 1) {
- var addButton = $('').appendTo(headerRow).click(function(evt) {
- evt.preventDefault();
- var deps = $.extend(true, {}, activeProject.dependencies);
- for (var m in modulesInUse) {
- if (modulesInUse.hasOwnProperty(m) && !modulesInUse[m].known) {
- deps[m] = modulesInUse[m].version;
+ if (RED.user.hasPermission("projects.write")) {
+ if (entry.index === 1) {
+ var addButton = $('').appendTo(headerRow).click(function(evt) {
+ evt.preventDefault();
+ var deps = $.extend(true, {}, activeProject.dependencies);
+ for (var m in modulesInUse) {
+ if (modulesInUse.hasOwnProperty(m) && !modulesInUse[m].known) {
+ deps[m] = modulesInUse[m].version;
+ }
}
- }
- editDependencies(activeProject,JSON.stringify(deps,"",4),pane,depsList);
- });
- } else if (entry.index === 3) {
- var removeButton = $('').appendTo(headerRow).click(function(evt) {
- evt.preventDefault();
- var deps = $.extend(true, {}, activeProject.dependencies);
- for (var m in activeProject.dependencies) {
- if (activeProject.dependencies.hasOwnProperty(m) && !modulesInUse.hasOwnProperty(m)) {
- delete deps[m];
+ editDependencies(activeProject,JSON.stringify(deps,"",4),pane,depsList);
+ });
+ } else if (entry.index === 3) {
+ var removeButton = $('').appendTo(headerRow).click(function(evt) {
+ evt.preventDefault();
+ var deps = $.extend(true, {}, activeProject.dependencies);
+ for (var m in activeProject.dependencies) {
+ if (activeProject.dependencies.hasOwnProperty(m) && !modulesInUse.hasOwnProperty(m)) {
+ delete deps[m];
+ }
}
- }
- editDependencies(activeProject,JSON.stringify(deps,"",4),pane,depsList);
- });
+ editDependencies(activeProject,JSON.stringify(deps,"",4),pane,depsList);
+ });
+ }
}
} else {
headerRow.addClass("palette-module-header");
@@ -630,26 +642,27 @@ RED.projects.settings = (function() {
function createFilesSection(activeProject,pane) {
var title = $('').text("Files").appendTo(pane);
var filesContainer = $('').appendTo(pane);
- var editFilesButton = $('')
- .appendTo(title)
- .click(function(evt) {
- evt.preventDefault();
- formButtons.show();
- editFilesButton.hide();
- flowFileLabelText.hide();
- flowFileInput.show();
- flowFileInputSearch.show();
- credFileLabel.hide();
- credFileInput.show();
- flowFileInput.focus();
- // credentialStateLabel.parent().hide();
- credentialStateLabel.addClass("uneditable-input");
- $(".user-settings-row-credentials").show();
- credentialStateLabel.css('height','auto');
- credentialFormRows.hide();
- credentialSecretButtons.show();
- });
-
+ if (RED.user.hasPermission("projects.write")) {
+ var editFilesButton = $('')
+ .appendTo(title)
+ .click(function(evt) {
+ evt.preventDefault();
+ formButtons.show();
+ editFilesButton.hide();
+ flowFileLabelText.hide();
+ flowFileInput.show();
+ flowFileInputSearch.show();
+ credFileLabel.hide();
+ credFileInput.show();
+ flowFileInput.focus();
+ // credentialStateLabel.parent().hide();
+ credentialStateLabel.addClass("uneditable-input");
+ $(".user-settings-row-credentials").show();
+ credentialStateLabel.css('height','auto');
+ credentialFormRows.hide();
+ credentialSecretButtons.show();
+ });
+ }
var row;
// Flow files
diff --git a/editor/js/ui/projects/projects.js b/editor/js/ui/projects/projects.js
index a559c798a..ff7981400 100644
--- a/editor/js/ui/projects/projects.js
+++ b/editor/js/ui/projects/projects.js
@@ -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,
diff --git a/editor/js/ui/projects/tab-versionControl.js b/editor/js/ui/projects/tab-versionControl.js
index 89c577677..62746e723 100644
--- a/editor/js/ui/projects/tab-versionControl.js
+++ b/editor/js/ui/projects/tab-versionControl.js
@@ -283,7 +283,10 @@ RED.sidebar.versionControl = (function() {
refreshFiles(result);
});
}
- })
+ });
+ RED.events.on("login",function() {
+ refresh(true);
+ });
sidebarContent = $('', {class:"sidebar-version-control"});
var stackContainer = $("
",{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();
diff --git a/editor/js/ui/userSettings.js b/editor/js/ui/userSettings.js
index 594129f87..59bf085b1 100644
--- a/editor/js/ui/userSettings.js
+++ b/editor/js/ui/userSettings.js
@@ -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;
diff --git a/editor/js/user.js b/editor/js/user.js
index 063f4d243..4d004a218 100644
--- a/editor/js/user.js
+++ b/editor/js/user.js
@@ -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
Warning: __message__",