Configuration split to lists, send configurations and server config.

This is before testing.
This commit is contained in:
Tomas Bures 2018-04-22 17:33:43 +02:00
parent 4fce4b6f81
commit c12efeb97f
40 changed files with 819 additions and 311 deletions

View file

@ -13,7 +13,7 @@ const segments = require('./segments');
const UnsubscriptionMode = require('../shared/lists').UnsubscriptionMode;
const allowedKeys = new Set(['name', 'description', 'default_form', 'public_subscribe', 'unsubscription_mode', 'namespace']);
const allowedKeys = new Set(['name', 'description', 'default_form', 'public_subscribe', 'unsubscription_mode', 'contact_email', 'homepage', 'namespace']);
function hash(entity) {
return hasher.hash(filterObject(entity, allowedKeys));

View file

@ -7,9 +7,9 @@ const { enforce, filterObject } = require('../lib/helpers');
const interoperableErrors = require('../shared/interoperable-errors');
const shares = require('./shares');
const namespaceHelpers = require('../lib/namespace-helpers');
const {MailerType} = require('../shared/send-configurations');
const {MailerType, getSystemSendConfigurationId} = require('../shared/send-configurations');
const allowedKeys = new Set(['name', 'description', 'from_email', 'from_email_overridable', 'from_name', 'from_name_overridable', 'subject', 'subject_overridable', 'mailer_type', 'mailer_settings', 'namespace']);
const allowedKeys = new Set(['name', 'description', 'from_email', 'from_email_overridable', 'from_name', 'from_name_overridable', 'subject', 'subject_overridable', 'verp_hostname', 'mailer_type', 'mailer_settings', 'namespace']);
function hash(entity) {
@ -95,6 +95,10 @@ async function updateWithConsistencyCheck(context, entity) {
}
async function remove(context, id) {
if (id === getSystemSendConfigurationId()) {
shares.throwPermissionDenied();
}
await knex.transaction(async tx => {
await shares.enforceEntityPermissionTx(tx, context, 'sendConfiguration', id, 'delete');

View file

@ -1,17 +1,23 @@
'use strict';
const knex = require('../lib/knex');
const { filterObject } = require('../lib/helpers');
const hasher = require('node-object-hash')();
const shares = require('./shares');
const allowedKeys = new Set(['adminEmail', 'uaCode', 'pgpPassphrase', 'pgpPrivateKey', 'defaultHomepage']);
const allowedKeys = new Set(['adminEmail', 'uaCode', 'shoutout', 'pgpPassphrase', 'pgpPrivateKey', 'defaultHomepage']);
// defaultHomepage is used as a default to list.homepage - if the list.homepage is not filled in
function hash(entity) {
return hasher.hash(filterObject(entity, allowedKeys));
}
async function get(context, keyOrKeys) {
shares.enforceGlobalPermission(context, 'manageSettings');
let keys;
if (!keyOrKeys) {
keys = allowedKeys.values();
keys = [...allowedKeys.values()];
} else if (!Array.isArray(keyOrKeys)) {
keys = [ keys ];
} else {
@ -25,7 +31,7 @@ async function get(context, keyOrKeys) {
settings[row.key] = row.value;
}
if (!Array.isArray(keyOrKeys)) {
if (!Array.isArray(keyOrKeys) && keyOrKeys) {
return settings[keyOrKeys];
} else {
return settings;
@ -48,6 +54,7 @@ async function set(context, data) {
}
module.exports = {
hash,
get,
set
};

View file

@ -1,6 +1,5 @@
'use strict';
let _ = require('../lib/translate')._;
const knex = require('../lib/knex');
const config = require('config');
const { enforce } = require('../lib/helpers');
@ -8,6 +7,7 @@ const dtHelpers = require('../lib/dt-helpers');
const permissions = require('../lib/permissions');
const interoperableErrors = require('../shared/interoperable-errors');
const log = require('npmlog');
const {getGlobalNamespaceId} = require('../shared/namespaces');
// TODO: This would really benefit from some permission cache connected to rebuildPermissions
// A bit of the problem is that the cache would have to expunged as the result of other processes modifying entites/permissions
@ -190,7 +190,7 @@ async function rebuildPermissionsTx(tx, restriction) {
const usersWithRoleInRootNamespaceQuery = tx('users')
.leftJoin(namespaceEntityType.sharesTable, {
'users.id': `${namespaceEntityType.sharesTable}.user`,
[`${namespaceEntityType.sharesTable}.entity`]: 1 /* Global namespace id */
[`${namespaceEntityType.sharesTable}.entity`]: getGlobalNamespaceId()
})
.select(['users.id', 'users.role as userRole', `${namespaceEntityType.sharesTable}.role`]);
if (restriction.userId) {
@ -204,8 +204,8 @@ async function rebuildPermissionsTx(tx, restriction) {
if (roleConf) {
const desiredRole = roleConf.rootNamespaceRole;
if (desiredRole && user.role !== desiredRole) {
await tx(namespaceEntityType.sharesTable).where({ user: user.id, entity: 1 /* Global namespace id */ }).del();
await tx(namespaceEntityType.sharesTable).insert({ user: user.id, entity: 1 /* Global namespace id */, role: desiredRole, auto: 1 });
await tx(namespaceEntityType.sharesTable).where({ user: user.id, entity: getGlobalNamespaceId() }).del();
await tx(namespaceEntityType.sharesTable).insert({ user: user.id, entity: getGlobalNamespaceId(), role: desiredRole, auto: 1 });
}
}
}
@ -393,7 +393,7 @@ async function regenerateRoleNamesTable() {
function throwPermissionDenied() {
throw new interoperableErrors.PermissionDeniedError(_('Permission denied'));
throw new interoperableErrors.PermissionDeniedError('Permission denied');
}
async function removeDefaultShares(tx, user) {
@ -409,7 +409,7 @@ async function removeDefaultShares(tx, user) {
}
if (roleConf.rootNamespaceRole) {
await tx(namespaceEntityType.sharesTable).where({ user: user.id, entity: 1 /* Global namespace id */ }).del();
await tx(namespaceEntityType.sharesTable).where({ user: user.id, entity: getGlobalNamespaceId() }).del();
}
}
}