Message ACS improvements & minor fixes

+ getSuitableMessageConfAndAreaTags(): Get a suitable conf/area tag pair with priority on defaults
+ hasMessageConfAndAreaRead() helper
+ filterMessageAreaTagsByReadACS() helper
* Always include confTag/areaTag when fetching a conf or area (convenience)
* Fix 'toRemoteUser' assignment in message
* Better kick out of message conf/areas users does not have access to
This commit is contained in:
Bryan Ashby 2019-09-11 21:21:33 -06:00
parent 8027a73ea5
commit dff8e12dcc
No known key found for this signature in database
GPG Key ID: B49EB437951D2542
3 changed files with 84 additions and 28 deletions

View File

@ -307,7 +307,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
fromUserId : _.get(this.message, 'meta.System.local_from_user_id', localUserIdNotAvail),
toUserId : _.get(this.message, 'meta.System.local_to_user_id', localUserIdNotAvail),
fromRemoteUser : _.get(this.message, 'meta.System.remote_from_user', remoteUserNotAvail),
toRemoteUser : _.get(this.messgae, 'meta.System.remote_to_user', remoteUserNotAvail),
toRemoteUser : _.get(this.message, 'meta.System.remote_to_user', remoteUserNotAvail),
subject : this.message.subject,
modTimestamp : this.message.modTimestamp.format(modTimestampFormat),
msgNum : this.messageIndex + 1,

View File

