This repository contains the source code for my diploma thesis titled "Design and development of a dynamic role management API for data protection in smart city applications", which was submitted to the Department of Electrical and Computer Engineering at the University of Patras.
- Make a parent directory for the project:
mkdir ${PWD}/SafeAmea
- Clone this repository:
git clone https://github.com/thanospan/diploma-thesis.git ${PWD}/SafeAmea/SafeAmea-Masked-API
- Create a Docker network:
docker network create safeamea
- Run the MailHog Docker container:
docker run -d -p 1025:1025 -p 8025:8025 --name safeamea-mailhog --network safeamea mailhog/mailhog:v1.0.1
- Run the MongoDB Docker container:
docker run -d -v ${PWD}/SafeAmea/SafeAmea-DB-Data:/data/db -p 27017:27017 --name safeamea-mongo --network safeamea -e MONGO_INITDB_ROOT_USERNAME=mongoadmin -e MONGO_INITDB_ROOT_PASSWORD=01234 mongo:4.4.12
- Check if all containers are running:
docker ps
- Create the maskedApi MongoDB user to control access to the database (Role-Based Access Control - RBAC):
Username: maskedApi
Password: 56789
Authentication database: safeameaMasked
Roles: findAmea on the safeamea database and dbOwner on the safeameaMasked database
findAmea privileges: Find actions on the amea and clubs collections of the safeamea database
Connect to the MongoDB using MongoDB Shell:
docker exec -it safeamea-mongo /bin/bash
mongo
use admin
db.auth("mongoadmin", passwordPrompt())
Enter password: 01234
show dbs
Create the findAmea Role:
use safeamea
db.createRole(
{
role: "findAmea",
privileges: [
{ resource: { db: "safeamea", collection: "amea" },
actions: [ "find" ]
},
{ resource: { db: "safeamea", collection: "clubs" },
actions: [ "find" ]
}
],
roles: []
}
)
Create the maskedApi User:
use safeameaMasked
db.createUser(
{
user: "maskedApi",
pwd: "56789",
roles: [
{ role: "findAmea", db: "safeamea" },
{ role: "dbOwner", db: "safeameaMasked" }
]
}
)
Verify that the maskedApi user is created properly and exit:
use safeamea
db.getRole( "findAmea", { showPrivileges: true } )
use safeameaMasked
db.getUser("maskedApi")
exit
exit
- Run the SafeAmea Masked API:
cd ${PWD}/SafeAmea/SafeAmea-Masked-API
Copy .env.example to .env:
cp config/.env.example config/.env
Build the safeamea-masked-api Docker image:
docker build -t safeamea-masked-api .
Run the SafeAmea Masked API Docker container:
docker run -d -p 3007:3007 --name safeamea-masked-api --network safeamea safeamea-masked-api
Execute an interactive bash shell on the container:
docker exec -it safeamea-masked-api /bin/bash
Populate the safeamea MongoDB:
node scripts/populateSafeameaDb.js
Populate the safeameaMasked MongoDB:
node scripts/populateSafeameaMaskedDb.js
Exit the interactive bash shell:
exit
Check if the database is populated correctly:
Using MongoDB Shell:
docker exec -it safeamea-mongo /bin/bash
mongo
use admin
db.auth("mongoadmin", passwordPrompt())
Enter password: 01234
show dbs
use safeamea
show collections
db.amea.find().pretty()
db.clubs.find().pretty()
use safeameaMasked
show collections
db.emailTokens.find().pretty()
db.users.find().pretty()
db.roles.find().pretty()
db.permissions.find().pretty()
db.policies.find().pretty()
exit
exit
or
Using Robo3T:
Address: localhost
Port: 27017
Authentication database: admin
User Name: mongoadmin
Password: 01234
- Verify that the SafeAmea Masked API is running:
curl -w '\n' http://localhost:3007/masked
- Import the provided Postman collection.
All URIs are relative to http://localhost:3007/masked
HTTP Method | Endpoint | Parameters |
---|---|---|
GET | / | |
GET | /users/ | headers: token |
POST | /users/signup | body: email, password |
POST | /users/email-verification | headers: emailToken query: userId |
POST | /users/login | body: email, password |
POST | /users/logout | headers: token |
POST | /users/:userId/roles | headers: token params: userId body: roles |
DELETE | /users/:userId/ | headers: token params: userId |
GET | /roles/ | headers: token |
POST | /roles/ | headers: token body: name, permissions, policies, status |
POST | /roles/:roleId/permissions | headers: token params: roleId body: permissions |
POST | /roles/:roleId/policies | headers: token params: roleId body: policies |
POST | /roles/:roleId/status | headers: token params: roleId body: status |
DELETE | /roles/:roleId/ | headers: token params: roleId |
GET | /permissions/ | headers: token |
POST | /permissions/ | headers: token body: endpoint, methods, status |
POST | /permissions/:permissionId/methods | headers: token params: permissionId body: methods |
POST | /permissions/:permissionId/status | headers: token params: permissionId body: status |
DELETE | /permissions/:permissionId/ | headers: token params: permissionId |
GET | /policies/ | headers: token |
POST | /policies/ | headers: token body: resource, excluded, masked, status |
POST | /policies/:policyId/excluded | headers: token params: policyId body: excluded |
POST | /policies/:policyId/masked | headers: token params: policyId body: masked |
POST | /policies/:policyId/status | headers: token params: policyId body: status |
DELETE | /policies/:policyId/ | headers: token params: policyId |
GET | /amea/ | headers: token |
-
User:
- email: user@example.com
- password: aA1!a
-
Role:
- name: cityPlanner
-
Permission:
- Method: GET
- Endpoint: /masked/amea/
- Method: GET
-
Masking policies:
-
Resource: Club
Excluded: [_id, __v, updated, created]
Masked: [] -
Resource: Amea
Excluded: [owner, __enc_surname, updated, created, disabilitiesDesc, caretaker.caredescription, __v, _id]
Masked: [name, surname, caretaker.carename, caretaker.caresurname, email.value, caretaker.careemail, phoneNumber.value, caretaker.carephone, address, loc.coordinates, birthday]
-
-
Update the adminToken Postman collection variable.
-
Sign up by sending a POST request to the /users/signup endpoint.
-
Visit MailHog (http://localhost:8025/), open the verification email and copy the userId, emailToken values.
-
Update the userId Postman collection variable.
-
Verify the email address by sending a POST request to the /users/email-verification endpoint, providing the emailToken as a header and the userId as a query parameter.
-
Log in by sending a POST request to the /users/login endpoint. Copy the token header of the response and update the userToken Postman collection variable.
-
Create the cityPlanner role by sending a POST request to the /roles endpoint. Resend the request and copy the roleId. (TODO: Return the roleId as a header after role creation)
-
Create the permission by sending a POST request to the /permissions endpoint. Copy the permissionId. (TODO: Return the permissionId as a header after permission creation)
-
Create the policies by sending POST requests to the /policies endpoint. Copy the policyId. (TODO: Return the policyId as a header after policy creation)
-
Update the cityPlanner role's permissions by sending a POST request to the /roles/{roleId}/permissions endpoint.
-
Update the cityPlanner role's policies by sending a POST request to the /roles/{roleId}/policies endpoint.
-
Assign the cityPlanner role to the user by sending a POST request to the /users/{userId}/roles endpoint.
-
Send a GET request to the /amea endpoint, providing the userToken as a header.
Field | amea MongoDB Collection | Masked API Response |
---|---|---|
_id |
|
|
owner |
|
|
name |
|
|
surname |
|
|
|
|
|
phoneNumber |
|
|
disabilities |
|
|
disabilitiesDesc |
|
|
loc |
|
|
address |
|
|
floor |
|
|
region |
|
|
club |
|
|
caretaker |
|
|
birthday |
|
|
created |
|
|
updated |
|
|
status |
|
|
__v |
|