GSOC 2023: Administration system for BookBrainz by LiB

Personal Information

Name: Mayank Tripathi

Discord: leaveitblank#8944

IRC nick: leaveitblank

Email: leaveitblank32@gmail.com

Github: Leave-it-blank · GitHub

Location: Bhopal, India

Time zone: UTC + 5:30 Kolkata

University: Vellore Institute of Technology, Bhopal

Major: Computer Science and Engineering

Project Description

Proposed Mentors: @Monkey

Languages/skills: Node.js, SQL, ExpressJS

Estimated Project Length: 175 hours

Difficulty: easy

Expected outcomes: A usable administration system with arbitrary levels of privileges

This will require at minimum:

  • Modifying the database schema, adding at least:
    • a table to define roles
    • a table to attach users to roles
  • Implementing a simple admin panel webpage to allow admins to search for users, give users privileges and take other actions
  • Middleware for securing specific routes according to a user’s roles:
    • admins can view the admin panel
    • admins can block or deleted abusive users
    • privileged editors can edit relationships and identifiers
    • privileged editors can trigger a reindex of the search server

Extended goals:

  • a web interface to allow privileged users to edit and add relationship types , identifier types and other types that currently require direct database access
  • a public log of administration actions

Project Overview

As we require the administration system for the BookBrainz website to grant users with permissions and roles allowing them to make modifications more effectively. I propose the following implementation.

Implementation

The proposed implementation aims to create a role-based permission system to provide flexibility for future use cases. The system consists of four database tables:

  • Roles
  • Permissions
  • UserHasRoles
  • RoleHasPermissions

Where a user can have multiple roles assigned to them, and roles can have multiple permissions. Roles can be dynamically created from the admin panel. While permissions are set via migrations. This allows us to create roles with varying levels of authorization for different purposes.

Table Schema:

Roles:

CREATE TABLE bookbrainz.roles (

id PRIMARY KEY,

role VARCHAR(20) UNIQUE NOT NULL,

timestamp TIMESTAMP,

);

Permissions:

CREATE TABLE bookbrainz.permissions (

id PRIMARY KEY,

role VARCHAR(20) UNIQUE NOT NULL,

timestamp TIMESTAMP,

);
UserHasRoles:

CREATE TABLE bookbrainz.user_has_roles (

id PRIMARY KEY,

userID int NOT NULL,

roleID int NOT NULL,

FOREIGN KEY (userID) REFERENCES user(id),

FOREIGN KEY (roleID) REFERENCES roles(id),

timestamp TIMESTAMP,

);
RoleHasPermissions:

CREATE TABLE bookbrainz.role_has_permissions (

id PRIMARY KEY,

roleID int NOT NULL,

permissionID int NOT NULL,

FOREIGN KEY (roleID) REFERENCES roles(id),

FOREIGN KEY (permissionID) REFERENCES permissions(id),

timestamp TIMESTAMP,

);
  • The Roles table has three columns: id, role, and timestamp. The id column is the primary key and is used as a unique identifier for each role. The role column stores the name of the role and must be unique. The timestamp column records the creation time of the role for logging purposes. Roles can be added or removed from the admin panel.

  • The Permissions table has the same structure as the Roles table, with the only difference being that it stores permissions instead of roles. Each permission is identified by its unique id, and its name is stored in the role column and also must be unique. Permissions cannot be modified from the admin panel.

  • The UserHasRoles table has four columns: id, userID, roleID, and timestamp. The id column is the primary key, and userID and roleID columns are foreign keys that reference the user and role tables, respectively. This table is used to assign roles to users. A user can have multiple roles, and each role can be assigned to multiple users.

  • The RoleHasPermissions table has the same structure as the UserHasRoles table, with the only difference being that it links roles to permissions. It has three columns: id, roleID, permissionID, and timestamp. The roleID and permissionID columns are foreign keys that reference the role and permission tables, respectively. This table is used to assign permissions to roles. A role can have multiple permissions, and each permission can be assigned to multiple roles.

Implementing a simple admin panel webpage to allow admins to search for users, give users privileges and take other actions.

We can implement a basic crud based react frontend for this, here are sample previews(mock):-

|645.3595800524934x378

We can also add an option to block users inside this menu as well the option to delete the user account. Similarly another menu to create roles and add permissions to each role.

There will be few basic roles that can be assigned to users.

→ administrator
→ manager
→ editor

  • Where administrator has permissions that lets users create and modify other roles [that do not have similar permissions]. Also the ability to block, delete users.
  • Manager has permissions that allow users the basic admin ability of blocking users, editing and other actions.
  • Editors have permissions that allow it to assign other users with the roles created by admins. Editors also have permission other permissions.

There are few basic permissions as well -