@ -26,10 +26,13 @@ exports.getAvailableMessageAreasByConfTag = getAvailableMessageAreasByConfTag;
exports.getSortedAvailMessageAreasByConfTag = getSortedAvailMessageAreasByConfTag;
exports.getDefaultMessageConferenceTag = getDefaultMessageConferenceTag;
exports.getDefaultMessageAreaTagByConfTag = getDefaultMessageAreaTagByConfTag;
exports.getSuitableMessageConfAndAreaTags = getSuitableMessageConfAndAreaTags;
exports.getMessageConferenceByTag = getMessageConferenceByTag;
exports.getMessageAreaByTag = getMessageAreaByTag;
exports.changeMessageConference = changeMessageConference;
exports.changeMessageArea = changeMessageArea;
exports.hasMessageConfAndAreaRead = hasMessageConfAndAreaRead;
exports.filterMessageAreaTagsByReadACS = filterMessageAreaTagsByReadACS;
exports.tempChangeMessageConfAndArea = tempChangeMessageConfAndArea;
exports.getMessageListForArea = getMessageListForArea;
exports.getNewMessageCountInAreaForUser = getNewMessageCountInAreaForUser;
@ -185,7 +188,10 @@ function getDefaultMessageAreaTagByConfTag(client, confTag, disableAcsCheck) {
}
}
defaultArea = _.findKey(areaPool, (area) => {
defaultArea = _.findKey(areaPool, (area, areaTag) => {
if(Message.isPrivateAreaTag(areaTag)) {
return false;
}
return (true === disableAcsCheck || client.acs.hasMessageAreaRead(area));
});
@ -193,8 +199,47 @@ function getDefaultMessageAreaTagByConfTag(client, confTag, disableAcsCheck) {
}
}
function getSuitableMessageConfAndAreaTags(client) {
//
// Attempts to get a pair of suitable conf/area tags:
// * Where the client/user has proper ACS to both
// * Try to use defaults where possible
// * If default conf/area is not an option, use any
// that pass ACS.
// * Returns a tuple [confTag, areaTag]; areaTag
// and possibly confTag may both be set to '' if
// if we fail to find something.
//
let confTag = getDefaultMessageConferenceTag(client);
if(!confTag) {
return ['', '']; // can't have an area without a conf
}
let areaTag = getDefaultMessageAreaTagByConfTag(client, confTag);
if(!areaTag) {
// OK, perhaps *any* area in *any* conf?
_.forEach(Config().messageConferences, (conf, ct) => {
if(!client.acs.hasMessageConfRead(conf)) {
return;
}
_.forEach(conf.areas, (area, at) => {
if(!_.includes(Message.WellKnownAreaTags, at) && client.acs.hasMessageAreaRead(area)) {
confTag = ct;
areaTag = at;
return false; // stop inner iteration
}
});
if(areaTag) {
return false; // stop iteration
}
});
}
return [confTag, areaTag || ''];
}
function getMessageConferenceByTag(confTag) {
return Config().messageConferences[confTag];
return Object.assign({ confTag }, Config().messageConferences[confTag]);
}
function getMessageConfTagByAreaTag(areaTag) {
@ -209,17 +254,23 @@ function getMessageAreaByTag(areaTag, optionalConfTag) {
// :TODO: this could be cached
if(_.isString(optionalConfTag)) {
if(_.has(confs, [ optionalConfTag, 'areas', areaTag ])) {
return confs[optionalConfTag].areas[areaTag];
if(_.isObject(confs, [ optionalConfTag, 'areas', areaTag ])) {
return Object.assign(
{
areaTag,
confTag : optionalConfTag,
},
confs[optionalConfTag].areas[areaTag]
);
}
} else {
//
// No confTag to work with - we'll have to search through them all
//
let area;
_.forEach(confs, (v) => {
if(_.has(v, [ 'areas', areaTag ])) {
area = v.areas[areaTag];
_.forEach(confs, (conf, confTag) => {
if(_.isObject(conf, [ 'areas', areaTag ])) {
area = Object.assign({ areaTag, confTag }, conf.areas[areaTag]);
return false; // stop iteration
}
});
@ -350,6 +401,22 @@ function changeMessageArea(client, areaTag, cb) {
changeMessageAreaWithOptions(client, areaTag, { persist : true }, cb);
}
function hasMessageConfAndAreaRead(client, area) {
const conf = getMessageConfTagByAreaTag(area.areaTag);
return client.acs.hasMessageConfRead(conf) && client.acs.hasMessageAreaRead(area);
}
function filterMessageAreaTagsByReadACS(client, areaTags) {
if(!Array.isArray(areaTags)) {
areaTags = [ areaTags ];
}
return areaTags.filter( areaTag => {
const area = getMessageAreaByTag(areaTag);
return hasMessageConfAndAreaRead(client, area);
});
}
function getNewMessageCountInAreaForUser(userId, areaTag, cb) {
getMessageAreaLastReadId(userId, areaTag, (err, lastMessageId) => {
lastMessageId = lastMessageId || 0;

View File

@ -21,6 +21,7 @@ const {
getMessageAreaByTag,
getDefaultMessageConferenceTag,
getDefaultMessageAreaTagByConfTag,
getSuitableMessageConfAndAreaTags,
} = require('./message_area.js');
const {
getFileAreaByTag,
@ -128,15 +129,6 @@ function userLogin(client, username, password, options, cb) {
}
function postLoginPrep(client, cb) {
const defaultMsgAreaTag = (confTag) => {
return (
getDefaultMessageAreaTagByConfTag(client, confTag) ||
getDefaultMessageAreaTagByConfTag(client, getDefaultMessageConferenceTag(client)) ||
''
);
};
async.series(
[
(callback) => {
@ -144,23 +136,20 @@ function postLoginPrep(client, cb) {
// User may (no longer) have read (view) rights to their current
// message, conferences and/or areas. Move them out if so.
//
let confTag = client.user.getProperty(UserProps.MessageConfTag);
const conf = getMessageConferenceByTag(confTag) || {};
const area = getMessageAreaByTag(client.user.getProperty(UserProps.MessageAreaTag), confTag) || {};
const confTag = client.user.getProperty(UserProps.MessageConfTag);
const conf = getMessageConferenceByTag(confTag) || {};
const area = getMessageAreaByTag(client.user.getProperty(UserProps.MessageAreaTag), confTag) || {};
if(!client.acs.hasMessageConfRead(conf)) {
confTag = getDefaultMessageConferenceTag(client) || '';
if(!client.acs.hasMessageConfRead(conf) || !client.acs.hasMessageAreaRead(area)) {
// move them out of both area and possibly conf to something suitable, hopefully.
const [newConfTag, newAreaTag] = getSuitableMessageConfAndAreaTags(client);
client.user.persistProperties({
[ UserProps.MessageConfTag ] : confTag,
[ UserProps.MessageAreaTag ] : defaultMsgAreaTag(confTag),
[ UserProps.MessageConfTag ] : newConfTag,
[ UserProps.MessageAreaTag ] : newAreaTag,
},
err => {
return callback(err);
});
} else if (!client.acs.hasMessageAreaRead(area)) {
client.user.persistProperty(UserProps.MessageAreaTag, defaultMsgAreaTag(confTag), err => {
return callback(err);
});
} else {
return callback(null);
}