Merge branch 'feat-roles-authorization' into develop
This commit is contained in:
@@ -194,15 +194,37 @@ module.exports =
|
||||
peer.email = userinfo.email;
|
||||
}
|
||||
},
|
||||
// Required roles for Access. All users have the role "ALL" by default.
|
||||
// Other roles need to be added in the "userMapping" function. This
|
||||
// is an Array of roles. userRoles.ADMIN have all priveleges and access
|
||||
// always.
|
||||
// All users have the role "NORMAL" by default. Other roles need to be
|
||||
// added in the "userMapping" function. The following accesses and
|
||||
// permissions are arrays of roles. Roles can be changed in userRoles.js
|
||||
//
|
||||
// Example:
|
||||
// [ userRoles.MODERATOR, userRoles.AUTHENTICATED ]
|
||||
// This will allow all MODERATOR and AUTHENTICATED users access.
|
||||
requiredRolesForAccess : [ userRoles.ALL ],
|
||||
accessFromRoles : {
|
||||
// The role(s) will gain access to the room
|
||||
// even if it is locked (!)
|
||||
BYPASS_ROOM_LOCK : [ userRoles.ADMIN ],
|
||||
// The role(s) will gain access to the room without
|
||||
// going into the lobby. If you want to restrict access to your
|
||||
// server to only directly allow authenticated users, you could
|
||||
// add the userRoles.AUTHENTICATED to the user in the userMapping
|
||||
// function, and change to BYPASS_LOBBY : [ userRoles.AUTHENTICATED ]
|
||||
BYPASS_LOBBY : [ userRoles.NORMAL ]
|
||||
},
|
||||
permissionsFromRoles : {
|
||||
// The role(s) have permission to lock/unlock a room
|
||||
CHANGE_ROOM_LOCK : [ userRoles.NORMAL ],
|
||||
// The role(s) have permission to promote a peer from the lobby
|
||||
PROMOTE_PEER : [ userRoles.NORMAL ],
|
||||
// The role(s) have permission to send chat messages
|
||||
SEND_CHAT : [ userRoles.NORMAL ],
|
||||
// The role(s) have permission to share screen
|
||||
SHARE_SCREEN : [ userRoles.NORMAL ],
|
||||
// The role(s) have permission to share files
|
||||
SHARE_FILE : [ userRoles.NORMAL ],
|
||||
// The role(s) have permission to moderate room (e.g. kick user)
|
||||
MODERATE_ROOM : [ userRoles.MODERATOR ]
|
||||
},
|
||||
// When truthy, the room will be open to all users when as long as there
|
||||
// are allready users in the room
|
||||
activateOnHostJoin : true,
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ class Peer extends EventEmitter
|
||||
|
||||
this._authenticated = false;
|
||||
|
||||
this._roles = [ userRoles.ALL ];
|
||||
this._roles = [ userRoles.NORMAL ];
|
||||
|
||||
this._displayName = false;
|
||||
|
||||
|
||||
+61
-31
@@ -59,12 +59,6 @@ class Room extends EventEmitter
|
||||
// Locked flag.
|
||||
this._locked = false;
|
||||
|
||||
// Required roles to access
|
||||
this._requiredRoles = [ userRoles.ALL ];
|
||||
|
||||
if ('requiredRolesForAccess' in config)
|
||||
this._requiredRoles = config.requiredRolesForAccess;
|
||||
|
||||
// if true: accessCode is a possibility to open the room
|
||||
this._joinByAccesCode = true;
|
||||
|
||||
@@ -157,15 +151,16 @@ class Room extends EventEmitter
|
||||
// Returning user
|
||||
if (returning)
|
||||
this._peerJoining(peer, true);
|
||||
// Always let ADMIN in, even if locked
|
||||
else if (peer.roles.includes(userRoles.ADMIN))
|
||||
else if ( // Has a role that is allowed to bypass room lock
|
||||
peer.roles.some((role) => config.accessFromRoles.BYPASS_ROOM_LOCK.includes(role))
|
||||
)
|
||||
this._peerJoining(peer);
|
||||
else if (this._locked)
|
||||
this._parkPeer(peer);
|
||||
else
|
||||
{
|
||||
// If the user has a role in config.requiredRolesForAccess, let them in
|
||||
peer.roles.some((role) => this._requiredRoles.includes(role)) ?
|
||||
// Has a role that is allowed to bypass lobby
|
||||
peer.roles.some((role) => config.accessFromRoles.BYPASS_LOBBY.includes(role)) ?
|
||||
this._peerJoining(peer) :
|
||||
this._handleGuest(peer);
|
||||
}
|
||||
@@ -200,18 +195,18 @@ class Room extends EventEmitter
|
||||
|
||||
this._lobby.on('peerRolesChanged', (peer) =>
|
||||
{
|
||||
// Always let admin in, even if locked
|
||||
if (peer.roles.includes(userRoles.ADMIN))
|
||||
if ( // Has a role that is allowed to bypass room lock
|
||||
peer.roles.some((role) => config.accessFromRoles.BYPASS_ROOM_LOCK.includes(role))
|
||||
)
|
||||
{
|
||||
this._lobby.promotePeer(peer.id);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If the user has a role in config.requiredRolesForAccess, let them in
|
||||
if (
|
||||
if ( // Has a role that is allowed to bypass lobby
|
||||
!this._locked &&
|
||||
peer.roles.some((role) => this._requiredRoles.includes(role))
|
||||
peer.roles.some((role) => config.accessFromRoles.BYPASS_LOBBY.includes(role))
|
||||
)
|
||||
{
|
||||
this._lobby.promotePeer(peer.id);
|
||||
@@ -554,9 +549,11 @@ class Room extends EventEmitter
|
||||
.map((joinedPeer) => (joinedPeer.peerInfo));
|
||||
|
||||
cb(null, {
|
||||
roles : peer.roles,
|
||||
peers : peerInfos,
|
||||
authenticated : peer.authenticated
|
||||
roles : peer.roles,
|
||||
peers : peerInfos,
|
||||
authenticated : peer.authenticated,
|
||||
permissionsFromRoles : config.permissionsFromRoles,
|
||||
userRoles : userRoles
|
||||
});
|
||||
|
||||
// Mark the new Peer as joined.
|
||||
@@ -683,12 +680,19 @@ class Room extends EventEmitter
|
||||
|
||||
case 'produce':
|
||||
{
|
||||
let { appData } = request.data;
|
||||
|
||||
if (
|
||||
appData.source === 'screen' &&
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.SHARE_SCREEN.includes(role))
|
||||
)
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
// Ensure the Peer is joined.
|
||||
if (!peer.joined)
|
||||
throw new Error('Peer not yet joined');
|
||||
|
||||
const { transportId, kind, rtpParameters } = request.data;
|
||||
let { appData } = request.data;
|
||||
const transport = peer.getTransport(transportId);
|
||||
|
||||
if (!transport)
|
||||
@@ -982,6 +986,11 @@ class Room extends EventEmitter
|
||||
|
||||
case 'chatMessage':
|
||||
{
|
||||
if (
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.SEND_CHAT.includes(role))
|
||||
)
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
const { chatMessage } = request.data;
|
||||
|
||||
this._chatHistory.push(chatMessage);
|
||||
@@ -1020,6 +1029,11 @@ class Room extends EventEmitter
|
||||
|
||||
case 'lockRoom':
|
||||
{
|
||||
if (
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.CHANGE_ROOM_LOCK.includes(role))
|
||||
)
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
this._locked = true;
|
||||
|
||||
// Spread to others
|
||||
@@ -1035,6 +1049,11 @@ class Room extends EventEmitter
|
||||
|
||||
case 'unlockRoom':
|
||||
{
|
||||
if (
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.CHANGE_ROOM_LOCK.includes(role))
|
||||
)
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
this._locked = false;
|
||||
|
||||
// Spread to others
|
||||
@@ -1090,6 +1109,11 @@ class Room extends EventEmitter
|
||||
|
||||
case 'promotePeer':
|
||||
{
|
||||
if (
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.PROMOTE_PEER.includes(role))
|
||||
)
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
const { peerId } = request.data;
|
||||
|
||||
this._lobby.promotePeer(peerId);
|
||||
@@ -1102,6 +1126,11 @@ class Room extends EventEmitter
|
||||
|
||||
case 'promoteAllPeers':
|
||||
{
|
||||
if (
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.PROMOTE_PEER.includes(role))
|
||||
)
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
this._lobby.promoteAllPeers();
|
||||
|
||||
// Return no error
|
||||
@@ -1112,6 +1141,11 @@ class Room extends EventEmitter
|
||||
|
||||
case 'sendFile':
|
||||
{
|
||||
if (
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.SHARE_FILE.includes(role))
|
||||
)
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
const { magnetUri } = request.data;
|
||||
|
||||
this._fileHistory.push({ peerId: peer.id, magnetUri: magnetUri });
|
||||
@@ -1149,10 +1183,9 @@ class Room extends EventEmitter
|
||||
case 'moderator:muteAll':
|
||||
{
|
||||
if (
|
||||
!peer.hasRole(userRoles.MODERATOR) &&
|
||||
!peer.hasRole(userRoles.ADMIN)
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.MODERATE_ROOM.includes(role))
|
||||
)
|
||||
throw new Error('peer does not have moderator priveleges');
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
// Spread to others
|
||||
this._notification(peer.socket, 'moderator:mute', {
|
||||
@@ -1167,10 +1200,9 @@ class Room extends EventEmitter
|
||||
case 'moderator:stopAllVideo':
|
||||
{
|
||||
if (
|
||||
!peer.hasRole(userRoles.MODERATOR) &&
|
||||
!peer.hasRole(userRoles.ADMIN)
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.MODERATE_ROOM.includes(role))
|
||||
)
|
||||
throw new Error('peer does not have moderator priveleges');
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
// Spread to others
|
||||
this._notification(peer.socket, 'moderator:stopVideo', {
|
||||
@@ -1185,10 +1217,9 @@ class Room extends EventEmitter
|
||||
case 'moderator:closeMeeting':
|
||||
{
|
||||
if (
|
||||
!peer.hasRole(userRoles.MODERATOR) &&
|
||||
!peer.hasRole(userRoles.ADMIN)
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.MODERATE_ROOM.includes(role))
|
||||
)
|
||||
throw new Error('peer does not have moderator priveleges');
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
this._notification(
|
||||
peer.socket,
|
||||
@@ -1208,10 +1239,9 @@ class Room extends EventEmitter
|
||||
case 'moderator:kickPeer':
|
||||
{
|
||||
if (
|
||||
!peer.hasRole(userRoles.MODERATOR) &&
|
||||
!peer.hasRole(userRoles.ADMIN)
|
||||
!peer.roles.some((role) => config.permissionsFromRoles.MODERATE_ROOM.includes(role))
|
||||
)
|
||||
throw new Error('peer does not have moderator priveleges');
|
||||
throw new Error('peer not authorized');
|
||||
|
||||
const { peerId } = request.data;
|
||||
|
||||
|
||||
+1
-1
@@ -327,7 +327,7 @@ async function setupAuth()
|
||||
{
|
||||
for (const role of peer.roles)
|
||||
{
|
||||
if (role !== userRoles.ALL)
|
||||
if (role !== userRoles.NORMAL)
|
||||
peer.removeRole(role);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-7
@@ -1,12 +1,11 @@
|
||||
module.exports = {
|
||||
// Allowed to enter locked rooms + all other priveleges
|
||||
// These can be changed
|
||||
ADMIN : 'admin',
|
||||
// Allowed to enter restricted rooms if configured.
|
||||
// Allowed to moderate users in a room (mute all,
|
||||
// spotlight video, kick users)
|
||||
MODERATOR : 'moderator',
|
||||
// Same as MODERATOR, but can't moderate users
|
||||
PRESENTER : 'presenter',
|
||||
AUTHENTICATED : 'authenticated',
|
||||
// No priveleges
|
||||
ALL : 'normal'
|
||||
// Don't change anything after this point
|
||||
|
||||
// All users have this role by default, do not change or remove this role
|
||||
NORMAL : 'normal'
|
||||
};
|
||||
Reference in New Issue
Block a user