Personal Information
-
Name: Riya Kumari
-
IRC nick: riyaku11
-
Email: riyaku217@gmail.com
-
Github: https://github.com/riyaku11
-
Location: Noida, India
-
Time zone: UTC +5:30 Kolkata
-
University: University of Delhi
-
Major: Information Technology and Mathematical Innovations
Project Description
-
Name: Implement an Administration System for Bookbrainz site
-
Proposed Mentor: @Monkey
-
Goals:
-
Modifying the database schema to add tables for to define roles and attach users to roles
-
Implementing an admin panel webpage to allow admins to perform privileged actions.
-
Developing middlewares for securing specific routes according to a userās roles
-
Developing a page to allow privileged users to edit and add relationships and identifiers
-
Implementing a public log of administration actions
Modifying the database schema
My proposed system suggests suggests three roles: Editor & Admin. So first of all I will be creating a TYPE column that includes these three types of users:
Create TYPE bookbrainz.Roles_type(
āEDITORā, āADMINā
);
Admin: Highest level
Editor: lowest level
To make the system future proof and to handle more complicated use roles and combination of roles, we can use flags with bit masking to determine the level of privileges as :
exports const Editor_flag = 1;
exports const Relationship_editor_flag = 2;
exports const Editing_disabled_flag = 4;
exports const Reindexing_disabled_flag = 8;
exports const Blocked_user_flag= 16;
and so on for all privileges.
Next step would be to modify the bookbrainz.editor table to include two fields: TYPE and PERMISSIONS . The PERMISSIONS field will have the AND of all the binary flags for the particular user.
Only the ADMINs will have the access to give permissions to specific users.
The users would be able to access only those routes which they are allowed to.
Implementing an Admin panel webpage
The next step would be to create an admin dashboard which is only accessible by users with the role as āAdminā. The page would contain all the necessary features like the total number of users, search users by Id, give privileged roles to different users (like upgrading editors to super-editors or admins), and block or delete abusive users.
Visual mockups for the admin dashboard
page to update user types and privileges
Middlewares for securing specific routes
Next step is to create middlewares to check the role of a user
For example
exports.IsAdmin = async (req,res,next)=>{
const role = req.user.type;
if(role !=="admin"){
return res.status(403).json({message: āYou are not authorized to access this resourceā})
}
next();
};
The admin routes can be accessed by
router.route("/admin/user/:id").get(isAuthenticatedUser,isAdmin,getUserById);
router.route("/admin/user/:id").put(isAuthenticatedUser,isAdmin,updateRole);
router.route("/admin/user/:id").delete(isAuthenticatedUser,isAdmin,deleteUser);
router.route("/superEditor/edit").put(isAuthenticatedUser,isSuperEditor,EditRelationships)
Where the isAuthenticatedUser function checks whether a user is signed in or not.
npm install --save bookbrainz-data-js
Once installed, you can use the bookbrainz-data-js module to create a connection to the BookBrainz database and perform CRUD operations on the various database tables.
Functions:
const { User } = require('bookbrainz-data-js');
const getUserById = async (req, res, next) => {
const userId = req.params.id;
try {
const user = await User.get(userId);
if (!user) {
return res.status(404).json({
error: 'User not found'
});
}
req.user = user;
next();
} catch (error) {
return res.status(500).json({
error: 'Error retrieving user from database'
});
}
};
The require(ābookbrainz-data-jsā) statement loads the bookbrainz-data-js module into the script. This module provides an interface for interacting with the BookBrainz database.
The first line of the function extracts the user ID from the req.params object. This assumes that the user ID is included in the URL parameters of the incoming request.
getUserById is an Express.js middleware function that takes three arguments: req, res, and next. This function is designed to be used as middleware in an Express application. When called, this function will attempt to retrieve a user from the BookBrainz database based on their ID.
const { User } = require('bookbrainz-data-js');
const updateUserRole = async (req, res, next) => {
const userId = req.params.id;
const newRoleId = req.body.roleId;
try {
const user = await User.where({ id: userId }).fetch();
if (!user) {
return res.status(404).json({
error: 'User not found'
});
}
await user.roles().detach(); // remove existing roles
await user.roles().attach(newRoleId); // assign new role
res.status(200).json({
message: 'User role updated successfully'
});
} catch (error) {
console.error(error);
res.status(500).json({
error: 'Error updating user role in database'
});
}
};
updateUserRole is an Express.js middleware function that updates the role of a user by the uses of the bookshelf ORM to fetch the user by their ID, detach any existing roles they have, and attach the new role specified in the request body. If thereās an error during this process, the function returns a JSON response with an error message and a 500 status code. If the update is successful, it returns a JSON response with a success message and a 200 status code.
const { User } = require('bookbrainz-data-js');
const deleteUser = async (req, res, next) => {
const userId = req.params.id;
try {
const user = await User.get(userId);
if (!user) {
return res.status(404).json({
error: 'User not found'
});
}
await user.delete();
res.status(200).json({
message: 'User deleted successfully'
});
} catch (error) {
return res.status(500).json({
error: 'Error deleting user from database'
});
}
};
deleteUser is an Express.js middleware function that takes three arguments: req, res, and next. This function is designed to be used as middleware in an Express application. When called, this function will attempt to delete a user from the BookBrainz database based on their ID.
Developing a page to allow privileged users to edit and add relationships and identifiers
Create the user interface for the edit and add relationships and identifiers page. This could involve designing a form that allows users to input the necessary data for the relationships and identifiers, as well as providing fields for searching for and selecting existing entities to connect to.
This web page would likely have a user interface that allows users to search for and select the entity they want to edit or add information to. They could then modify or add relationships and identifiers through a form or other interface provided by the page. Additionally, access control and security measures would need to be implemented to ensure that only authorised users can access and modify the data.
Implementing a public log of administration actions
Create a table for admin logs
Create table bookbrainz.admin_logs(
id serial primary key,
User_id integer references editor(Metabrainz_user_id)
Action varchar(100)
)
SQL Query:
-
INSERTs a new row into the bookbrainz.admin_logs table
-
Sets the user_id column to the userId value extracted from the request
-
Sets the action column to the action string constructed from the HTTP method and original URL of the request
Create a function for admin logs
const { AdminLog } = require('../models');
const logAction = (req, res, next) => {
const userId = req.user.id;
const action = req.method + ' ' + req.originalUrl;
AdminLog.create({
user_id: userId,
action: action
})
.catch(error => {
console.error('Error logging action:', error);
});
next();
};
;
module.exports = logAction;
Function:
- It requires the AdminLog model, which represents the admin_log table in the database. This model is defined using Bookshelf.js, an ORM that makes it easier to work with databases in JavaScript.
- It extracts the user ID from the req.user object, assuming that the user has been authenticated and their information is stored in this object.
- It constructs an action string by concatenating the HTTP method (req.method) and original URL (req.originalUrl) of the request.
- It creates a new instance of the AdminLog model with the user_id and action values set to the user ID and action string, respectively.
- Then we create a new log entry using AdminLog.create(), passing in an object with the user_id and action values.
Contribution
I recently contributed to resolving an issue on the BookBrainz website, where the test environment wasnāt easily distinguishable from other environments. I implemented a banner feature that makes it clear to users when they are on the test site, and PR has been merged into the codebase.
Timeline
Week 1:
- Analyse the requirements for the admin system and finalise the database schema.
- Implement the new database schema, adding tables for roles and attaching users to roles.
Week 2:
-
Implement middleware for securing specific routes according to a userās roles.
-
Add necessary API endpoints to update user privileges and roles.
Week 3:
-
Implement the admin panel webpage to allow admins to search for users, give users privileges, and take other actions.
-
Add a security layer to the admin panel to restrict access to authorised users.
Week 4:
-
Implement the page to allow privileged users to edit and add relationships and identifiers
-
Developing middlewares for securing routes.
Week 5:
- Develop a feature that permits privileged users to trigger a reindex of the search server, which updates the search index and improves search performance.
Week 6:
- Test the system, and fix any bugs and issues found during testing.
Week 7:
-
Improve the documentation of the admin system and the API endpoints.
-
Submit the code and documentation to the BookBrainz project repository for review.
Other Information
-
Tell us about the computer(s) you have available for working on your
SoC project!I have an ASUS vivobook with an i3 processor and 8 gb of RAM.
-
When did you first start programming?
I started programming when I was in class 11th.
-
What type of music do you listen to?
I mostly listen to country music
-
If applying for a BookBrainz project: what type of books do you
read?I love to read fiction novels. Everything by Rober
Frost-Bookbrainz. -
What aspects of the project youāre applying for (e.g., MusicBrainz,
AcousticBrainz, etc.) interest you the most?Iāve been making some contributions to Bookbrainz. I like the
community and the discussions focused on improving the project as
a whole. -
Have you ever used MusicBrainz to tag your files?
No. I would like to give it a try.
-
Have you contributed to other Open Source projects?
Yes, I have been contributing to Open Source projects since last
year. I have also participated in hacktoberfest 2022. -
How much time do you have available, and how would you plan to use
it?I will be able to give 30 hours a week. I plan to utilise this
time to achieve my goal to complete the project within the
specified timeline, while also ensuring that the implementation is
of high quality, well documented, and conforms to the coding
standards and best practices of the BookBrainz project.