bigbluebutton-Github/bigbluebutton-html5/imports/api/acl/Acl.js

93 lines
2.6 KiB
JavaScript
Raw Normal View History

2017-10-10 02:53:45 +08:00
import { Meteor } from 'meteor/meteor';
2017-06-19 21:13:35 +08:00
import { check } from 'meteor/check';
import deepMerge from '/imports/utils/deepMerge';
export default class Acl {
2017-06-19 21:13:35 +08:00
constructor(config, Users) {
this.Users = Users;
this.config = config;
}
can(permission, credentials) {
check(permission, String);
const permissions = this.getPermissions(credentials);
return this.checkToken(credentials) && this.fetchPermission(permission, permissions);
}
checkToken(credentials) {
2017-10-10 02:53:45 +08:00
// skip token check in client `can` calls since we dont have the authToken in the collection
if (!Meteor.isServer) return true;
const { meetingId, requesterUserId: userId, requesterToken: authToken } = credentials;
const User = this.Users.findOne({
meetingId,
userId,
authToken,
validated: true,
connectionStatus: 'online',
// TODO: We cant check for approved until we move subscription login out of <Base />
// approved: true,
});
2017-06-19 21:13:35 +08:00
return !!User; // if he found a user means the meeting/user/token is valid
2017-06-19 21:13:35 +08:00
}
fetchPermission(permission, permissions) {
if (!permission) return false;
if (Match.test(permissions, String)) {
return permissions.indexOf(permission) > -1;
} else if (Match.test(permissions, Array)) {
return permissions.some(internalAcl => (this.fetchPermission(permission, internalAcl)));
} else if (Match.test(permissions, Object)) {
if (permission.indexOf('.') > -1) {
return this.fetchPermission(
permission.substring(permission.indexOf('.') + 1),
permissions[permission.substring(0, permission.indexOf('.'))],
);
2017-06-19 21:13:35 +08:00
}
return permissions[permission];
}
return false;
}
getPermissions(credentials) {
if (!credentials) {
return false;
}
const { meetingId, requesterUserId: userId } = credentials;
2017-06-19 21:13:35 +08:00
const user = this.Users.findOne({
meetingId,
userId,
});
2017-06-07 21:02:31 +08:00
const containRole = Acl.containsRole(user);
2017-06-19 21:13:35 +08:00
2017-06-07 21:02:31 +08:00
if (containRole) {
const { roles } = user;
2017-06-07 21:02:31 +08:00
let permissions = {};
2017-06-19 21:13:35 +08:00
2017-06-07 21:02:31 +08:00
roles.forEach((role) => {
// There is a big issue here, if we just send the content from the this.config
// inside the deepMerge, we change both permissions and the config.
// Couldn't find a better way to prevent the changing.
// The problems occurs in the `sources.shift()`.
permissions = deepMerge(permissions, JSON.parse(JSON.stringify(this.config[role])));
2017-06-07 21:02:31 +08:00
});
return permissions;
}
return false;
}
2017-06-19 21:13:35 +08:00
2017-06-07 21:02:31 +08:00
static containsRole(user) {
return Match.test(user, Object) &&
Match.test(user.roles, Array);
2017-06-19 21:13:35 +08:00
}
}