mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
Add permissions with providers
This commit is contained in:
parent
19f545b24f
commit
04577d5ce2
10 changed files with 122 additions and 17 deletions
|
|
@ -357,8 +357,9 @@ const Dashboard: React.FC = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ApiService.isTeacher()) {
|
||||||
|
return (<div className="dashboard"></div>);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,10 @@ const QuizForm: React.FC = () => {
|
||||||
navigator.clipboard.writeText(link);
|
navigator.clipboard.writeText(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ApiService.isTeacher()) {
|
||||||
|
return (<div className="dashboard"></div>);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='quizEditor'>
|
<div className='quizEditor'>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,22 @@ class ApiService {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isTeacher(): boolean {
|
||||||
|
const token = this.getToken()
|
||||||
|
|
||||||
|
if (token == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let user = JSON.parse(atob(token.split('.')[1]))
|
||||||
|
|
||||||
|
if (user.role == "teacher") {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public logout(): void {
|
public logout(): void {
|
||||||
return localStorage.removeItem("jwt");
|
return localStorage.removeItem("jwt");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
var OAuth2Strategy = require('passport-oauth2')
|
var OAuth2Strategy = require('passport-oauth2')
|
||||||
|
const model = require("../../../models/users");
|
||||||
|
|
||||||
class PassportOAuth {
|
class PassportOAuth {
|
||||||
register(app, passport,endpoint, name, provider) {
|
register(app, passport,endpoint, name, provider) {
|
||||||
|
|
@ -17,6 +18,15 @@ class PassportOAuth {
|
||||||
headers: { 'Authorization': `Bearer ${accessToken}` }
|
headers: { 'Authorization': `Bearer ${accessToken}` }
|
||||||
});
|
});
|
||||||
const userInfo = await userInfoResponse.json();
|
const userInfo = await userInfoResponse.json();
|
||||||
|
let role;
|
||||||
|
|
||||||
|
if (userInfo.groups.includes(provider.OAUTH_ROLE_TEACHER_VALUE)) {
|
||||||
|
role = "teacher";
|
||||||
|
} else if (userInfo.groups.includes(provider.OAUTH_ROLE_STUDENT_VALUE)) {
|
||||||
|
role = "student";
|
||||||
|
} else {
|
||||||
|
role = "anonymous";
|
||||||
|
}
|
||||||
|
|
||||||
const user = {
|
const user = {
|
||||||
id: userInfo.sub,
|
id: userInfo.sub,
|
||||||
|
|
@ -25,7 +35,8 @@ class PassportOAuth {
|
||||||
groups: userInfo.groups ?? [],
|
groups: userInfo.groups ?? [],
|
||||||
accessToken: accessToken,
|
accessToken: accessToken,
|
||||||
refreshToken: refreshToken,
|
refreshToken: refreshToken,
|
||||||
expiresIn: params.expires_in
|
expiresIn: params.expires_in,
|
||||||
|
role: role
|
||||||
};
|
};
|
||||||
|
|
||||||
// Store the tokens in the session
|
// Store the tokens in the session
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
var OpenIDConnectStrategy = require('passport-openidconnect')
|
var OpenIDConnectStrategy = require('passport-openidconnect')
|
||||||
|
const model = require("../../../models/users");
|
||||||
|
|
||||||
class PassportOpenIDConnect {
|
class PassportOpenIDConnect {
|
||||||
|
|
||||||
|
|
@ -54,6 +55,13 @@ class PassportOpenIDConnect {
|
||||||
},
|
},
|
||||||
(req, res) => {
|
(req, res) => {
|
||||||
if (req.user) {
|
if (req.user) {
|
||||||
|
if (req.user.groups.includes(provider.OAUTH_ROLE_TEACHER_VALUE)) {
|
||||||
|
model.register(req.user.email, "teacher");
|
||||||
|
} else if (req.user.groups.includes(provider.OAUTH_ROLE_STUDENT_VALUE)) {
|
||||||
|
model.register(req.user.email, "student");
|
||||||
|
} else {
|
||||||
|
model.register(req.user.email, "anonymous");
|
||||||
|
}
|
||||||
res.json(req.user)
|
res.json(req.user)
|
||||||
console.info(`L'utilisateur '${req.user.name}' vient de se connecter`)
|
console.info(`L'utilisateur '${req.user.name}' vient de se connecter`)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -151,15 +151,11 @@ class AuthConfig {
|
||||||
|
|
||||||
if (providerConfig.type === 'oauth') {
|
if (providerConfig.type === 'oauth') {
|
||||||
passportConfig[providerName] = {
|
passportConfig[providerName] = {
|
||||||
type: providerConfig.type,
|
type: providerConfig.type
|
||||||
authorizationUrl: providerConfig.OAUTH_AUTHORIZATION_URL,
|
|
||||||
callbackUrl: providerConfig.OAUTH_CALLBACK_URL,
|
|
||||||
};
|
};
|
||||||
} else if (providerConfig.type === 'oidc') {
|
} else if (providerConfig.type === 'oidc') {
|
||||||
passportConfig[providerName] = {
|
passportConfig[providerName] = {
|
||||||
type: providerConfig.type,
|
type: providerConfig.type
|
||||||
issuerUrl: providerConfig.OIDC_ISSUER_URL,
|
|
||||||
callbackUrl: providerConfig.OIDC_CALLBACK_URL
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"crud_quiz",
|
"crud_quiz",
|
||||||
"crud_folders",
|
"crud_folders",
|
||||||
"crud_images"
|
"crud_images",
|
||||||
|
"participate_quiz"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,18 @@
|
||||||
const Permissions = require('../models/permissions');
|
const Permissions = require('../models/permissions');
|
||||||
const AppError = require("./AppError");
|
const AppError = require("./AppError");
|
||||||
const { UNAUTHORIZED_PERMISSION_MISSING} = require("../constants/errorCodes");
|
const { UNAUTHORIZED_PERMISSION_MISSING} = require("../constants/errorCodes");
|
||||||
const jwt = require("jsonwebtoken");
|
|
||||||
|
|
||||||
class Rbac {
|
class Rbac {
|
||||||
checkPermission = (...permissions) => {
|
checkPermission = (...permissions) => {
|
||||||
return (req, res, next) => {
|
return (req, res, next) => {
|
||||||
const userRole = req.user ? req.user.role : 'anonymous';
|
let userRole;
|
||||||
|
if (req.user) {
|
||||||
|
userRole = req.user.role;
|
||||||
|
} else if (req.session.passport.user) {
|
||||||
|
userRole = req.session.passport.user.role;
|
||||||
|
} else {
|
||||||
|
userRole = 'anonymous';
|
||||||
|
}
|
||||||
const userPermissions = Permissions.getPermissionsByRoleName(userRole);
|
const userPermissions = Permissions.getPermissionsByRoleName(userRole);
|
||||||
|
|
||||||
for (let permission of permissions) {
|
for (let permission of permissions) {
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,37 @@ class Users {
|
||||||
// TODO: verif if inserted properly...
|
// TODO: verif if inserted properly...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async register(email, role) {
|
||||||
|
await db.connect();
|
||||||
|
const conn = db.getConnection();
|
||||||
|
|
||||||
|
const userCollection = conn.collection('users');
|
||||||
|
|
||||||
|
const existingUser = await userCollection.findOne({ email: email });
|
||||||
|
|
||||||
|
if (existingUser) {
|
||||||
|
await userCollection.updateOne(
|
||||||
|
{ email: existingUser.email },
|
||||||
|
{
|
||||||
|
$set: { 'role': role },
|
||||||
|
$currentDate: { lastModified: true }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const newUser = {
|
||||||
|
email: email,
|
||||||
|
role: role,
|
||||||
|
created_at: new Date()
|
||||||
|
};
|
||||||
|
|
||||||
|
await userCollection.insertOne(newUser);
|
||||||
|
|
||||||
|
const folderTitle = 'Dossier par Défaut';
|
||||||
|
const userId = newUser._id.toString();
|
||||||
|
await Folders.create(folderTitle, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async login(email, password) {
|
async login(email, password) {
|
||||||
await db.connect()
|
await db.connect()
|
||||||
const conn = db.getConnection();
|
const conn = db.getConnection();
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,38 @@
|
||||||
const MAX_USERS_PER_ROOM = 60;
|
const MAX_USERS_PER_ROOM = 60;
|
||||||
const MAX_TOTAL_CONNECTIONS = 2000;
|
const MAX_TOTAL_CONNECTIONS = 2000;
|
||||||
|
var passport = require('passport')
|
||||||
|
const Permissions = require("../models/permissions");
|
||||||
|
const AppError = require("../middleware/AppError");
|
||||||
|
const {UNAUTHORIZED_PERMISSION_MISSING} = require("../constants/errorCodes");
|
||||||
|
|
||||||
const setupWebsocket = (io) => {
|
const setupWebsocket = (io) => {
|
||||||
let totalConnections = 0;
|
let totalConnections = 0;
|
||||||
|
|
||||||
|
function onlyForHandshake(middleware) {
|
||||||
|
return (req, res, next) => {
|
||||||
|
const isHandshake = req._query.sid === undefined;
|
||||||
|
if (isHandshake) {
|
||||||
|
middleware(req, res, next);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
io.engine.use(onlyForHandshake(passport.session()));
|
||||||
|
io.engine.use(
|
||||||
|
onlyForHandshake((req, res, next) => {
|
||||||
|
if (req.user) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
res.writeHead(401);
|
||||||
|
res.end();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
io.on("connection", (socket) => {
|
io.on("connection", (socket) => {
|
||||||
// Get jwt and roles
|
const userRole = socket.request.user.role;
|
||||||
if (totalConnections >= MAX_TOTAL_CONNECTIONS) {
|
if (totalConnections >= MAX_TOTAL_CONNECTIONS) {
|
||||||
console.log("Connection limit reached. Disconnecting client.");
|
console.log("Connection limit reached. Disconnecting client.");
|
||||||
socket.emit(
|
socket.emit(
|
||||||
|
|
@ -25,10 +52,10 @@ const setupWebsocket = (io) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
socket.on("create-room", (sentRoomName) => {
|
socket.on("create-room", (sentRoomName) => {
|
||||||
// If roles authorize else send error message
|
const userPermissions = Permissions.getPermissionsByRoleName(userRole);
|
||||||
// else {
|
if (!userPermissions.includes("create_quiz")) {
|
||||||
// socket.emit('access_denied', 'You do not have permission to perform this action');
|
socket.emit(UNAUTHORIZED_PERMISSION_MISSING.code, UNAUTHORIZED_PERMISSION_MISSING.message);
|
||||||
// }
|
}
|
||||||
if (sentRoomName) {
|
if (sentRoomName) {
|
||||||
const roomName = sentRoomName.toUpperCase();
|
const roomName = sentRoomName.toUpperCase();
|
||||||
if (!io.sockets.adapter.rooms.get(roomName)) {
|
if (!io.sockets.adapter.rooms.get(roomName)) {
|
||||||
|
|
@ -49,6 +76,10 @@ const setupWebsocket = (io) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("join-room", ({ enteredRoomName, username }) => {
|
socket.on("join-room", ({ enteredRoomName, username }) => {
|
||||||
|
const userPermissions = Permissions.getPermissionsByRoleName(userRole);
|
||||||
|
if (!userPermissions.includes("participate_quiz")) {
|
||||||
|
socket.emit(UNAUTHORIZED_PERMISSION_MISSING.code, UNAUTHORIZED_PERMISSION_MISSING.message);
|
||||||
|
}
|
||||||
if (io.sockets.adapter.rooms.has(enteredRoomName)) {
|
if (io.sockets.adapter.rooms.has(enteredRoomName)) {
|
||||||
const clientsInRoom =
|
const clientsInRoom =
|
||||||
io.sockets.adapter.rooms.get(enteredRoomName).size;
|
io.sockets.adapter.rooms.get(enteredRoomName).size;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue