diff --git a/access-control.md b/access-control.md index 8e99b6a1..aad39e45 100644 --- a/access-control.md +++ b/access-control.md @@ -60,9 +60,18 @@ A namespace role further defines allowed operations for entity types within and The following defines the role master for scope "global". This effectively means that in "Create/Edit User" form, the user can be given role "Master". -The role gives the permission to rebuild the permission cache. Further, it specifies that the +The role gives the permission to rebuild the permission cache. + +Further, it specifies that the holder of the role will automatically be given access (share) to the root namespace in the -namespace role "master". This role is also an admin role, which means that user id 1 will always be reset to this role. +namespace role "master" (specified by ```rootNamespaceRole="master"```). This access to the root namespace is given irrespective of the namespace +in which the user is created. This highlight the dual purpose of namespaces: a) they group +entities w.r.t. access management, b) they allow categorizing entities and users in a hierarchy +to potentially reflect the organisational or process hierarchy. The latter is especially useful for +more enterprise applications where a single installation of Mailtrain serves a number of rather +independent groups. + +The global role defined below is also an admin role (denoted by the ```admin=true```), which means that user id 1 will always be reset to this role. This serves as a kind of bootstrap that makes sure that there is always a user that can be used to give access to other users. ``` @@ -74,11 +83,23 @@ permissions=["rebuildPermissions"] rootNamespaceRole="master" ``` -This defines the role "master" for "report" entities. It lists the operations that a user +Another example for a global role is the following. This one is intended for regular users. +As such, it does not automatically give access to everything. Rather, it gives limited access +to entities under the namespace in which the user has been created. This is specified by the +```ownNamespaceRole="editor"``` +``` +[roles.global.editor] +name="Editor" +description="Anything under own namespace except operations related to sending and doing reports" +permissions=[] +ownNamespaceRole="editor" +``` + +The roles for entities are defined in a similar fashion. The example below shows the definition +of the role "master" for "report" entities. It lists the operations that a user that has "master" access to a particular report can do with the report. Note that to get the "master" access to a particular report through this role, the report would either have to be shared with the user -with role "master". - +with role "master". ``` [roles.report.master] name="Master" @@ -86,6 +107,14 @@ description="All permissions" permissions=["view", "edit", "delete", "share", "execute", "viewContent", "viewOutput"] ``` +The same for the restricted role "editor" can look as follows. +``` +[roles.report.editor] +name="Editor" +description="Anything under own namespace except operations related to sending and doing reports" +permissions=["view", "viewContent", "viewOutput"] +``` + The following defines the role "master" for "namespace" entities. Similarly to the example above, it lists operations that relate to a namespace. In particular all "create" operations pertain to a namespace rathen than to an entity, which at the time of creation does not exist yet. @@ -101,4 +130,12 @@ permissions=["view", "edit", "delete", "share", "createNamespace", "createReport reportTemplate=["view", "edit", "delete", "share", "execute"] report=["view", "edit", "delete", "share", "execute", "viewContent", "viewOutput"] namespace=["view", "edit", "delete", "share", "createNamespace", "createReportTemplate", "createReport", "manageUsers"] +``` + +And the same for the more restricted role "editor". +``` +[roles.namespace.editor.children] +reportTemplate=[] +report=["view", "viewContent", "viewOutput"] +namespace=["view", "edit", "delete"] ``` \ No newline at end of file diff --git a/app.js b/app.js index 64039a41..dc876977 100644 --- a/app.js +++ b/app.js @@ -22,14 +22,14 @@ const tools = require('./lib/tools'); const contextHelpers = require('./lib/context-helpers'); const routes = require('./routes/index'); -const lists = require('./routes/lists'); +const lists = require('./routes/lists-legacy'); const settings = require('./routes/settings'); const settingsModel = require('./lib/models/settings'); const templates = require('./routes/templates'); const campaigns = require('./routes/campaigns'); const links = require('./routes/links'); const fields = require('./routes/fields'); -const forms = require('./routes/forms'); +const forms = require('./routes/forms-legacy'); const segments = require('./routes/segments'); const triggers = require('./routes/triggers'); const webhooks = require('./routes/webhooks'); @@ -51,12 +51,14 @@ const reportTemplatesRest = require('./routes/rest/report-templates'); const reportsRest = require('./routes/rest/reports'); const campaignsRest = require('./routes/rest/campaigns'); const listsRest = require('./routes/rest/lists'); +const formsRest = require('./routes/rest/forms'); const sharesRest = require('./routes/rest/shares'); const namespacesLegacyIntegration = require('./routes/namespaces-legacy-integration'); const usersLegacyIntegration = require('./routes/users-legacy-integration'); const accountLegacyIntegration = require('./routes/account-legacy-integration'); const reportsLegacyIntegration = require('./routes/reports-legacy-integration'); +const listsLegacyIntegration = require('./routes/lists-legacy-integration'); const interoperableErrors = require('./shared/interoperable-errors'); @@ -253,6 +255,7 @@ if (config.reports && config.reports.enabled === true) { app.use('/users', usersLegacyIntegration); app.use('/namespaces', namespacesLegacyIntegration); app.use('/account', accountLegacyIntegration); +app.use('/lists', listsLegacyIntegration); if (config.reports && config.reports.enabled === true) { app.use('/reports', reports); @@ -270,6 +273,7 @@ app.use('/rest', usersRest); app.use('/rest', accountRest); app.use('/rest', campaignsRest); app.use('/rest', listsRest); +app.use('/rest', formsRest); app.use('/rest', sharesRest); if (config.reports && config.reports.enabled === true) { @@ -329,6 +333,7 @@ if (app.get('env') === 'development') { return next(); } + console.log(err); if (req.needsJSONResponse) { const resp = { message: err.message, diff --git a/client/src/account/Login.js b/client/src/account/Login.js index b3b8c103..6d2c9770 100644 --- a/client/src/account/Login.js +++ b/client/src/account/Login.js @@ -105,7 +105,7 @@ export default class Login extends Component {