This project demonstrates (in a simplified form) the principles of anti-fraud systems in the financial sector. For this project, we will work on a system with an expanded role model, a set of REST endpoints responsible for interacting with users, and an internal transaction validation logic based on a set of heuristic rules.
Implementation of Hyperskill's project that includes JSON, REST API, Spring Boot Security, H2 database, LocalDateTime, Project Lombok concepts.
- JDK 11
- Gradle 7.3.3
- Spring Boot 2.7.2
- Clone the repository
git clone https://github.com/MichalLeh/Anti-FraudSystem.git
- Build and run the project
cd Recipes gradlew build
The endpoints can be accessed using a browser or a tool that allows you to send HTTP requests like Postman.
- Registration
- Get all users
- Delete an user
- Lock/Unlock an user
- Update user role
- Post a new transaction
- Save a suspicious IP address
- Delete a suspicious IP address
- Get all suspicious IP addresses
- Save a stolen card
- Delete a stolen card
- Get all stolen cards
Endpoint | Anonymous | MERCHANT | ADMINISTRATOR | SUPPORT |
---|---|---|---|---|
POST /api/auth/user | + | + | + | + |
GET /api/auth/list | - | - | + | + |
DELETE /api/auth/user/{username} | - | - | + | - |
PUT /api/auth/access | - | - | + | - |
PUT /api/auth/role | - | - | + | - |
POST /api/antifraud/transaction | - | + | - | - |
POST, DELETE, GET /api/antifraud/suspicious-ip/{ip} | - | - | - | + |
POST, DELETE, GET /api/antifraud/stolencard/{number} | - | - | - | + |
'+' means the user with given role can access given endpoint. '-' means the user without given role can't access given endpoint.
- It must be available to unauthorized users for registration and accept data in the JSON format;
- If a user has been successfully added, the endpoint must respond with the
HTTP CREATED
status201
; - If an attempt to register an existing user was a failure, the endpoint must respond with the
HTTP CONFLICT
status409
; - If a request contains wrong data, the endpoint must respond with the
BAD REQUEST
status400
; - The first registered user should receive the
ADMINISTRATOR
role; the rest -MERCHANT
. - In case of authorization violation, respond with the
HTTP FORBIDDEN
status403
. Mind that only one role can be assigned to a user; - All users, except
ADMINISTRATOR
, must be locked immediately after registration; onlyADMINISTRATOR
can unlock users.
POST /api/auth/user
request
Request body:
{
"name": "John Doe",
"username": "JohnDoe",
"password": "secret"
}
Response: 201 CREATED
Response body:
{
"id": 1,
"name": "John Doe",
"username": "JohnDoe",
"role": "ADMINISTRATOR"
}
- The endpoint must respond with the
HTTP OK
status200
and the body with an array of objects representing the users sorted by ID in ascending order. Return an empty JSON array if there's no information.
GET /api/auth/list
request
Response: 200 OK
Response body:
[
{
"name":"John Doe",
"username":"JohnDoe",
"role": "ADMINISTRATOR"
},
{
"name":"JohnDoe2",
"username":"JohnDoe2",
"role": "MERCHANT"
}
]
or
[]
- The endpoint must delete the user and respond with the
HTTP OK
status200
; - If a user is not found, respond with the
HTTP NOT FOUND
status404
.
DELETE /api/auth/user/johndoe
request
Response: 200 OK
Response body:
{
"username": "JohnDoe",
"status": "Deleted successfully!"
}
- Endpoint that locks/unlocks users;
- If successful, respond with the
HTTP OK
status200
; - For safety reasons,
ADMINISTRATOR
cannot be blocked. In this case, respond with theHTTP BAD REQUEST
status400
; - If a user is not found, respond with
HTTP NOT FOUND
status404
.
PUT /api/auth/access
request with the correct authentication under the ADMINISTRATOR
role:
Request body:
{
"username": "JohnDoe2",
"operation": "UNLOCK"
}
Response: 200 OK
Response body:
{
"status": "User JohnDoe2 unlocked!"
}
- Endpoint that changes user roles;
- If successful, respond with the
HTTP OK
status200
; - If a user is not found, respond with the
HTTP NOT FOUND
status404
; - If a role is not
SUPPORT
orMERCHANT
, respond withHTTP BAD REQUEST
status400
; - If you want to assign a role that has been already provided to a user, respond with the
HTTP CONFLICT
status409
.
PUT /api/auth/role
request with the correct authentication under the ADMINISTRATOR
role:
Request body:
{
"username": "JohnDoe2",
"role": "SUPPORT"
}
Response: 200 OK
Response body:
{
"id": 1,
"name": "John Doe 2",
"username": "JohnDoe2",
"role": "SUPPORT"
}
- The transaction amount must be greater than
0
; - Transactions with a sum of lower or equal to
200
areALLOWED
; - Transactions with a sum of greater than
200
but lower or equal than1500
requireMANUAL_PROCESSING
; - Transactions with a sum of greater than
1500
arePROHIBITED
; - If the validation process was successful, the endpoint should respond with the status
HTTP OK
200
; - In case of wrong data in the request, the endpoint should respond with the status
HTTP BAD REQUEST
400
; - If the result is
ALLOWED
, theinfo
field must be set tonone
(a string value); - A transaction containing a card number is set to:
MANUAL_PROCESSING
if there are transactions from 3 different regions/IP addresses (count == 3) of the world other than the region/IP addresses of the transaction that are being verified in the last hour in the transaction history;PROHIBITED
if there are transactions from more than 3 different regions/IP addresses (count > 3) of the world other than the region/IP addresses of the transaction that are being verified in the last hour in the transaction history;
- In the case of the
PROHIBITED
orMANUAL_PROCESSING
result, theinfo
field must contain the reason for rejecting the transaction. The reason must be separated by,
and sorted alphabetically. For example,amount, card-number, ip, ip-correlation, region-correlation
; - IP addresses are checked for compliance with IPv4. Any address following this format consists of four series of numbers from 0 to 255 separated by dots;
- Card numbers must be checked according to the Luhn algorithm.
World region codes:
Code | Description |
---|---|
EAP | East Asia and Pacific |
ECA | Europe and Central Asia |
HIC | High-Income countries |
LAC | Latin America and the Caribbean |
MENA | The Middle East and North Africa |
SA | South Asia |
SSA | Sub-Saharan Africa |
POST /api/antifraud/transaction
request
Request body:
{
"amount": 150,
"ip": "192.168.1.1",
"number": "4000008449433403",
"region": "EAP",
"date": "2022-01-22T16:04:00"
}
Response: 200 OK
Response body:
{
"result": "ALLOWED",
"info": "none"
}
- Endpoint that saves suspicious IP addresses in the database;
- If successful, respond with the
HTTP OK
status200
; - If the IP is already in the database, respond with the
HTTP CONFLICT
status409
; - If an IP address has the wrong format, respond with the
HTTP BAD REQUEST
status400
;
POST /api/antifraud/suspicious-ip
request
Request body:
{
"ip": "192.168.1.1"
}
Response: 200 OK
Response body:
{
"id": 1,
"ip": "192.168.1.1"
}
- Endpoint that deletes IP addresses from the database;
- If successful, respond with the
HTTP OK
status200
; - If an IP is not found in the database, respond with the
HTTP NOT FOUND
status404
; - If an IP address has the wrong format, respond with the
HTTP BAD REQUEST
status400
.
DELETE /api/antifraud/suspicious-ip/192.168.1.1
request
Response: 200 OK
Response body:
{
"status": "IP 192.168.1.1 successfully removed!"
}
- Endpoint that shows IP addresses stored in the database;
- If successful, respond with the
HTTP OK
status200
and a body with an array of JSON objects representing IP address sorted by ID in ascending order (or an empty array if the database is empty).
GET /api/antifraud/suspicious-ip
request
Response: 200 OK
Response body:
[
{
"id": 1,
"ip": "192.168.1.1"
},
...
{
"id": 100,
"ip": "192.168.1.254"
}
]
or
[]
- Endpoint that saves stolen card in the database;
- If successful, respond with the
HTTP OK
status200
; - If a card is already in the database, respond with the
HTTP CONFLICT
status409
; - If a card has the wrong format, respond with the
HTTP BAD REQUEST
status400
;
POST /api/antifraud/stolencard
request
Request body:
{
"number": "4000008449433403"
}
Response: 200 OK
Response body:
{
"id": 1,
"number": "4000008449433403"
}
- Endpoint that deletes card number from the database;
- If successful, respond with the
HTTP OK
status200
; - If a card number is not found in the database, respond with the
HTTP NOT FOUND
status404
; - If a card number has the wrong format, respond with the
HTTP BAD REQUEST
status400
.
DELETE /api/antifraud/suspicious-ip/4000008449433403
request
Response: 200 OK
Response body:
{
"status": "Card 4000008449433403 successfully removed!"
}
- Endpoint that shows card numbers stored in the database;
- If successful, respond with the
HTTP OK
status200
and a body with an array of JSON objects representing card numbers sorted by ID in ascending order (or an empty array if the database is empty).
GET /api/antifraud/stolencard
request
Response: 200 OK
Response body:
[
{
"id": 1,
"number": "4000008449433403"
},
...
{
"id": 100,
"number": "4000009455296122"
}
]
or
[]