refactor all JWT verification of isModerator and get BoardRole

This commit is contained in:
Entwicklung 2022-09-05 21:19:36 +02:00
parent 7fff39eecd
commit 180c6d7e83
3 changed files with 67 additions and 75 deletions

View file

@ -28,56 +28,18 @@ config = require("./configuration.js"),
jsonwebtoken = require("jsonwebtoken");
/**
* Validates jwt and returns whether board name fits to the board name given in the JWT
* @param {URL} url
* @param {string} boardNameIn
* @returns {boolean} - True if user is a moderator, else false
* @throws {Error} - If no token is provided when it should be or when the board name is incorrect
*/
function checkBoardName(url, boardNameIn) {
var roomIsCorrect = true;
if (config.AUTH_SECRET_KEY != "") {
var token = url.searchParams.get("token");
if (token) {
roomIsCorrect = getBoardnamefromToken(token, boardNameIn);
} else {
throw new Error("No token provided");
}
}
return roomIsCorrect;
}
/**
* Check if user is a moderator
* @param {string} token
* This function checks if a board name is set in the roles claim.
* Returns true of the board name is set in the JWT and the board name matches the board name in the URL
* @param {string} url
* @param {string} boardNameIn
@returns {boolean} - True if user does not have the role forbidden false if the user hase the role forbidden
@throws {Error} - If no boardname match
*/
function getBoardnamefromToken(token, boardNameIn) {
if (config.AUTH_SECRET_KEY != "") {
var payload = jsonwebtoken.verify(token, config.AUTH_SECRET_KEY);
var roles = payload.roles;
var oneHasBoardName = false;
var oneHasCorretBoardname = false;
if (roles) {
for (var line of roles) {
var role = parse_role(line);
if (role.board_name !== '') {
oneHasBoardName = true;
}
if (role.board_name === boardNameIn) {
return true;
}
}
if (!oneHasBoardName) {
return true;
}
throw new Error("No board name match");
} else {
return true;
}
function checkBoardnameInToken(url, boardNameIn) {
var token = url.searchParams.get("token");
if (roleInBoard(token, boardNameIn) === 'forbidden') {
throw new Error("Acess Forbidden");
}
}
@ -85,4 +47,53 @@ function parse_role(role) {
let [_, role_name, board_name] = role.match(/^([^:]*):?(.*)$/);
return {role_name, board_name}
}
module.exports = {checkBoardName, parse_role};
/**
* This function checks if a oard name is set in the roles claim.
* Returns string depending on the role in the board
* @param {string} token
* @param {string} board
@returns {string} "moderator"|"editor"|"forbidden"
*/
function roleInBoard(token, board = null) {
if (config.AUTH_SECRET_KEY != "") {
if (!token) {
throw new Error("No token provided");
}
var payload = jsonwebtoken.verify(token, config.AUTH_SECRET_KEY);
var roles = payload.roles;
var oneHasBoardName = false;
var oneHasModerator = false;
if (roles) {
for (var line of roles) {
var role = parse_role(line);
if (role.board_name !== '') {
oneHasBoardName = true;
}
if (role.role_name === "moderator") {
oneHasModerator = true;
}
if (role.board_name === board) {
return role.role_name;
}
}
if ((!board && oneHasModerator) || !oneHasBoardName) {
if (oneHasModerator) {
return "moderator";
} else {
return "editor";
}
}
return "forbidden";
} else {
return "editor";
}
} else {
return "editor";
}
}
module.exports = {checkBoardnameInToken, roleInBoard};

View file

@ -24,9 +24,10 @@
* @licend
*/
config = require("./configuration.js"),
jsonwebtoken = require("jsonwebtoken");
const {roleInBoard} = require("./jwtBoardnameAuth");
/**
* Validates jwt and returns whether user is a moderator
* @param {URL} url
@ -38,7 +39,7 @@ function checkUserPermission(url) {
if (config.AUTH_SECRET_KEY != "") {
var token = url.searchParams.get("token");
if (token) {
isModerator = checkIfModerator(token);
isModerator = roleInBoard(token) === "moderator";
} else {
// Error out as no token provided
throw new Error("No token provided");
@ -47,25 +48,5 @@ function checkUserPermission(url) {
return isModerator;
}
/**
* Check if user is a moderator
* @param {string} token
*/
function checkIfModerator(token) {
if(config.AUTH_SECRET_KEY != "") {
var payload = jsonwebtoken.verify(token, config.AUTH_SECRET_KEY);
var roles = payload.roles;
if(roles) {
for (var role of roles) {
if (role.match(/^moderator/gm)) {
return true;
}
return false;
}
} else {
return false;
}
}
}
module.exports = { checkUserPermission, checkIfModerator };
module.exports = { checkUserPermission };

View file

@ -121,13 +121,13 @@ function handleRequest(request, response) {
if (parts.length === 1) {
// '/boards?board=...' This allows html forms to point to boards
var boardName = parsedUrl.searchParams.get("board") || "anonymous";
jwtBoardName.checkBoardName(parsedUrl, boardName);
jwtBoardName.checkBoardnameInToken(parsedUrl, boardName);
var headers = { Location: "boards/" + encodeURIComponent(boardName) };
response.writeHead(301, headers);
response.end();
} else if (parts.length === 2 && parsedUrl.pathname.indexOf(".") === -1) {
var boardName = validateBoardName(parts[1]);
jwtBoardName.checkBoardName(parsedUrl, boardName);
jwtBoardName.checkBoardnameInToken(parsedUrl, boardName);
boardTemplate.serve(request, response, isModerator);
// If there is no dot and no directory, parts[1] is the board name
} else {
@ -142,7 +142,7 @@ function handleRequest(request, response) {
config.HISTORY_DIR,
"board-" + boardName + ".json"
);
jwtBoardName.checkBoardName(parsedUrl, boardName);
jwtBoardName.checkBoardnameInToken(parsedUrl, boardName);
if (parts.length > 2 && /^[0-9A-Za-z.\-]+$/.test(parts[2])) {
history_file += "." + parts[2] + ".bak";
}
@ -165,7 +165,7 @@ function handleRequest(request, response) {
config.HISTORY_DIR,
"board-" + boardName + ".json"
);
jwtBoardName.checkBoardName(parsedUrl, boardName);
jwtBoardName.checkBoardnameInToken(parsedUrl, boardName);
response.writeHead(200, {
"Content-Type": "image/svg+xml",
"Content-Security-Policy": CSP,