→ delete-user
→ edit-user
→ create-role
→ edit-role
→ reindexing
→ block-user

We can discuss more on permissions and roles as they can change depending on scope and requirements.

Public log of administration actions:

This we can simply implement by adding an event based logging where each time a user takes any option on the admin panel it is then logged into a database which is then connected to a public page which shows all the logs in a formatted order by day.

Basic Designs (mock)

Sample Code:

Routes:


* router.get('/create/roles')
* router.post('/role/:id/edit')
* router.delete('/role/:id/delete')
* router.post('/create/roles/handler)
* router.post('/role/:id/edit/handler)
* router.get('/permissions')

* router.get('/users')
* router.get('/dashboard')
* router.get('/user/:id/edit)
* router.post('/user/:id/edit/handler')

UserPolicies MiddleWare Example

//User policy to delete the user.


const isAuthorizedToDelete = (req: { headers: { authorization: any; }; user: any; }, res: { sendStatus: (arg0: number) => void; }, next: () => void) => {

Let flag = false;

if( user){

user.roles.forEach(x => if(x.hasPermission(“delete User”)){

flag = true;

});

if(flag){

//log the action with success

next();

}else {

//log the action with failure

throw new error.PermissionDeniedError(

'You do not have permission for this action', req

);

}

}

else{

//no need to log as user is not logged in

res.sendStatus(401);

}

};

Timeline of the development

During the community bonding period, my focus will be on getting acquainted with the database and the current middleware implementation, as well as resolving any issues with the testing suite setup. Additionally, I will establish the basic development environment.

Week 1

  • Modifying the database schema, creating the necessary roles and permissions and creating the associated tables.
  • Defining rules for permission and writing the test cases.
  • Modifying schema and create a logs table to track the action of privileged users (admins, editors, etc)

Week 2-3

  • Setup migrations and seeding to initially create roles and permissions.

  • Interact with existing api to setup login and pull up users data from the database.

  • Work on designing the admin panel, Make figma mock up for approval.

  • Implementing the designs using tailwindCSS and reactJs.

  • Design a public logging page with filters for dates and action.

Week 4-5

Implement the CRUD operation in the api backend for roles creation and editing.

  • Create the api endpoints to create/delete/edit roles and assign permissions to roles.
  • Create an endpoint to assign/remove roles to the user and write up the function logic.
  • Implement the user table on the admin panel and connect with the api to edit user roles.
  • Implement roles table (listing all roles) and add buttons to create and edit roles.

Week 6-7

  • Connect roles & permission frontend with api endpoints.
  • Setup middleware for each route and set up an event based logging feature.
  • Add user policies and checks for edge cases where it checks if a user has permissions to take an action, or if both users have the same privilege.
  • Make sure test cases are being satisfied.
  • Implement a public logging page where all the logs are displayed in a sorted day wise manner.

Week 8-9

  • Fix any linting issues and failing test cases. Ensure the functionality of the admin panel and testing for various edge cases.
  • Look through code for any possible exploits and tidying up the loose code.
  • Connecting and testing backend api with react frontend and check the behavior of the admin panel.

Week 10-11

  • Work on additional features such as interfaces to interact with databases directly for privileged users to change and edit relationships etc.
  • Designing and implementing the page for editing relationships and other types.
  • Document the whole code base and write comments and tidy up comments as required.

Week 12

  • Improve the documentation for api endpoints and various functions.
  • Submit the code for review.

Other Information

  1. Tell us about the computer(s) you have available for working on your GSoC project!
I have a macbook pro 14 inch with 16 gb ram.
  1. When did you first start programming?
I first started in my 11th class with C++ 2018, But I got most interested after 1st year in college while 
learning web development.
  1. What type of music do you listen to?

I listen to a mix of romantic and sad songs from hindi and english depending on my mood and task at
hand. I like music as it keeps me motivated while working.

  1. If applying for a BookBrainz project: what type of books do you read?
Not typical books, But i love to read fantasy/fiction novels.
  1. What aspects of the project you’re applying for (e.g., MusicBrainz, AcousticBrainz, etc.) interest you the most?

I am applying for BookBrainz as i was looking to work on something like this, I have done some basic implementation using different packages but i always wanted to implement the functions and everything from scatch.

  1. Have you ever used MusicBrainz to tag your files?

No. I would like to give it a try.

  1. Have you contributed to other Open Source projects?

Yes, I have made some minor contributions.

  1. How much time do you have available, and how would you plan to use it?

I am usually available after my 4 hr morning college classes so approximately 30-40 hr per week. I plan
to use this time to follow my proposed timeline and finish everything in a timely manner. I would even
like to finish early so I could review it again. I would follow the best practices to write my code and test
cases. And follow the standard set by the Bookbrainz team.