Change auth strategy (#174)
This commit is contained in:
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "soul-cli",
|
"name": "soul-cli",
|
||||||
"version": "0.7.1",
|
"version": "0.7.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "soul-cli",
|
"name": "soul-cli",
|
||||||
"version": "0.7.1",
|
"version": "0.7.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "soul-cli",
|
"name": "soul-cli",
|
||||||
"version": "0.7.1",
|
"version": "0.7.2",
|
||||||
"description": "A SQLite REST and Realtime server",
|
"description": "A SQLite REST and Realtime server",
|
||||||
"main": "src/server.js",
|
"main": "src/server.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ const runCLICommands = () => {
|
|||||||
// if the updatesuperuser command is passed from the CLI execute the updatesuperuser function
|
// if the updatesuperuser command is passed from the CLI execute the updatesuperuser function
|
||||||
if (argv._.includes('updatesuperuser')) {
|
if (argv._.includes('updatesuperuser')) {
|
||||||
const { id, password, is_superuser } = argv;
|
const { id, password, is_superuser } = argv;
|
||||||
|
if (!password && is_superuser === undefined) {
|
||||||
if (!password && !is_superuser) {
|
|
||||||
console.log(
|
console.log(
|
||||||
'Please provide either the --password or --is_superuser flag when using the updateuser command.',
|
'Please provide either the --password or --is_superuser flag when using the updateuser command.',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -76,10 +76,10 @@ const createDefaultTables = async () => {
|
|||||||
permissions.push({
|
permissions.push({
|
||||||
role_id: roleId,
|
role_id: roleId,
|
||||||
table_name: table.name,
|
table_name: table.name,
|
||||||
create: 'false',
|
create: 0,
|
||||||
read: 'true',
|
read: 1,
|
||||||
update: 'false',
|
update: 0,
|
||||||
delete: 'false',
|
delete: 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const obtainAccessToken = async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
let permissions, roleIds;
|
let roleIds;
|
||||||
|
|
||||||
// if the user is not a superuser get the role and its permission from the DB
|
// if the user is not a superuser get the role and its permission from the DB
|
||||||
if (!toBoolean(user.is_superuser)) {
|
if (!toBoolean(user.is_superuser)) {
|
||||||
@@ -64,7 +64,6 @@ const obtainAccessToken = async (req, res) => {
|
|||||||
res,
|
res,
|
||||||
});
|
});
|
||||||
|
|
||||||
permissions = roleData.permissions;
|
|
||||||
roleIds = roleData.roleIds;
|
roleIds = roleData.roleIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +72,6 @@ const obtainAccessToken = async (req, res) => {
|
|||||||
userId: user.id,
|
userId: user.id,
|
||||||
isSuperuser: user.is_superuser,
|
isSuperuser: user.is_superuser,
|
||||||
roleIds,
|
roleIds,
|
||||||
permissions,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// generate an access token
|
// generate an access token
|
||||||
@@ -151,7 +149,7 @@ const refreshAccessToken = async (req, res) => {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
let permissions, roleIds;
|
let roleIds;
|
||||||
const user = users[0];
|
const user = users[0];
|
||||||
|
|
||||||
// if the user is not a superuser get the role and its permission from the DB
|
// if the user is not a superuser get the role and its permission from the DB
|
||||||
@@ -161,7 +159,6 @@ const refreshAccessToken = async (req, res) => {
|
|||||||
res,
|
res,
|
||||||
});
|
});
|
||||||
|
|
||||||
permissions = roleData.permissions;
|
|
||||||
roleIds = roleData.roleIds;
|
roleIds = roleData.roleIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +167,6 @@ const refreshAccessToken = async (req, res) => {
|
|||||||
userId: user.id,
|
userId: user.id,
|
||||||
isSuperuser: user.is_superuser,
|
isSuperuser: user.is_superuser,
|
||||||
roleIds,
|
roleIds,
|
||||||
permissions,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// generate an access token
|
// generate an access token
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const updateSuperuser = async (fields) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// find the user by using the id field
|
// find the user by using the id field
|
||||||
const users = authService.getRoleByUserId({ id });
|
const users = authService.getUsersById({ userId: id });
|
||||||
|
|
||||||
// abort if the id is invalid
|
// abort if the id is invalid
|
||||||
if (users.length === 0) {
|
if (users.length === 0) {
|
||||||
|
|||||||
@@ -657,7 +657,7 @@ const updateRowInTableByPK = async (req, res, next) => {
|
|||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
value = `'${value}'`;
|
value = `'${value}'`;
|
||||||
}
|
}
|
||||||
return `${key} = ${value}`;
|
return `'${key}' = ${value}`;
|
||||||
})
|
})
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,16 @@ const {
|
|||||||
responseMessages,
|
responseMessages,
|
||||||
} = require('../constants/');
|
} = require('../constants/');
|
||||||
const { removeFields } = require('../utils');
|
const { removeFields } = require('../utils');
|
||||||
|
const { customValidator } = require('../middlewares/validation');
|
||||||
|
const schema = require('../schemas/auth');
|
||||||
|
|
||||||
const { httpVerbs } = apiConstants;
|
const { httpVerbs } = apiConstants;
|
||||||
const { reservedTableNames, USERS_TABLE, tableFields } = dbConstants;
|
const {
|
||||||
|
reservedTableNames,
|
||||||
|
USERS_TABLE,
|
||||||
|
ROLES_PERMISSIONS_TABLE,
|
||||||
|
tableFields,
|
||||||
|
} = dbConstants;
|
||||||
const { errorMessage } = responseMessages;
|
const { errorMessage } = responseMessages;
|
||||||
|
|
||||||
const processRowRequest = async (req, res, next) => {
|
const processRowRequest = async (req, res, next) => {
|
||||||
@@ -39,6 +46,21 @@ const processRowRequest = async (req, res, next) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate fields for the _roles_permission API on POST and PUT requests
|
||||||
|
if (
|
||||||
|
resource === ROLES_PERMISSIONS_TABLE &&
|
||||||
|
(method === httpVerbs.POST || method === httpVerbs.PUT)
|
||||||
|
) {
|
||||||
|
const validation = customValidator(schema.updateRolePermissions)(req);
|
||||||
|
|
||||||
|
if (validation.errorStatus) {
|
||||||
|
return res.status(400).json({
|
||||||
|
message: validation.message,
|
||||||
|
error: validation.details,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const config = require('../config');
|
const config = require('../config');
|
||||||
const { decodeToken, toBoolean } = require('../utils/index');
|
const { decodeToken, toBoolean } = require('../utils/index');
|
||||||
const { apiConstants, responseMessages } = require('../constants');
|
const { apiConstants, responseMessages } = require('../constants');
|
||||||
|
const { authService } = require('../services');
|
||||||
|
|
||||||
const { errorMessage } = responseMessages;
|
const { errorMessage } = responseMessages;
|
||||||
|
|
||||||
@@ -42,12 +43,16 @@ const hasAccess = async (req, res, next) => {
|
|||||||
.send({ message: errorMessage.NOT_AUTHORIZED_ERROR });
|
.send({ message: errorMessage.NOT_AUTHORIZED_ERROR });
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the user is not a super user, check the users permission on the resource
|
// if the user is not a super user, fetch the permission of the user from the DB
|
||||||
const permissions = payload.permissions.filter((row) => {
|
const rolePermissions = authService.getPermissionByRoleIds({
|
||||||
return row.table_name === tableName;
|
roleIds: payload.roleIds,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (permissions.length <= 0) {
|
const resourcePermission = rolePermissions.filter(
|
||||||
|
(row) => row.table_name === tableName,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (resourcePermission.length <= 0) {
|
||||||
return res
|
return res
|
||||||
.status(403)
|
.status(403)
|
||||||
.send({ message: errorMessage.PERMISSION_NOT_DEFINED_ERROR });
|
.send({ message: errorMessage.PERMISSION_NOT_DEFINED_ERROR });
|
||||||
@@ -56,7 +61,7 @@ const hasAccess = async (req, res, next) => {
|
|||||||
// If the user has permission on the table in at least in one of the roles then allow access on the table
|
// If the user has permission on the table in at least in one of the roles then allow access on the table
|
||||||
let hasPermission = false;
|
let hasPermission = false;
|
||||||
|
|
||||||
permissions.some((resource) => {
|
resourcePermission.some((resource) => {
|
||||||
const httpMethod =
|
const httpMethod =
|
||||||
apiConstants.httpMethodDefinitions[verb].toLowerCase();
|
apiConstants.httpMethodDefinitions[verb].toLowerCase();
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,24 @@ const validator = (schema) => (req, res, next) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const customValidator = (schema) => (req) => {
|
||||||
|
const response = { errorStatus: false, message: '', error: '' };
|
||||||
|
|
||||||
|
const { body, params, query, cookies } = req;
|
||||||
|
const data = { body, params, query, cookies };
|
||||||
|
|
||||||
|
const { error } = schema.validate(data);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
response.errorStatus = true;
|
||||||
|
response.message = error.message;
|
||||||
|
response.error = error.details;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
validator,
|
validator,
|
||||||
|
customValidator,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -59,9 +59,30 @@ const registerUser = Joi.object({
|
|||||||
}).required(),
|
}).required(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const updateRolePermissions = Joi.object({
|
||||||
|
query: Joi.object({}).required(),
|
||||||
|
params: Joi.object({ name: Joi.string(), pks: Joi.string() }).required(),
|
||||||
|
body: Joi.object({
|
||||||
|
fields: Joi.object({
|
||||||
|
role_id: Joi.number().required(),
|
||||||
|
table_name: Joi.string().required(),
|
||||||
|
create: Joi.number().valid(0, 1).required(),
|
||||||
|
read: Joi.number().valid(0, 1).required(),
|
||||||
|
update: Joi.number().valid(0, 1).required(),
|
||||||
|
delete: Joi.number().valid(0, 1).required(),
|
||||||
|
}).required(),
|
||||||
|
}).required(),
|
||||||
|
|
||||||
|
cookies: Joi.object({
|
||||||
|
accessToken: Joi.string().required(),
|
||||||
|
refreshToken: Joi.string().optional(),
|
||||||
|
}).required(),
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
obtainAccessToken,
|
obtainAccessToken,
|
||||||
refreshAccessToken,
|
refreshAccessToken,
|
||||||
changePassword,
|
changePassword,
|
||||||
registerUser,
|
registerUser,
|
||||||
|
updateRolePermissions,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user