Description
An enterprise anti-fraud system has hundreds of merchant users who take advantage of the system by checking the validity of the transactions only. These users do not want to delve into a list of stolen cards, suspicious IP addresses, and who else uses the app. On the other hand, the number of users responsible for reporting stolen cards/IPs and excluding them from the blacklist is limited. These users don't have access to user-management functions. Finally, we have several users who are 100%-trusted and are allowed to access and modify more sensitive data.
In this stage, you need to add the authorization feature. Authorization is a process when the system decides whether an authenticated client has permission to access the requested resource. Authorization always follows authentication.
Let's implement the role model for our system:
| Anonymous | MERCHANT | ADMINISTRATOR | SUPPORT | |
|---|---|---|---|---|
| POST /api/auth/user | + | + | + | + |
| DELETE /api/auth/user | - | - | + | - |
| GET /api/auth/list | - | - | + | + |
| POST /api/antifraud/transaction | - | + | - | - |
| PUT /api/auth/access | - | - | + | - |
| PUT /api/auth/role | - | - | + | - |
Let's talk about roles. ADMINISTRATOR is the user who has registered first, all other users should receive the MERCHANT roles. All users added after ADMINISTRATOR must be locked by default and unlocked later by ADMINISTRATOR. The SUPPORT role should be assigned by ADMINISTRATOR to one of the users later.
Objectives
- Add authorization to the service and implement the role model shown in the table above. The first registered user should receive the
ADMINISTRATORrole; the rest —MERCHANT. In case of authorization violation, respond with theHTTP Forbiddenstatus (403). Mind that only one role can be assigned to a user; - All users, except
ADMINISTRATOR, must be locked immediately after registration; onlyADMINISTRATORcan unlock users; - Change the response for the
POST /api/auth/userendpoint. It should respond with theHTTP Createdstatus (201) and the body with the JSON object containing the information about a user. Add therolefield in the response:
{
"id": <Long value, not empty>,
"name": "<String value, not empty>",
"username": "<String value, not empty>",
"role": "<String value, not empty>"
}
- Change the response for the
GET /api/auth/listendpoint. Add therolefield in the response:
[
{
"id": <user1 id>,
"name": "<user1 name>",
"username": "<user1 username>",
"role": "<user1 role>"
},
...
{
"id": <userN id>,
"name": "<userN name>",
"username": "<userN username>",
"role": "<userN role>"
}
]
- Add the
PUT /api/auth/roleendpoint that changes user roles. It must accept the following JSON body:
{
"username": "<String value, not empty>",
"role": "<String value, not empty>"
}
If successful, respond with the HTTP OK status (200) and the body like this:
{
"id": <Long value, not empty>,
"name": "<String value, not empty>",
"username": "<String value, not empty>",
"role": "<String value, not empty>"
}
- If a user is not found, respond with the
HTTP Not Foundstatus (404); - If a role is not
SUPPORTorMERCHANT, respond withHTTP Bad Requeststatus (400); - If you want to assign a role that has been already provided to a user, respond with the
HTTP Conflictstatus (409); - Add the
PUT /api/auth/accessendpoint that locks/unlocks users. It accepts the following JSON body:
{
"username": "<String value, not empty>",
"operation": "<[LOCK, UNLOCK]>" // determines whether the user will be activated or deactivated
}
If successful, respond with the HTTP OK status (200) and the following body:
{
"status": "User <username> <[locked, unlocked]>!"
}
- For safety reasons,
ADMINISTRATORcannot be blocked. In this case, respond with theHTTP Bad Requeststatus (400); - If a user is not found, the endpoint must respond with
HTTP Not Foundstatus (404).
Examples
Example 1: a POST request for /api/auth/user with the correct user credentials
Request body:
{
"name": "John Doe",
"username": "JohnDoe",
"password": "secret"
}
Response: 201 CREATED
Response body:
{
"id": 1,
"name": "John Doe",
"username": "JohnDoe",
"role": "ADMINISTRATOR"
}
Example 2: a GET request for /api/auth/list
Response: 200 OK
[
{
"name":"John Doe",
"username":"JohnDoe",
"role": "ADMINISTRATOR"
},
{
"name":"JohnDoe2",
"username":"JohnDoe2",
"role": "MERCHANT"
}
]
Example 3: a PUT request for /api/auth/role with the correct authentication under the ADMINISTRATOR role:
Request body:
{
"username": "JohnDoe1",
"role": "SUPPORT"
}
Response: 200 OK
Response body:
{
"id": 1,
"name": "John Doe 1",
"username": "JohnDoe1",
"role": "SUPPORT"
}
Example 4: a PUT request for /api/auth/role with the correct authentication under the ADMINISTRATOR role:
Request body:
{
"username": "JohnDoe1",
"role": "ADMINISTRATOR"
}
Response: 400 HTTP Bad Request
Example 5: a PUT request for /api/auth/role with the correct authentication under the ADMINISTRATOR role:
Request body:
{
"username": "JohnDoe1",
"role": "SUPPORT"
}
Response: 409 HTTP Conflict
Example 6: a PUT request for /api/auth/access with the correct authentication under the ADMINISTRATOR role:
Request body:
{
"username": "JohnDoe1",
"operation": "UNLOCK"
}
Response: 200 OK
Response body:
{
"status": "User JohnDoe1 unlocked!"
}
Example 7: a PUT request for /api/auth/access with the correct authentication under the ADMINISTRATOR role:
Request body:
{
"username": "Administrator",
"operation": "LOCK"
}
Response: 400 Bad Request