mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
Add permissions
This commit is contained in:
parent
cfee8a213a
commit
0a82574eb4
13 changed files with 135 additions and 27 deletions
27
server/config/roles.json
Normal file
27
server/config/roles.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"roles": [
|
||||
{
|
||||
"name": "admin",
|
||||
"permissions": [
|
||||
"crud_quiz",
|
||||
"crud_folders",
|
||||
"crud_images",
|
||||
"crud_user"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "teacher",
|
||||
"permissions": [
|
||||
"crud_quiz",
|
||||
"crud_folders",
|
||||
"crud_images"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "student",
|
||||
"permissions": [
|
||||
"participate_quiz"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -7,6 +7,11 @@ exports.UNAUTHORIZED_INVALID_TOKEN = {
|
|||
code: 401
|
||||
}
|
||||
|
||||
exports.UNAUTHORIZED_PERMISSION_MISSING = {
|
||||
message: 'Accès refusé. Vous n\'avez pas les permissions nécessaires.',
|
||||
code: 403
|
||||
}
|
||||
|
||||
exports.MISSING_REQUIRED_PARAMETER = {
|
||||
message: 'Paramètre requis manquant.',
|
||||
code: 400
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ class UsersController {
|
|||
|
||||
async register(req, res, next) {
|
||||
try {
|
||||
const { email, password } = req.body;
|
||||
const { email, password, role } = req.body;
|
||||
|
||||
if (!email || !password) {
|
||||
throw new AppError(MISSING_REQUIRED_PARAMETER);
|
||||
}
|
||||
|
||||
await model.register(email, password);
|
||||
await model.register(email, password, role);
|
||||
|
||||
emailer.registerConfirmation(email)
|
||||
|
||||
|
|
@ -43,11 +43,12 @@ class UsersController {
|
|||
throw new AppError(LOGIN_CREDENTIALS_ERROR);
|
||||
}
|
||||
|
||||
const token = jwt.create(user.email, user._id);
|
||||
const token = jwt.create(user.email, user._id, user.role);
|
||||
|
||||
return res.status(200).json({
|
||||
token: token,
|
||||
id: user.email
|
||||
id: user.email,
|
||||
role: user.role
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ dotenv.config();
|
|||
|
||||
class Token {
|
||||
|
||||
create(email, userId) {
|
||||
return jwt.sign({ email, userId }, process.env.JWT_SECRET);
|
||||
create(email, userId, role) {
|
||||
return jwt.sign({ email, userId, role }, process.env.JWT_SECRET);
|
||||
}
|
||||
|
||||
authenticate(req, res, next) {
|
||||
|
|
|
|||
23
server/middleware/rbac.js
Normal file
23
server/middleware/rbac.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
const Permissions = require('../models/permissions');
|
||||
const AppError = require("./AppError");
|
||||
const { UNAUTHORIZED_PERMISSION_MISSING} = require("../constants/errorCodes");
|
||||
const jwt = require("jsonwebtoken");
|
||||
|
||||
class Rbac {
|
||||
checkPermission = (...permissions) => {
|
||||
return (req, res, next) => {
|
||||
const userRole = req.user ? req.user.role : 'anonymous';
|
||||
const userPermissions = Permissions.getPermissionsByRoleName(userRole);
|
||||
|
||||
for (let permission of permissions) {
|
||||
if (!userPermissions.includes(permission)) {
|
||||
return next(new AppError(UNAUTHORIZED_PERMISSION_MISSING));
|
||||
}
|
||||
}
|
||||
|
||||
return next();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = new Rbac;
|
||||
13
server/models/permissions.js
Normal file
13
server/models/permissions.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
const Role = require('../models/role');
|
||||
|
||||
class Permissions {
|
||||
constructor() {
|
||||
this.permissions = [];
|
||||
}
|
||||
|
||||
getPermissionsByRoleName(roleName) {
|
||||
const role = Role.getRoleByName(roleName);
|
||||
return role ? role.permissions : [];
|
||||
}
|
||||
}
|
||||
module.exports = new Permissions;
|
||||
30
server/models/role.js
Normal file
30
server/models/role.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
const roles = require('../config/roles.json');
|
||||
|
||||
class Role {
|
||||
constructor() {
|
||||
this.roles = roles.roles;
|
||||
}
|
||||
|
||||
getRoleByName(name) {
|
||||
return this.convertCrud(this.roles.find((role) => role.name === name));
|
||||
}
|
||||
|
||||
getRoles() {
|
||||
return this.roles;
|
||||
}
|
||||
|
||||
convertCrud(role) {
|
||||
for (let permission of role.permissions) {
|
||||
if (permission.startsWith("crud")) {
|
||||
let resourceName = permission.split("_");
|
||||
role.permissions.push("create_" + resourceName[1]);
|
||||
role.permissions.push("read_" + resourceName[1]);
|
||||
role.permissions.push("update_" + resourceName[1]);
|
||||
role.permissions.push("delete_" + resourceName[1]);
|
||||
}
|
||||
}
|
||||
return role;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new Role;
|
||||
|
|
@ -19,7 +19,7 @@ class Users {
|
|||
return await bcrypt.compare(password, hash)
|
||||
}
|
||||
|
||||
async register(email, password) {
|
||||
async register(email, password, role) {
|
||||
await db.connect()
|
||||
const conn = db.getConnection();
|
||||
|
||||
|
|
@ -34,6 +34,7 @@ class Users {
|
|||
const newUser = {
|
||||
email: email,
|
||||
password: await this.hashPassword(password),
|
||||
role: role,
|
||||
created_at: new Date()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,16 +3,16 @@ const router = express.Router();
|
|||
const jwt = require('../middleware/jwtToken.js');
|
||||
|
||||
const foldersController = require('../controllers/folders.js')
|
||||
const rbac = require("../middleware/rbac");
|
||||
|
||||
router.post("/create", jwt.authenticate, foldersController.create);
|
||||
router.get("/getUserFolders", jwt.authenticate, foldersController.getUserFolders);
|
||||
router.get("/getFolderContent/:folderId", jwt.authenticate, foldersController.getFolderContent);
|
||||
router.delete("/delete/:folderId", jwt.authenticate, foldersController.delete);
|
||||
router.put("/rename", jwt.authenticate, foldersController.rename);
|
||||
router.post("/create", jwt.authenticate, rbac.checkPermission('create_folders'), foldersController.create);
|
||||
router.get("/getUserFolders", jwt.authenticate, rbac.checkPermission('read_folders'), foldersController.getUserFolders);
|
||||
router.get("/getFolderContent/:folderId", jwt.authenticate, rbac.checkPermission('read_folders'), foldersController.getFolderContent);
|
||||
router.delete("/delete/:folderId", jwt.authenticate, rbac.checkPermission('delete_folders'), foldersController.delete);
|
||||
router.put("/rename", jwt.authenticate, rbac.checkPermission('update_folders'), foldersController.rename);
|
||||
|
||||
//router.post("/duplicate", jwt.authenticate, foldersController.duplicate);
|
||||
router.post("/duplicate", jwt.authenticate, foldersController.duplicate);
|
||||
router.post("/duplicate", jwt.authenticate, rbac.checkPermission('create_folders', 'read_folders'), foldersController.duplicate);
|
||||
|
||||
router.post("/copy/:folderId", jwt.authenticate, foldersController.copy);
|
||||
router.post("/copy/:folderId", jwt.authenticate, rbac.checkPermission('create_folders', 'read_folders'), foldersController.copy);
|
||||
|
||||
module.exports = router;
|
||||
|
|
@ -6,10 +6,11 @@ const imagesController = require('../controllers/images.js')
|
|||
|
||||
// For getting the image out of the form data
|
||||
const multer = require('multer');
|
||||
const rbac = require("../middleware/rbac");
|
||||
const storage = multer.memoryStorage();
|
||||
const upload = multer({ storage: storage });
|
||||
|
||||
router.post("/upload", jwt.authenticate, upload.single('image'), imagesController.upload);
|
||||
router.post("/upload", jwt.authenticate, rbac.checkPermission('create_images'), upload.single('image'), imagesController.upload);
|
||||
router.get("/get/:id", imagesController.get);
|
||||
|
||||
module.exports = router;
|
||||
|
|
@ -3,17 +3,18 @@ const router = express.Router();
|
|||
|
||||
const jwt = require('../middleware/jwtToken.js');
|
||||
const quizController = require('../controllers/quiz.js')
|
||||
const rbac = require('../middleware/rbac.js');
|
||||
|
||||
router.post("/create", jwt.authenticate, quizController.create);
|
||||
router.get("/get/:quizId", jwt.authenticate, quizController.get);
|
||||
router.delete("/delete/:quizId", jwt.authenticate, quizController.delete);
|
||||
router.put("/update", jwt.authenticate, quizController.update);
|
||||
router.put("/move", jwt.authenticate, quizController.move);
|
||||
router.post("/create", jwt.authenticate, rbac.checkPermission('create_quiz'), quizController.create);
|
||||
router.get("/get/:quizId", jwt.authenticate, rbac.checkPermission('participate_quiz'), quizController.get);
|
||||
router.delete("/delete/:quizId", jwt.authenticate, rbac.checkPermission('delete_quiz'), quizController.delete);
|
||||
router.put("/update", jwt.authenticate, rbac.checkPermission('update_quiz'), quizController.update);
|
||||
router.put("/move", jwt.authenticate, rbac.checkPermission('update_quiz'), quizController.move);
|
||||
|
||||
router.post("/duplicate", jwt.authenticate, quizController.duplicate);
|
||||
router.post("/copy/:quizId", jwt.authenticate, quizController.copy);
|
||||
router.put("/Share", jwt.authenticate, quizController.Share);
|
||||
router.get("/getShare/:quizId", jwt.authenticate, quizController.getShare);
|
||||
router.post("/receiveShare", jwt.authenticate, quizController.receiveShare);
|
||||
router.post("/duplicate", jwt.authenticate, rbac.checkPermission('create_quiz', 'read_quiz'), quizController.duplicate);
|
||||
router.post("/copy/:quizId", jwt.authenticate, rbac.checkPermission('create_quiz', 'read_quiz'), quizController.copy);
|
||||
router.put("/Share", jwt.authenticate, rbac.checkPermission('create_quiz', 'read_quiz'), quizController.Share);
|
||||
router.get("/getShare/:quizId", jwt.authenticate, rbac.checkPermission('create_quiz', 'read_quiz'), quizController.getShare);
|
||||
router.post("/receiveShare", jwt.authenticate, rbac.checkPermission('create_quiz', 'read_quiz'), quizController.receiveShare);
|
||||
|
||||
module.exports = router;
|
||||
|
|
@ -3,11 +3,12 @@ const router = express.Router();
|
|||
|
||||
const jwt = require('../middleware/jwtToken.js');
|
||||
const usersController = require('../controllers/users.js')
|
||||
const rbac = require("../middleware/rbac");
|
||||
|
||||
router.post("/register", usersController.register);
|
||||
router.post("/login", usersController.login);
|
||||
router.post("/reset-password", usersController.resetPassword);
|
||||
router.post("/change-password", jwt.authenticate, usersController.changePassword);
|
||||
router.post("/delete-user", jwt.authenticate, usersController.delete);
|
||||
router.post("/delete-user", jwt.authenticate, rbac.checkPermission('delete_user'), usersController.delete);
|
||||
|
||||
module.exports = router;
|
||||
|
|
@ -5,6 +5,7 @@ const setupWebsocket = (io) => {
|
|||
let totalConnections = 0;
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
// Get jwt and roles
|
||||
if (totalConnections >= MAX_TOTAL_CONNECTIONS) {
|
||||
console.log("Connection limit reached. Disconnecting client.");
|
||||
socket.emit(
|
||||
|
|
@ -24,6 +25,10 @@ const setupWebsocket = (io) => {
|
|||
);
|
||||
|
||||
socket.on("create-room", (sentRoomName) => {
|
||||
// If roles authorize else send error message
|
||||
// else {
|
||||
// socket.emit('access_denied', 'You do not have permission to perform this action');
|
||||
// }
|
||||
if (sentRoomName) {
|
||||
const roomName = sentRoomName.toUpperCase();
|
||||
if (!io.sockets.adapter.rooms.get(roomName)) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue