Initial commit
976
docs/api/barong_admin_api_v2.md
Normal file
@@ -0,0 +1,976 @@
|
||||
# Barong
|
||||
RESTful AdminAPI for barong OAuth server
|
||||
|
||||
## Version: 2.7.0
|
||||
|
||||
### Security
|
||||
**BearerToken**
|
||||
|
||||
|basic|*Basic*|
|
||||
|---|---|
|
||||
|Description|Bearer Token authentication|
|
||||
|Name|Authorization|
|
||||
|In|header|
|
||||
|
||||
### /api/v2/barong/admin/users/data_storage
|
||||
|
||||
#### DELETE
|
||||
##### Description
|
||||
|
||||
Deletes user's data storage record
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | query | user uniq id | Yes | string |
|
||||
| title | query | data storage uniq title | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 204 | Deletes user's data storage record | [API_V2_Admin_Entities_UserWithKYC](#api_v2_admin_entities_userwithkyc) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/users/{uid}
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns user info
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | path | user uniq id | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Returns user info | [API_V2_Admin_Entities_UserWithKYC](#api_v2_admin_entities_userwithkyc) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/users/documents/pending
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns array of users with pending or replaced documents as paginated collection
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| extended | query | When true endpoint returns full information about users | No | boolean |
|
||||
| uid | query | | No | string |
|
||||
| email | query | | No | string |
|
||||
| role | query | | No | string |
|
||||
| first_name | query | | No | string |
|
||||
| last_name | query | | No | string |
|
||||
| country | query | | No | string |
|
||||
| level | query | | No | integer |
|
||||
| state | query | | No | string |
|
||||
| range | query | | No | string |
|
||||
| from | query | An integer represents the seconds elapsed since Unix epoch.If set, only records FROM the time will be retrieved. | No | integer |
|
||||
| to | query | An integer represents the seconds elapsed since Unix epoch.If set, only records BEFORE the time will be retrieved. | No | integer |
|
||||
| page | query | Page number (defaults to 1). | No | integer |
|
||||
| limit | query | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Returns array of users with pending or replaced documents as paginated collection | [API_V2_Entities_User](#api_v2_entities_user) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/users
|
||||
|
||||
#### PUT
|
||||
##### Description
|
||||
|
||||
Update user attributes
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | user uniq id | Yes | string |
|
||||
| email | formData | User Email | No | string |
|
||||
| state | formData | user state | No | string |
|
||||
| otp | formData | user 2fa status | No | boolean |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | User attributes were created |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns array of users as paginated collection
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| extended | query | When true endpoint returns full information about users | No | boolean |
|
||||
| uid | query | | No | string |
|
||||
| email | query | | No | string |
|
||||
| role | query | | No | string |
|
||||
| country | query | | No | string |
|
||||
| level | query | | No | integer |
|
||||
| state | query | | No | string |
|
||||
| range | query | | No | string |
|
||||
| ordering | query | If set, returned values will be sorted in specific order, defaults to 'asc'. | No | string |
|
||||
| order_by | query | Name of the field, which result will be ordered by. | No | string |
|
||||
| from | query | An integer represents the seconds elapsed since Unix epoch.If set, only records FROM the time will be retrieved. | No | integer |
|
||||
| to | query | An integer represents the seconds elapsed since Unix epoch.If set, only records BEFORE the time will be retrieved. | No | integer |
|
||||
| page | query | Page number (defaults to 1). | No | integer |
|
||||
| limit | query | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Returns array of users as paginated collection | [API_V2_Entities_User](#api_v2_entities_user) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/users/role
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Update user role
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | user uniq id | Yes | string |
|
||||
| role | formData | user role | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | User role was created |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
### /api/v2/barong/admin/users/update
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Update user attributes
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | user uniq id | Yes | string |
|
||||
| state | formData | user state | No | string |
|
||||
| otp | formData | user 2fa status | No | boolean |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | User attributes were updated |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
### /api/v2/barong/admin/users/labels
|
||||
|
||||
#### DELETE
|
||||
##### Description
|
||||
|
||||
Deletes label for user
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | query | user uniq id | Yes | string |
|
||||
| key | query | label key. [a-z0-9_-]+ should be used. Min - 3, max - 255 characters. | Yes | string |
|
||||
| scope | query | label key. [a-z0-9_-]+ should be used. Min - 3, max - 255 characters. | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 204 | Label was deleted |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
#### PUT
|
||||
##### Description
|
||||
|
||||
Update user label scope
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | user uniq id | Yes | string |
|
||||
| key | formData | Label key. | Yes | string |
|
||||
| scope | formData | label key. [a-z0-9_-]+ should be used. Min - 3, max - 255 characters. | Yes | string |
|
||||
| description | formData | label description. [A-Za-z0-9_-] should be used. max - 255 characters. | No | string |
|
||||
| value | formData | Label value. | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Label was updated |
|
||||
| 400 | Required params are empty |
|
||||
| 401 | Invalid bearer token |
|
||||
| 404 | Record is not found |
|
||||
| 422 | Validation errors |
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Add label for user
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | user uniq id | Yes | string |
|
||||
| key | formData | label key. [a-z0-9_-]+ should be used. Min - 3, max - 255 characters. | Yes | string |
|
||||
| value | formData | label value. [A-Za-z0-9_-] should be used. Min - 3, max - 255 characters. | Yes | string |
|
||||
| description | formData | label description. [A-Za-z0-9_-] should be used. max - 255 characters. | No | string |
|
||||
| scope | formData | Label scope: 'public' or 'private'. Default is public | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Label was created |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns array of users as paginated collection
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| key | query | Label key | Yes | string |
|
||||
| value | query | Label value | Yes | string |
|
||||
| page | query | Page number (defaults to 1). | No | integer |
|
||||
| limit | query | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Returns array of users as paginated collection | [API_V2_Entities_User](#api_v2_entities_user) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/users/labels/update
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Update user label value
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | user uniq id | Yes | string |
|
||||
| key | formData | Label key. | Yes | string |
|
||||
| scope | formData | label key. [a-z0-9_-]+ should be used. Min - 3, max - 255 characters. | Yes | string |
|
||||
| value | formData | Label value. | Yes | string |
|
||||
| description | formData | label description. [A-Za-z0-9_-] should be used. max - 255 characters. | No | string |
|
||||
| replace | formData | When true label will be created if not exist | No | boolean |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Label was updated |
|
||||
| 400 | Required params are empty |
|
||||
| 401 | Invalid bearer token |
|
||||
| 404 | Record is not found |
|
||||
| 422 | Validation errors |
|
||||
|
||||
### /api/v2/barong/admin/users/labels/list
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns existing labels keys and values
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Returns existing labels keys and values |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
### /api/v2/barong/admin/users/comments
|
||||
|
||||
#### DELETE
|
||||
##### Description
|
||||
|
||||
Delete user's comment
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| id | query | comment uniq id | Yes | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 204 | Delete user's comment | [API_V2_Admin_Entities_UserWithKYC](#api_v2_admin_entities_userwithkyc) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
#### PUT
|
||||
##### Description
|
||||
|
||||
Edit user's comment
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| id | formData | comment uniq id | Yes | integer |
|
||||
| title | formData | comment title | No | string |
|
||||
| data | formData | comment data | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Edit user's comment | [API_V2_Admin_Entities_UserWithKYC](#api_v2_admin_entities_userwithkyc) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Adds new user's comment
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | user uniq id | Yes | string |
|
||||
| title | formData | comment uniq title | Yes | string |
|
||||
| data | formData | comment data | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Adds new user's comment | [API_V2_Admin_Entities_UserWithKYC](#api_v2_admin_entities_userwithkyc) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/api_keys
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
List all api keys for selected account.
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | query | user uniq id | Yes | string |
|
||||
| ordering | query | If set, returned values will be sorted in specific order, defaults to 'asc'. | No | string |
|
||||
| order_by | query | Name of the field, which result will be ordered by. | No | string |
|
||||
| page | query | Page number (defaults to 1). | No | integer |
|
||||
| limit | query | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | List all api keys for selected account. | [API_V2_Entities_APIKey](#api_v2_entities_apikey) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/permissions
|
||||
|
||||
#### PUT
|
||||
##### Description
|
||||
|
||||
Update Permission
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| id | formData | Permission id | Yes | integer |
|
||||
| role | formData | permission field - role | No | string |
|
||||
| verb | formData | permission field - request verb | No | string |
|
||||
| path | formData | permission field - request path | No | string |
|
||||
| action | formData | | No | string |
|
||||
| topic | formData | | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Permission was updated |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
#### DELETE
|
||||
##### Description
|
||||
|
||||
Deletes permission
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| id | query | permission id | Yes | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 204 | Permission was deleted |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Create permission
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| role | formData | | Yes | string |
|
||||
| verb | formData | | Yes | string |
|
||||
| path | formData | | Yes | string |
|
||||
| action | formData | | Yes | string |
|
||||
| topic | formData | | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Permission was created |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns array of permissions as paginated collection
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| page | query | Page number (defaults to 1). | No | integer |
|
||||
| limit | query | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Returns array of permissions as paginated collection | [API_V2_Entities_Permission](#api_v2_entities_permission) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/activities/admin
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns array of activities as paginated collection
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| topic | query | | No | string |
|
||||
| action | query | | No | string |
|
||||
| uid | query | | No | string |
|
||||
| email | query | | No | string |
|
||||
| from | query | An integer represents the seconds elapsed since Unix epoch.If set, only records FROM the time will be retrieved. | No | integer |
|
||||
| to | query | An integer represents the seconds elapsed since Unix epoch.If set, only records BEFORE the time will be retrieved. | No | integer |
|
||||
| page | query | Page number (defaults to 1). | No | integer |
|
||||
| limit | query | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
| target_uid | query | | No | string |
|
||||
| range | query | | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Returns array of activities as paginated collection | [API_V2_Admin_Entities_AdminActivity](#api_v2_admin_entities_adminactivity) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/activities
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns array of activities as paginated collection
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| topic | query | | No | string |
|
||||
| action | query | | No | string |
|
||||
| uid | query | | No | string |
|
||||
| email | query | | No | string |
|
||||
| from | query | An integer represents the seconds elapsed since Unix epoch.If set, only records FROM the time will be retrieved. | No | integer |
|
||||
| to | query | An integer represents the seconds elapsed since Unix epoch.If set, only records BEFORE the time will be retrieved. | No | integer |
|
||||
| page | query | Page number (defaults to 1). | No | integer |
|
||||
| limit | query | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Returns array of activities as paginated collection | [API_V2_Admin_Entities_ActivityWithUser](#api_v2_admin_entities_activitywithuser) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/metrics
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns main statistic in the given time period
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| created_from | query | | No | string |
|
||||
| created_to | query | | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Returns main statistic in the given time period |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
### /api/v2/barong/admin/restrictions
|
||||
|
||||
#### DELETE
|
||||
##### Description
|
||||
|
||||
Delete restriction
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| id | query | Restriction id | Yes | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 204 | Restriction was deleted |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
#### PUT
|
||||
##### Description
|
||||
|
||||
Update restriction
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| id | formData | Restriction id | Yes | integer |
|
||||
| scope | formData | | No | string |
|
||||
| category | formData | | No | string |
|
||||
| value | formData | | No | string |
|
||||
| state | formData | | No | string |
|
||||
| code | formData | | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Restriction was updated |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Create restriction
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| scope | formData | | Yes | string |
|
||||
| value | formData | | Yes | string |
|
||||
| category | formData | | Yes | string |
|
||||
| state | formData | | No | string |
|
||||
| code | formData | | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Restriction was created |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns array of restrictions as a paginated collection
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| scope | query | | No | string |
|
||||
| category | query | | No | string |
|
||||
| range | query | | No | string |
|
||||
| page | query | Page number (defaults to 1). | No | integer |
|
||||
| limit | query | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Returns array of restrictions as a paginated collection | [API_V2_Entities_Restriction](#api_v2_entities_restriction) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/restrictions/whitelink
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Create whitelink
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| expire_time | formData | link will be active for (Time.now + expire_time in following range) | No | integer |
|
||||
| range | formData | In combination with expire_time gives full controll over token expiration | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Created whitelink |
|
||||
| 401 | Invalid bearer token |
|
||||
|
||||
### /api/v2/barong/admin/profiles
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Create a profile for user
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | | Yes | string |
|
||||
| first_name | formData | | No | string |
|
||||
| last_name | formData | | No | string |
|
||||
| dob | formData | | No | date |
|
||||
| address | formData | | No | string |
|
||||
| postcode | formData | | No | string |
|
||||
| city | formData | | No | string |
|
||||
| country | formData | | No | string |
|
||||
| metadata | formData | Any additional key: value pairs in json string format | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Create a profile for user | [API_V2_Admin_Entities_Profile](#api_v2_admin_entities_profile) |
|
||||
| 400 | Required params are empty | |
|
||||
| 401 | Invalid bearer token | |
|
||||
| 422 | Validation errors | |
|
||||
|
||||
#### PUT
|
||||
##### Description
|
||||
|
||||
Verify user's profile
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | | Yes | string |
|
||||
| state | formData | | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Verify user's profile | [API_V2_Admin_Entities_Profile](#api_v2_admin_entities_profile) |
|
||||
| 400 | Required params are empty | |
|
||||
| 401 | Invalid bearer token | |
|
||||
| 422 | Validation errors | |
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Return all profiles
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| page | query | Page number (defaults to 1). | No | integer |
|
||||
| limit | query | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Return all profiles | [API_V2_Admin_Entities_Profile](#api_v2_admin_entities_profile) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/levels
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Returns array of permissions as paginated collection
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Returns array of permissions as paginated collection | [API_V2_Entities_Level](#api_v2_entities_level) |
|
||||
| 401 | Invalid bearer token | |
|
||||
|
||||
### /api/v2/barong/admin/abilities
|
||||
|
||||
#### GET
|
||||
##### Description
|
||||
|
||||
Get all roles and admin_permissions of barong cancan.
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Get all roles and admin_permissions of barong cancan. |
|
||||
|
||||
### Models
|
||||
|
||||
#### API_V2_Admin_Entities_UserWithKYC
|
||||
|
||||
Adds new user's comment
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| email | string | User Email | No |
|
||||
| uid | string | User UID | No |
|
||||
| role | string | User role | No |
|
||||
| level | integer | User level | No |
|
||||
| otp | boolean | is 2FA enabled for account | No |
|
||||
| state | string | User state: active, pending, inactive | No |
|
||||
| referral_uid | string | UID of referrer | No |
|
||||
| data | string | Additional phone and profile info | No |
|
||||
| profiles | [API_V2_Admin_Entities_Profile](#api_v2_admin_entities_profile) | | No |
|
||||
| labels | [API_V2_Entities_AdminLabelView](#api_v2_entities_adminlabelview) | | No |
|
||||
| phones | [API_V2_Admin_Entities_Phone](#api_v2_admin_entities_phone) | | No |
|
||||
| documents | [API_V2_Admin_Entities_Document](#api_v2_admin_entities_document) | | No |
|
||||
| data_storages | [API_V2_Entities_DataStorage](#api_v2_entities_datastorage) | | No |
|
||||
| comments | [API_V2_Entities_Comment](#api_v2_entities_comment) | | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Admin_Entities_Profile
|
||||
|
||||
Return all profiles
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| first_name | string | First Name | No |
|
||||
| last_name | string | Last name | No |
|
||||
| dob | date | Birth date | No |
|
||||
| address | string | Address | No |
|
||||
| postcode | string | Address Postcode | No |
|
||||
| city | string | City name | No |
|
||||
| country | string | Country name | No |
|
||||
| state | string | Profile state: drafted, submitted, verified, rejected | No |
|
||||
| metadata | object | Profile additional fields | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_AdminLabelView
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| key | string | Label key. [a-z0-9_-]+ should be used. Min - 3, max - 255 characters. | No |
|
||||
| value | string | Label value. [A-Za-z0-9_-] should be used. Min - 3, max - 255 characters. | No |
|
||||
| scope | string | Label scope: 'public' or 'private' | No |
|
||||
| description | string | Label desc: json string with any additional information | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Admin_Entities_Phone
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| country | string | Phone country | No |
|
||||
| number | string | Phone number | No |
|
||||
| validated_at | s (g) | Phone validation date | No |
|
||||
|
||||
#### API_V2_Admin_Entities_Document
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| upload | string | File url | No |
|
||||
| doc_type | string | Document type: passport, driver license, utility bill, identity card, institutional, address, residental | No |
|
||||
| doc_number | string | document number: AB123123 type | No |
|
||||
| doc_expire | string | Expire date of uploaded documents | No |
|
||||
| metadata | string | Any additional stored data | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_DataStorage
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| title | string | Any additional data title | No |
|
||||
| data | string | Any additional data json key:value pairs | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_Comment
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| id | integer | Comment id | No |
|
||||
| author_uid | string | Comment author UID | No |
|
||||
| title | string | Comment title | No |
|
||||
| data | string | Comment plain text | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_User
|
||||
|
||||
Returns array of users as paginated collection
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| email | string | User Email | No |
|
||||
| uid | string | User UID | No |
|
||||
| role | string | User role | No |
|
||||
| level | integer | User level | No |
|
||||
| otp | boolean | is 2FA enabled for account | No |
|
||||
| state | string | User state: active, pending, inactive | No |
|
||||
| referral_uid | string | UID of referrer | No |
|
||||
| data | string | Additional phone and profile info | No |
|
||||
|
||||
#### API_V2_Entities_APIKey
|
||||
|
||||
List all api keys for selected account.
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| kid | string | JWT public key | No |
|
||||
| algorithm | string | Cryptographic hash function type | No |
|
||||
| scope | string | Serialized array of scopes | No |
|
||||
| state | string | active/non-active state of key | No |
|
||||
| secret | string | Api key secret | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_Permission
|
||||
|
||||
Returns array of permissions as paginated collection
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| id | integer | Permission id | No |
|
||||
| action | string | Permission action: accept (allow access (drop access), audit (record activity) | No |
|
||||
| role | string | Permission user role | No |
|
||||
| verb | string | Permission verb: put, post, delete, get | No |
|
||||
| path | string | API path | No |
|
||||
| topic | string | Permission topic: general, session etc | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Admin_Entities_AdminActivity
|
||||
|
||||
Returns array of activities as paginated collection
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| user_ip | string | User IP | No |
|
||||
| user_agent | string | User Browser Agent | No |
|
||||
| topic | string | Defined topic (session, adjustments) or general by default | No |
|
||||
| action | string | API action: POST => 'create', PUT => 'update', GET => 'read', DELETE => 'delete', PATCH => 'update' or system if there is no match of HTTP method | No |
|
||||
| result | string | Status of API response: succeed, failed, denied | No |
|
||||
| data | string | Parameters which was sent to specific API endpoint | No |
|
||||
| admin | [API_V2_Entities_User](#api_v2_entities_user) | | No |
|
||||
| target | [API_V2_Entities_User](#api_v2_entities_user) | | No |
|
||||
| created_at | string | | No |
|
||||
|
||||
#### API_V2_Admin_Entities_ActivityWithUser
|
||||
|
||||
Returns array of activities as paginated collection
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| user_ip | string | User IP | No |
|
||||
| user_agent | string | User Browser Agent | No |
|
||||
| topic | string | Defined topic (session, adjustments) or general by default | No |
|
||||
| action | string | API action: POST => 'create', PUT => 'update', GET => 'read', DELETE => 'delete', PATCH => 'update' or system if there is no match of HTTP method | No |
|
||||
| result | string | Status of API response: succeed, failed, denied | No |
|
||||
| data | string | Parameters which was sent to specific API endpoint | No |
|
||||
| user | [API_V2_Entities_User](#api_v2_entities_user) | | No |
|
||||
| created_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_Restriction
|
||||
|
||||
Returns array of restrictions as a paginated collection
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| id | integer | Restriction id | No |
|
||||
| category | string | Restriction categories: blacklist, maintenance, whitelist, blocklogin | No |
|
||||
| scope | string | Restriction scopes: continent, country, ip, ip_subnet, all | No |
|
||||
| value | string | Restriction value: IP address, country abbreviation, all | No |
|
||||
| code | integer | Restriction codes: {"continent"=>423, "country"=>423, "ip_subnet"=>403, "ip"=>401, "all"=>401} | No |
|
||||
| state | string | Restriction states: disabled, enabled | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_Level
|
||||
|
||||
Returns array of permissions as paginated collection
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| id | integer | Level identifier, level number | No |
|
||||
| key | string | Label key. [A-Za-z0-9_-] should be used. Min - 3, max - 255 characters. | No |
|
||||
| value | string | Label value. [A-Za-z0-9_-] should be used. Min - 3, max - 255 characters. | No |
|
||||
|
||||
#### API_V2_Admin_Entities_UserWithProfile
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| email | string | User Email | No |
|
||||
| uid | string | User UID | No |
|
||||
| role | string | User role | No |
|
||||
| level | integer | User level | No |
|
||||
| otp | boolean | is 2FA enabled for account | No |
|
||||
| state | string | User state: active, pending, inactive | No |
|
||||
| referral_uid | string | UID of referrer | No |
|
||||
| data | string | Additional phone and profile info | No |
|
||||
| profiles | [API_V2_Admin_Entities_Profile](#api_v2_admin_entities_profile) | | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
678
docs/api/barong_management_api_v2.md
Normal file
@@ -0,0 +1,678 @@
|
||||
# Barong
|
||||
Management API for barong OAuth server
|
||||
|
||||
## Version: 2.7.0
|
||||
|
||||
### Security
|
||||
**SecurityScope**
|
||||
|
||||
|basic|*Basic*|
|
||||
|---|---|
|
||||
|Description|JWT should have signature keychains|
|
||||
|Name|Authorization|
|
||||
|
||||
### /api/v2/barong/management/labels/delete
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Delete a label with 'private' scope
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| user_uid | formData | User uid | Yes | string |
|
||||
| key | formData | Label key. | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 201 | Delete a label with 'private' scope |
|
||||
|
||||
### /api/v2/barong/management/labels
|
||||
|
||||
#### PUT
|
||||
##### Description
|
||||
|
||||
Update a label with 'private' scope
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| user_uid | formData | User uid | Yes | string |
|
||||
| key | formData | Label key. | Yes | string |
|
||||
| value | formData | Label value. | Yes | string |
|
||||
| description | formData | Label desc. | No | string |
|
||||
| replace | formData | When true label will be created if not exist | No | boolean |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Update a label with 'private' scope | [API_V2_Entities_Label](#api_v2_entities_label) |
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Create a label with 'private' scope and assigns to users
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| user_uid | formData | User uid | Yes | string |
|
||||
| key | formData | Label key. | Yes | string |
|
||||
| value | formData | Label value. | Yes | string |
|
||||
| description | formData | Label desc. | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Create a label with 'private' scope and assigns to users | [API_V2_Entities_Label](#api_v2_entities_label) |
|
||||
|
||||
### /api/v2/barong/management/labels/list
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Get user collection filtered on label attributes
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| user_uid | formData | User uid | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Get user collection filtered on label attributes | [API_V2_Entities_AdminLabelView](#api_v2_entities_adminlabelview) |
|
||||
|
||||
### /api/v2/barong/management/labels/filter/users
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Get all labels assigned to users
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| key | formData | Label key. | Yes | string |
|
||||
| value | formData | Label value. | No | string |
|
||||
| scope | formData | Label scope. | No | string |
|
||||
| extended | formData | When true endpoint returns full information about users | No | boolean |
|
||||
| range | formData | | No | string |
|
||||
| page | formData | Page number (defaults to 1). | No | integer |
|
||||
| limit | formData | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Get all labels assigned to users | [API_V2_Entities_User](#api_v2_entities_user) |
|
||||
|
||||
### /api/v2/barong/management/users/import
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Imports an existing user
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| email | formData | User Email | Yes | string |
|
||||
| password_digest | formData | User Password Hash | Yes | string |
|
||||
| referral_uid | formData | Referral uid | No | string |
|
||||
| phone | formData | Phone | No | string |
|
||||
| first_name | formData | First Name | No | string |
|
||||
| last_name | formData | Last Name | No | string |
|
||||
| dob | formData | Birth date | No | date |
|
||||
| address | formData | Address | No | string |
|
||||
| postcode | formData | Postcode | No | string |
|
||||
| city | formData | City | No | string |
|
||||
| country | formData | Country | No | string |
|
||||
| state | formData | State | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Imports an existing user | [API_V2_Management_Entities_UserWithProfile](#api_v2_management_entities_userwithprofile) |
|
||||
|
||||
### /api/v2/barong/management/users/update
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Updates role and data fields of existing user
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | User Uid | Yes | string |
|
||||
| role | formData | User Role | No | string |
|
||||
| data | formData | Any additional key:value pairs in json format | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Updates role and data fields of existing user | [API_V2_Management_Entities_UserWithProfile](#api_v2_management_entities_userwithprofile) |
|
||||
|
||||
### /api/v2/barong/management/users
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Creates new user
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| email | formData | User Email | Yes | string |
|
||||
| password | formData | User Password | Yes | string |
|
||||
| referral_uid | formData | Referral uid | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Creates new user | [API_V2_Management_Entities_UserWithProfile](#api_v2_management_entities_userwithprofile) |
|
||||
|
||||
### /api/v2/barong/management/users/list
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Returns array of users as collection
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| extended | formData | When true endpoint returns full information about users | No | boolean |
|
||||
| range | formData | | No | string |
|
||||
| from | formData | An integer represents the seconds elapsed since Unix epoch.If set, only records FROM the time will be retrieved. | No | integer |
|
||||
| to | formData | An integer represents the seconds elapsed since Unix epoch.If set, only records BEFORE the time will be retrieved. | No | integer |
|
||||
| page | formData | Page number (defaults to 1). | No | integer |
|
||||
| limit | formData | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Returns array of users as collection | [API_V2_Entities_User](#api_v2_entities_user) |
|
||||
|
||||
### /api/v2/barong/management/users/get
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Get users and profile information
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | User uid | No | string |
|
||||
| email | formData | User email | No | string |
|
||||
| phone_num | formData | User phone number | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Get users and profile information | [API_V2_Management_Entities_UserWithKYC](#api_v2_management_entities_userwithkyc) |
|
||||
|
||||
### /api/v2/barong/management/profiles
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Imports a profile for user
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | User Uid | Yes | string |
|
||||
| first_name | formData | First Name | No | string |
|
||||
| last_name | formData | Last Name | No | string |
|
||||
| dob | formData | Birth date | No | date |
|
||||
| address | formData | Address | No | string |
|
||||
| postcode | formData | Postcode | No | string |
|
||||
| city | formData | City | No | string |
|
||||
| country | formData | Country | No | string |
|
||||
| state | formData | State | No | string |
|
||||
| metadata | formData | Metadata | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Imports a profile for user | [API_V2_Management_Entities_UserWithProfile](#api_v2_management_entities_userwithprofile) |
|
||||
|
||||
### /api/v2/barong/management/phones/delete
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Delete phone number for user
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | User uid | Yes | string |
|
||||
| number | formData | User phone number | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Delete phone number for user | [API_V2_Management_Entities_Phone](#api_v2_management_entities_phone) |
|
||||
|
||||
### /api/v2/barong/management/phones
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Create phone number for user
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | User uid | Yes | string |
|
||||
| number | formData | User phone number | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Create phone number for user | [API_V2_Management_Entities_Phone](#api_v2_management_entities_phone) |
|
||||
|
||||
### /api/v2/barong/management/phones/get
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Get user phone numbers
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | User uid | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Get user phone numbers | [API_V2_Management_Entities_Phone](#api_v2_management_entities_phone) |
|
||||
|
||||
### /api/v2/barong/management/otp/sign
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Sign request with barong signature
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| user_uid | formData | Account UID | Yes | string |
|
||||
| otp_code | formData | Code from Google Authenticator | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 201 | Sign request with barong signature |
|
||||
|
||||
### /api/v2/barong/management/documents
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Push documents to barong DB
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | User uid | Yes | string |
|
||||
| doc_type | formData | Document type | Yes | string |
|
||||
| doc_number | formData | Document number | Yes | string |
|
||||
| filename | formData | Document name | Yes | string |
|
||||
| file_ext | formData | Document file extension | Yes | string |
|
||||
| upload | formData | Base64 encoded document | Yes | string |
|
||||
| doc_expire | formData | Document expiration date | No | date |
|
||||
| update_labels | formData | If set to false, user label will not be created/updated | No | boolean |
|
||||
| metadata | formData | Any additional key: value pairs in json string format | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 201 | Push documents to barong DB |
|
||||
|
||||
### /api/v2/barong/management/service_accounts/delete
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Delete specific service_account
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | service_account uid | Yes | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Delete specific service_account | [API_V2_Entities_ServiceAccounts](#api_v2_entities_serviceaccounts) |
|
||||
|
||||
### /api/v2/barong/management/service_accounts/create
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Create service_account
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| owner_uid | formData | owner uid | Yes | string |
|
||||
| service_account_role | formData | service_account role | Yes | string |
|
||||
| service_account_uid | formData | service_account uid | No | string |
|
||||
| service_account_email | formData | service_account email | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Create service_account | [API_V2_Entities_ServiceAccounts](#api_v2_entities_serviceaccounts) |
|
||||
|
||||
### /api/v2/barong/management/service_accounts/list
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Get service_accounts as a paginated collection
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| page | formData | Page number (defaults to 1). | No | integer |
|
||||
| limit | formData | Number of users per page (defaults to 100, maximum is 100). | No | integer |
|
||||
| owner_uid | formData | owner uid | No | string |
|
||||
| owner_email | formData | owner email | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Get service_accounts as a paginated collection | [API_V2_Entities_ServiceAccounts](#api_v2_entities_serviceaccounts) |
|
||||
|
||||
### /api/v2/barong/management/service_accounts/get
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Get specific service_account information
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Located in | Description | Required | Schema |
|
||||
| ---- | ---------- | ----------- | -------- | ---- |
|
||||
| uid | formData | service_account uid | No | string |
|
||||
| email | formData | service_account email | No | string |
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 201 | Get specific service_account information | [API_V2_Entities_ServiceAccounts](#api_v2_entities_serviceaccounts) |
|
||||
|
||||
### /api/v2/barong/management/timestamp
|
||||
|
||||
#### POST
|
||||
##### Description
|
||||
|
||||
Returns server time in seconds since Unix epoch.
|
||||
|
||||
##### Responses
|
||||
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 201 | Returns server time in seconds since Unix epoch. |
|
||||
|
||||
### Models
|
||||
|
||||
#### API_V2_Entities_Label
|
||||
|
||||
Create a label with 'private' scope and assigns to users
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| key | string | Label key. [a-z0-9_-]+ should be used. Min - 3, max - 255 characters. | No |
|
||||
| value | string | Label value. [A-Za-z0-9_-] should be used. Min - 3, max - 255 characters. | No |
|
||||
| scope | string | Label scope: 'public' or 'private' | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_AdminLabelView
|
||||
|
||||
Get user collection filtered on label attributes
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| key | string | Label key. [a-z0-9_-]+ should be used. Min - 3, max - 255 characters. | No |
|
||||
| value | string | Label value. [A-Za-z0-9_-] should be used. Min - 3, max - 255 characters. | No |
|
||||
| scope | string | Label scope: 'public' or 'private' | No |
|
||||
| description | string | Label desc: json string with any additional information | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_User
|
||||
|
||||
Returns array of users as collection
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| email | string | User Email | No |
|
||||
| uid | string | User UID | No |
|
||||
| role | string | User role | No |
|
||||
| level | integer | User level | No |
|
||||
| otp | boolean | is 2FA enabled for account | No |
|
||||
| state | string | User state: active, pending, inactive | No |
|
||||
| referral_uid | string | UID of referrer | No |
|
||||
| data | string | Additional phone and profile info | No |
|
||||
|
||||
#### API_V2_Management_Entities_UserWithProfile
|
||||
|
||||
Imports a profile for user
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| email | string | User Email | No |
|
||||
| uid | string | User UID | No |
|
||||
| role | string | User role | No |
|
||||
| level | integer | User level | No |
|
||||
| otp | boolean | is 2FA enabled for account | No |
|
||||
| state | string | User state: active, pending, inactive | No |
|
||||
| referral_uid | string | UID of referrer | No |
|
||||
| data | string | Additional phone and profile info | No |
|
||||
| profiles | [API_V2_Management_Entities_Profile](#api_v2_management_entities_profile) | | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Management_Entities_Profile
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| first_name | string | First Name | No |
|
||||
| last_name | string | Last name | No |
|
||||
| dob | date | Birth date | No |
|
||||
| address | string | Address | No |
|
||||
| postcode | string | Address Postcode | No |
|
||||
| city | string | City name | No |
|
||||
| country | string | Country name | No |
|
||||
| state | string | Profile state: drafted, submitted, verified, rejected | No |
|
||||
| metadata | object | Profile additional fields | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Management_Entities_UserWithKYC
|
||||
|
||||
Get users and profile information
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| email | string | User Email | No |
|
||||
| uid | string | User UID | No |
|
||||
| role | string | User role | No |
|
||||
| level | integer | User level | No |
|
||||
| otp | boolean | is 2FA enabled for account | No |
|
||||
| state | string | User state: active, pending, inactive | No |
|
||||
| referral_uid | string | UID of referrer | No |
|
||||
| data | string | Additional phone and profile info | No |
|
||||
| profiles | [API_V2_Management_Entities_Profile](#api_v2_management_entities_profile) | | No |
|
||||
| labels | [API_V2_Entities_AdminLabelView](#api_v2_entities_adminlabelview) | | No |
|
||||
| phones | [API_V2_Management_Entities_Phone](#api_v2_management_entities_phone) | | No |
|
||||
| documents | [API_V2_Management_Entities_Document](#api_v2_management_entities_document) | | No |
|
||||
| data_storages | [API_V2_Entities_DataStorage](#api_v2_entities_datastorage) | | No |
|
||||
| comments | [API_V2_Entities_Comment](#api_v2_entities_comment) | | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Management_Entities_Phone
|
||||
|
||||
Get user phone numbers
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| country | string | Phone country | No |
|
||||
| number | string | Phone Number | No |
|
||||
| validated_at | s (g) | Phone validation date | No |
|
||||
|
||||
#### API_V2_Management_Entities_Document
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| upload | string | File url | No |
|
||||
| doc_type | string | Document type: passport, driver license, utility bill, identity card, institutional, address, residental | No |
|
||||
| doc_number | string | Document number: AB123123 type | No |
|
||||
| doc_expire | string | Expire date of uploaded documents | No |
|
||||
| metadata | string | Any additional stored data | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_DataStorage
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| title | string | Any additional data title | No |
|
||||
| data | string | Any additional data json key:value pairs | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_Comment
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| id | integer | Comment id | No |
|
||||
| author_uid | string | Comment author UID | No |
|
||||
| title | string | Comment title | No |
|
||||
| data | string | Comment plain text | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_ServiceAccounts
|
||||
|
||||
Get specific service_account information
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| email | string | User Email | No |
|
||||
| uid | string | User UID | No |
|
||||
| role | string | Service Account Role | No |
|
||||
| level | integer | User Level | No |
|
||||
| state | string | Service Account State: active, disabled | No |
|
||||
| user | [API_V2_Entities_User](#api_v2_entities_user) | | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_APIKey
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| kid | string | JWT public key | No |
|
||||
| algorithm | string | Cryptographic hash function type | No |
|
||||
| scope | string | Serialized array of scopes | No |
|
||||
| state | string | active/non-active state of key | No |
|
||||
| secret | string | Api key secret | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_UserWithFullInfo
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| email | string | User Email | No |
|
||||
| uid | string | User UID | No |
|
||||
| role | string | User role | No |
|
||||
| level | integer | User level | No |
|
||||
| otp | boolean | is 2FA enabled for account | No |
|
||||
| state | string | User state: active, pending, inactive | No |
|
||||
| referral_uid | string | UID of referrer | No |
|
||||
| data | string | Additional phone and profile info | No |
|
||||
| csrf_token | string | Сsrf protection token | No |
|
||||
| labels | [API_V2_Entities_Label](#api_v2_entities_label) | | No |
|
||||
| phones | [API_V2_Entities_Phone](#api_v2_entities_phone) | | No |
|
||||
| profiles | [API_V2_Entities_Profile](#api_v2_entities_profile) | | No |
|
||||
| data_storages | [API_V2_Entities_DataStorage](#api_v2_entities_datastorage) | | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
|
||||
#### API_V2_Entities_Phone
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| country | string | Phone country | No |
|
||||
| number | string | Submasked phone number | No |
|
||||
| validated_at | s (g) | Phone validation date | No |
|
||||
|
||||
#### API_V2_Entities_Profile
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| first_name | string | First Name | No |
|
||||
| last_name | string | Submasked last name | No |
|
||||
| dob | date | Submasked birth date | No |
|
||||
| address | string | Address | No |
|
||||
| postcode | string | Address Postcode | No |
|
||||
| city | string | City name | No |
|
||||
| country | string | Country name | No |
|
||||
| state | string | Profile state: drafted, submitted, verified, rejected | No |
|
||||
| metadata | object | Profile additional fields | No |
|
||||
| created_at | string | | No |
|
||||
| updated_at | string | | No |
|
||||
1317
docs/api/barong_user_api_v2.md
Normal file
2731
docs/api/swagger/admin_api.json
Normal file
1685
docs/api/swagger/management_api.json
Normal file
1
docs/api/swagger/user_api.json
Normal file
194
docs/configuration.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# Barong environments overview
|
||||
##### This document provides description, defaults and possible values for all environment variables that take a part in app configuration
|
||||
|
||||
### General configuration
|
||||
| Env name | Default value | Possible values | Description |
|
||||
| ---------- | ------ |-------------------------|---------------------------------- |
|
||||
| `barong_app_name` | Barong | any string value | Define app name for `2FA issuer` and `friendly_name` for twilio v2 verification |
|
||||
| `barong_domain` | openware.com | any string value | Value of the env will be sent as `domain` param in `EVENT API` in identity module, which helps mailer or 3rd party email send services to avoid additional configurations |
|
||||
| `barong_uid_prefix` | ID | any string value that matches regex: `/^[A-z]{2,6}$/` | This env configurate first 2-6 chars of UID |
|
||||
| `barong_session_name` | _barong_session | any string value | session cookie name |
|
||||
| `barong_session_expire_time` | 1800 | any number ( value is in seconds) | session lifetime (auto-renews on every private call |
|
||||
| `barong_required_docs_expire` | true | `false` `true` | force Barong to validate or not validate `expires_in` parameter at document creation. with `false` still can be sent and recorded but with no time validation |
|
||||
| `barong_doc_num_limit` | 10 | any amount number | number of maximum documents that can be attached to uniq user |
|
||||
| `barong_geoip_lang` | en | `en`, `de`, `es`, `fr`, `ja`, `ru` | internal GeoIP lang `Barong::GeoIP.lang`, which configures the language of detected country/continent name |
|
||||
| `barong_csrf_protection` | true | `true`, `false` | when turned on (`true`) exposes csrf_token on session create and requires X-CSRF-Token on every private POST PUT PATCH DELETE TRACE on AuthZ level |
|
||||
| `barong_apikey_nonce_lifetime` | 5000 | integer representation of milliseconds | nonce in api key headers should not be older than this env value |
|
||||
| `barong_gateway` | 'cloudflare' | `cloudflare`, `akamai` | when turned on (`true`) user IP on session and AuthZ level will firstly be checked in TRUE_CLIENT_IP header |
|
||||
| `barong_jwt_expire_time` | '3600' | integer representation of seconds | general purpose tokens (reset password, confirm email) expiration time |
|
||||
| `crc32_salt` | - | any string value | salt for crc32 algorithm which used to searching in encrypted fields |
|
||||
| `api_data_masking_enabled` | true | `true`, `false` | when turned on (`true`) user API will be with ecnrypted user data |
|
||||
|`first_registration_superadmin`| true | `true`, `false` | when turned on (`true`) first registered user on a platform will be superadmin without any email confirmation |
|
||||
|`mgn_api_keys_user`| false | `true`, `false` | when turned on (`true`) management API to create/update api keys will be provided for user entity|
|
||||
|`mgn_api_keys_sa`| false | `true`, `false` | when turned on (`true`) management API to create/update api keys will be provided for service account entity |
|
||||
|
||||
### Password configuration
|
||||
| Env name | Default value | Possible values | Description |
|
||||
| ---------- | ------ |-------------------------|---------------------------------- |
|
||||
| `barong_password_regexp` | ^(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:digit:]])(?=.*[[:graph:]]).{8,80}$ | any valid regex without / / | regex will validate password while user sign up / reset pass / password change |
|
||||
| `barong_password_min_entropy` | 14 | any positive int | minimal entropy required by password |
|
||||
| `barong_password_use_dictionary` | true | bool | activates or deactivates most common password dictionary check |
|
||||
|
||||
### Storage configuration
|
||||
More details in [storage configuration doc](#storage-configuration)
|
||||
|
||||
| Env name | Default value | Possible values | Description |
|
||||
| ---------- | ------ |-------------------------|---------------------------------- |
|
||||
| `barong_storage_provider` | local | `local` `google` `aws` `alicloud` | provider for documents store. this env may have an affected on other from this module |
|
||||
| `barong_storage_bucket_name` | local | any string value | bucket name, required for all providers |
|
||||
| `barong_storage_access_key` | - | any string value | access key for bucket, required for all providers |
|
||||
| `barong_storage_secret_key` | - | any string value | secret key for bucket, required for all providers |
|
||||
| `barong_storage_endpoint` | - | any string valid url value | custom storage endpoint, can be used for AWS, AliCloud providers |
|
||||
| `barong_storage_signature_version` | 4 | `2` `3` `4` | custom signature version, can be used for AWS provider |
|
||||
| `barong_storage_region` | - | any string value | bucket storage region |
|
||||
| `barong_storage_pathstyle` | false | `false` `true` | storage pathstyle, myght be used for AWS or AliCloud providers |
|
||||
| `barong_upload_size_min_range` | 1 | any integer value | minimum size of possible upload (in megabytes) |
|
||||
| `barong_upload_size_max_range` | 10 | any integer value | maximum size of possible upload (in megabytes) |
|
||||
| `barong_upload_auth_url_expiration` | 1 | any integer value | configures in minutes the lifetime of auth signature to see upload |
|
||||
| `barong_upload_extension_whitelist` | jpg, jpeg, png, pdf | string with comma-separated extensions formats | whitelist of upload extensions |
|
||||
|
||||
### API CORS configuration
|
||||
| Env name | Default value | Possible values | Description |
|
||||
| ---------- | ------ |-------------------------|---------------------------------- |
|
||||
| `barong_api_cors_origins` | * | any string valid url value or wildcard `*` | CORS configuration - url or wildcard |
|
||||
| `barong_api_cors_max_age` | 3600 | any number ( value is in seconds) | indicates how long the results of a preflight request can be cached, in seconds |
|
||||
| `barong_api_cors_allow_credentials` | false | `false` `true` | allows cookies to be sent in cross-domain responses |
|
||||
|
||||
### CAPTCHA configuration
|
||||
More details in [captcha policy doc](https://www.openware.com/sdk/docs/barong/general/captcha.html)
|
||||
|
||||
| Env name | Default value | Possible values | Description |
|
||||
| ---------- | ------ |-------------------------|---------------------------------- |
|
||||
| `barong_captcha` | none | `none` `recaptcha` `geetest` | configures captcha policy |
|
||||
| `barong_geetest_id` | - | any string value | geetest id for captcha from geetest.com |
|
||||
| `barong_geetest_key` | - | any string value | geetest id for captcha from geetest.com |
|
||||
| `barong_recaptcha_site_key` | - | any string value | site key for RECAPTCHA |
|
||||
| `barong_recaptcha_secret_key` | - | any string value | secret key for RECAPTCHA |
|
||||
|
||||
### Twilio configuration
|
||||
More details in [twilio configuration](#twilio-configuration)
|
||||
|
||||
| Env name | Default value | Possible values | Description |
|
||||
| ---------- | ------ |-------------------------|---------------------------------- |
|
||||
| `barong_phone_verification` | mock | `twilio_verify` , `twilio_sms` , `mock` | sms send policy, switcher between twilio services and stub (mock) |
|
||||
| `barong_twilio_phone_number` | +15005550000 | any twilio valid number or twilio string name | Twilio sms sender number/name |
|
||||
| `barong_twilio_account_sid` | - | any string value | twilio account sid, required by configuration |
|
||||
| `barong_twilio_auth_token` | - | any string value | twilio auth token, required by configuration |
|
||||
| `barong_twilio_service_sid` | - | any string value | twilio service sid, required by configuration of `twilio_verify` policy |
|
||||
| `barong_sms_content_template` | Your verification code for Barong: `{{code}}` | any string value containing `{{code}}` | template, used in both configurations as content for SMS |
|
||||
|
||||
### RabbitMQ configuration
|
||||
| Env name | Default value | Possible values | Description |
|
||||
| ---------- | ------ |-------------------------|---------------------------------- |
|
||||
| `barong_event_api_rabbitmq_host` | localhost | any string value | rabbitmq server host |
|
||||
| `barong_event_api_rabbitmq_port` | 5672 | any valid port string | rabbitmq server port |
|
||||
| `barong_event_api_rabbitmq_username` | guest | any string value | rabbitmq server access username |
|
||||
| `barong_event_api_rabbitmq_password` | guest | any string value | rabbitmq server access password |
|
||||
|
||||
### Redis configuration
|
||||
| `barong_redis_cluster` | `false` | `false` `true` | define redis mode usage (https://redis.io/topics/cluster-tutorial) |
|
||||
| `barong_redis_url` | `redis://localhost:6379/1` | any valid url | url of redis server with port |
|
||||
| `barong_redis_password` | ~ | any string value | redis server access password |
|
||||
|
||||
### Vault configuration
|
||||
| `barong_vault_address` | `http://localhost:8200` | any valid url | vault server url with port |
|
||||
| `barong_vault_token` | | any string value | vault access token |
|
||||
| `barong_vault_app_name` | barong | any string value | the name of the application, all encryption keys in Vault will be prefixed with this application name |
|
||||
|
||||
### Sentry configuration
|
||||
| `barong_sentry_dsn_backend` | ~ | valid host url | Sentry SDK client key |
|
||||
|
||||
### Auth0 configuration
|
||||
|
||||
| Env name | Default value | Possible values | Description |
|
||||
| ---------- | :------: |:------: |---------------------------------- |
|
||||
|`auth0_domain`| - | any string value | auth0 Domain name (without https://) |
|
||||
|`auth0_client_id`| - | any string value | the client_id of your auth0 application |
|
||||
|
||||
### SMTP configuration
|
||||
| Env name | Default value | Possible values | Description |
|
||||
| ---------- | ------ |-------------------------|---------------------------------- |
|
||||
| `barong_sender_email` | noreply@barong.io | any valid email | this will be displayed as sender email for client in all outbox |
|
||||
| `barong_sender_name` | Barong | any string value | this will be displayed as sender name for client in all outbox |
|
||||
| `barong_smtp_password` | - | any string value | password for auth 3d party send emails service smtp |
|
||||
| `barong_smtp_port` | 1025 | any integer value | port for auth 3d party send emails service smtp |
|
||||
| `barong_smtp_host` | localhost | valid host url | host for auth 3d party send emails service smtp |
|
||||
| `barong_smtp_user` | - | any string value | username for auth 3d party send emails service smtp |
|
||||
| `barong_default_language` | en | alpha-2 country | default language for email letters |
|
||||
|
||||
### Config files configuration
|
||||
| Env name | Default value | Possible values | Description |
|
||||
| ---------- | ------ |-------------------------|---------------------------------- |
|
||||
| `barong_config` | config/barong.yml | any valid path to existing file | path to barong config with `activation_requirements`, `state_triggers`, `document_types` and `user_storage_titles` |
|
||||
| `barong_maxminddb_path` | geolite/GeoLite2-Country.mmdb | any valid path to existing file | path to geolite country DB file |
|
||||
| `barong_seeds_file` | config/seeds.yml | any valid path to existing file | path to configuration file with pre-defined API rules, users and levels |
|
||||
| `barong_authz_rules_file` | config/authz_rules.yml | any valid path to existing file | path to configuration file with blacklisted and whitelisted API pathes |
|
||||
|
||||
# Barong configurations overview
|
||||
## Twilio configuration
|
||||
For twilio configuration we need to set such required envs
|
||||
- `BARONG_TWILIO_ACCOUNT_SID`, which acts as a twilio username
|
||||
- `BARONG_TWILIO_SERVICE_SID`, which acts as a twilio password
|
||||
- `BARONG_TWILIO_PHONE_NUMBER`, virtual phone numbers which will give you instant access to local, national, mobile, and toll-free phone numbers
|
||||
|
||||
We have ability to set twilio with 3 different ways
|
||||
1. ```BARONG_PHONE_VERIFICATION == "twilio_sms"```
|
||||
If you choose phone verification as twilio sms we will use send_sms [API call](https://www.twilio.com/docs/sms/send-messages)
|
||||
Also you can add your own template for sms using `BARONG_SMS_CONTENT_TEMPLATE`
|
||||
2. ```BARONG_PHONE_VERIFICATION == "twilio_verify"```
|
||||
In this case we will use twilio Verify [API call](https://www.twilio.com/docs/verify/api)
|
||||
There are a lot of benefits of using Verify API like you can validate users via voice
|
||||
One verification service can be used to send multiple verification tokens, it is not necessary to create a new service each time, so you can set ```BARONG_TWILIO_SERVICE_SID``` at once
|
||||
3. ```BARONG_PHONE_VERIFICATION == "mock"```
|
||||
With this type of verification all the numbers will be accepted and validated as a right code for any given number
|
||||
|
||||
---
|
||||
|
||||
## Blacklist/Whitelist configuration
|
||||
|
||||
`Pass` routes will never be checked by AuthZ endpoint and will be available without session requirement. On `Block` routes user always will get 401, it doesn't depend on a session / role / ip / etc
|
||||
|
||||
You need to put whitelisted (public) routes for pass object and blacklisted routes for block in authz_rules.yml
|
||||
|
||||
```yml
|
||||
rules:
|
||||
pass:
|
||||
- api/v2/barong/identity
|
||||
- api/v2/peatio/public
|
||||
- api/v2/ranger/public
|
||||
- api/v2/applogic/public
|
||||
block:
|
||||
- api/v2/barong/management
|
||||
- api/v2/peatio/managemen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## State configuration
|
||||
|
||||
We can customize barong configuration as we want
|
||||
|
||||
1. For user activation we just need to have verified email label in example below. You can put more labels to create your own rules for user activation
|
||||
2. For example, if you want to ban your user you just need to put ban and fraud labels on tower admin panel. For sure you can customize this case too and put change or add label names in barong.yml
|
||||
3. For document verification we use, as standard - following document types. But you can configure available document types by changing or extending existing list. This way we keep an opportunity to support any custom KYC services, logic, etc
|
||||
|
||||
```yml
|
||||
activation_requirements:
|
||||
email: 'verified'
|
||||
state_triggers:
|
||||
banned:
|
||||
- ban
|
||||
- fraud
|
||||
deleted:
|
||||
- delete
|
||||
locked:
|
||||
- suspicious
|
||||
- lock
|
||||
document_types:
|
||||
- Passport
|
||||
- Identity card
|
||||
- Driver license
|
||||
- Utility Bill
|
||||
- Residental
|
||||
- Institutional
|
||||
```
|
||||
39
docs/development/mailer.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Run the barong mailer locally
|
||||
|
||||
## Prerequisites
|
||||
You need to following deamons running
|
||||
|
||||
1. RabbitMQ
|
||||
2. Redis
|
||||
|
||||
## Start Rails console
|
||||
|
||||
```bash
|
||||
rails console
|
||||
```
|
||||
|
||||
## Start the mailer
|
||||
|
||||
1. Generate the barong public key in base64 format
|
||||
|
||||
```
|
||||
cat config/rsa-key.pub | base64 -w0 (base64 -b0 for MacOS users)
|
||||
```
|
||||
|
||||
2. Configure it in config/mailer.yml
|
||||
Replace *changeme* with the previous generated string.
|
||||
|
||||
```yaml
|
||||
keychain:
|
||||
barong:
|
||||
algorithm: RS256
|
||||
value: "changeme"
|
||||
```
|
||||
|
||||
## Generate an event
|
||||
|
||||
From the rails console you can generate an event by creating a label on a user:
|
||||
|
||||
```ruby
|
||||
Label.create!(user_id:1, key: 'phone', value: 'verified')
|
||||
```
|
||||
70
docs/general/2fa.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Setting up 2FA
|
||||
|
||||
This document describes Barong [TOTP](https://tools.ietf.org/html/rfc6238) setup
|
||||
using [Vault](https://www.vaultproject.io/intro/getting-started/install.html).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
[Vault](https://www.vaultproject.io/intro/getting-started/install.html)
|
||||
with [TOTP secrets engine](https://www.vaultproject.io/docs/secrets/totp/index.html#setup) enabled.
|
||||
|
||||
## Configuration
|
||||
|
||||
To use Vault with Barong you will need to set the following environment variables:
|
||||
|
||||
```shell
|
||||
export VAULT_ADDR=http://your-vault-url.com
|
||||
export VAULT_TOKEN=12345-vault-t0k3n-54321
|
||||
```
|
||||
|
||||
To allow using Google Authenticator `VAULT_ADDR` should be _public_ ip.
|
||||
|
||||
Note, that TOTP uses time-based algorithm.
|
||||
So, if you want to test 2FA with phone, make sure, that your Vault's server time and your phone's time are synchronized, or it will not work.
|
||||
[ntpdate](http://doc.ntp.org/4.1.1/ntpdate.htm) can help you to update your time with ntp servers:
|
||||
|
||||
```shell
|
||||
sudo ntpdate 0.ua.pool.ntp.org
|
||||
```
|
||||
|
||||
|
||||
## Developer How-tos
|
||||
|
||||
### Getting a code without Google Authenticator:
|
||||
|
||||
* From _shell_:
|
||||
|
||||
```shell
|
||||
$ vault login
|
||||
$ vault read totp/code/IDMYAWESOMEID
|
||||
```
|
||||
|
||||
* From _rails console_:
|
||||
|
||||
```ruby
|
||||
> me = Account.find_by_email('me@example.com')
|
||||
> Vault.logical.read("totp/code/#{me.uid}")
|
||||
```
|
||||
|
||||
### Getting a new key (e.g. if you lost your Google Authenticator):
|
||||
|
||||
* From _shell_:
|
||||
|
||||
```shell
|
||||
$ vault login
|
||||
$ vault write totp/keys/IDMYAWESOMEID \
|
||||
generate=true \
|
||||
issuer=Barong \
|
||||
account_name=me@example.com
|
||||
```
|
||||
|
||||
* From _rails console_:
|
||||
|
||||
```ruby
|
||||
> me = Account.find_by_email('me@example.com')
|
||||
> Vault::TOTP.send(:create, me.uid)
|
||||
```
|
||||
|
||||
Each response includes equivalent base64-encoded barcode and OTP url.
|
||||
You can find the key's secret in this OTP url query params.
|
||||
|
||||
35
docs/general/activities.md
Normal file
@@ -0,0 +1,35 @@
|
||||
### Activities
|
||||
|
||||
To track admin activities you need to define it on seed.yml on `permissions` key
|
||||
- `role` should be in a range of existing: `admin`, `superadmin`, `support`, `techical`, `accountant`
|
||||
- `verb` should be `post`, `get`, `put`, `delete`
|
||||
- `path` - endpoint which should be checked, should be started with `api/v2/#{component}` as prefix
|
||||
- `action` should be `audit`
|
||||
```
|
||||
For example
|
||||
|
||||
permissions:
|
||||
- { role: 'admin', verb: 'post', path: api/v2/admin, action: audit }
|
||||
```
|
||||
|
||||
Here you can see a list of possible fields for activity:
|
||||
| Field | Type | Description |
|
||||
|:-----------|:--------:|:-----------:|
|
||||
| user_id | bigint | ID of user who creates activity |
|
||||
| target_uid | string | User UID for whom activity was created (admin remove OTP for user, target_uid will be uid of user for which admin removed OTP|
|
||||
| category | string | `admin` (admin activities), `user` (user activities)|
|
||||
| user_ip | string | IP address |
|
||||
| user_agent | string | User Agent such as `Mozilla/5.0`|
|
||||
| topic | string | Defined topic (`session`, `adjustments`) or `general` by default|
|
||||
| action | string | API action: `POST => 'create'`, `PUT => 'update'`, `GET => 'read'`, `DELETE => 'delete'`, `PATCH => 'update'` or `system` if there is no match of HTTP method|
|
||||
| result | string | Status of API response: `succeed`, `failed`, `denied`|
|
||||
| data | text | Parameters which was sent to specific API endpoint|
|
||||
| created_at | datetime | Time of activity creation|
|
||||
|
||||
##### Useful commands
|
||||
If you want to delete old activities you can run next command
|
||||
|
||||
Be sure that your parameters has valid date string, such as `YYYY-mm-dd` !
|
||||
```
|
||||
bundle exec rake activities:delete[from,to]
|
||||
```
|
||||
142
docs/general/api-keys.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# Barong API keys creation and usage
|
||||
|
||||
This document explains how to create an API key on barong using the UI or command line tool.
|
||||
This API key can be used to access microservices in the cluster protected by barong authentication.
|
||||
You can find below an example how to use the API key.
|
||||
|
||||
## How to create API key ?
|
||||
|
||||
### Using UI (recommended option)
|
||||
|
||||
1. Find API keys section (often located on profile page).
|
||||
|
||||

|
||||
|
||||
2. Create your API key and securely save Access Key and Secret Key
|
||||
|
||||

|
||||
|
||||
### Using API (use this option in case your frontend doesn't support API keys feature)
|
||||
|
||||
1. Install [httpie](https://httpie.org/)
|
||||
|
||||
2. Login into your account using httpie
|
||||
|
||||
```bash
|
||||
http --session barong_session https://your.domain/api/v2/barong/identity/sessions \
|
||||
email=your@email.com password=changeme otp_code=000000
|
||||
```
|
||||
Example of response:
|
||||
```json
|
||||
{
|
||||
"created_at": "2020-06-01T07:01:20Z",
|
||||
"csrf_token": "f5b36515a428328e199a",
|
||||
"data": "{\"language\":\"en\"}",
|
||||
"data_storages": [],
|
||||
"email": "your@example.com",
|
||||
"labels": [
|
||||
{
|
||||
"created_at": "2020-06-01T07:01:45Z",
|
||||
"key": "email",
|
||||
"scope": "private",
|
||||
"updated_at": "2020-06-01T07:01:45Z",
|
||||
"value": "verified"
|
||||
}
|
||||
],
|
||||
"level": 5,
|
||||
"otp": true,
|
||||
"phones": [
|
||||
{
|
||||
"country": "FR",
|
||||
"number": "33*****0471",
|
||||
"validated_at": "2020-06-01T07:03:18.000Z"
|
||||
}
|
||||
],
|
||||
"profiles": [],
|
||||
"referral_uid": null,
|
||||
"role": "member",
|
||||
"state": "active",
|
||||
"uid": "IDAF1AED1A42",
|
||||
"updated_at": "2020-10-22T18:01:09Z"
|
||||
}
|
||||
```
|
||||
|
||||
3. Validate your session
|
||||
|
||||
```bash
|
||||
http --session barong_session https://your.domain.com/api/v2/peatio/account/balances
|
||||
```
|
||||
|
||||
4. Create your API key
|
||||
|
||||
```
|
||||
http --session barong_session https://your.domain.com/api/v2/barong/resource/api_keys \
|
||||
algorithm=HS256 totp_code=681757 x-csrf-token:f5b36515a428328e199a
|
||||
```
|
||||
|
||||
Expected response:
|
||||
|
||||
```json
|
||||
{
|
||||
"algorithm": "HS256",
|
||||
"created_at": "2019-12-23T12:22:15Z",
|
||||
"kid": "61d025b8573501c2", // Access Key
|
||||
"scope": [],
|
||||
"secret": {
|
||||
"auth": null,
|
||||
"data": {
|
||||
"value": "2d0b4979c7fe6986daa8e21d1dc0644f" // Secret Key
|
||||
},
|
||||
"lease_duration": 2764800,
|
||||
"lease_id": "",
|
||||
"metadata": null,
|
||||
"renewable": false,
|
||||
"warnings": null,
|
||||
"wrap_info": null
|
||||
},
|
||||
"state": "active",
|
||||
"updated_at": "2019-12-23T12:22:15Z"
|
||||
}
|
||||
```
|
||||
|
||||
5. Securely save Access Key and Secret Key
|
||||
|
||||
## How to use API key ?
|
||||
|
||||
To authenticate using API key you need to pass next 3 headers:
|
||||
|
||||
| Header | Description |
|
||||
| ---------------- | ------------------------------------------------------------ |
|
||||
| X-Auth-Apikey | Access Key for API key (see 'How to create API key section ?') |
|
||||
| X-Auth-Nonce | Timestamp in milliseconds (can be passed as a string) |
|
||||
| X-Auth-Signature | HMAC-SHA256, calculated using concatenation of X-Auth-Nonce and Access Key |
|
||||
|
||||
1. Generate X-Auth-Nonce - unique string (e.g current unix timestamp)
|
||||
|
||||
```bash
|
||||
date +%s%3N
|
||||
1584524005143
|
||||
```
|
||||
|
||||
Nonce will be validated on server side to be not older than 5 seconds from the generation moment
|
||||
|
||||
2. Calculate X-Auth-Signature header.
|
||||
|
||||
X-Auth-Signature is HMAC-SHA256, calculated using concatenation of X-Auth-Nonce and Access Key.
|
||||
|
||||
```ruby
|
||||
nonce = (Time.now.to_f * 1000).to_i.to_s # timestamp in milliseconds, ex: 1584524005143
|
||||
access_key = '61d025b8573501c2' # Access Key from 'How to create API key section ?'
|
||||
secret_key = '2d0b4979c7fe6986daa8e21d1dc0644f' # Secret Key from 'How to create API key section ?'
|
||||
OpenSSL::HMAC.hexdigest("SHA256", secret_key, nonce + access_key)
|
||||
# => "bd42b945e095880e28d046846dbecf655fdf09d95a396a24fe6fe1df42f15d13"
|
||||
```
|
||||
|
||||
3. Pass your headers in httpie (note `--session` is not needed anymore)
|
||||
|
||||
```
|
||||
http https://your.domain.com/api/v2/peatio/account/balances \
|
||||
"X-Auth-Apikey: 61d025b8573501c2" \
|
||||
"X-Auth-Nonce: 1584524005143" \
|
||||
"X-Auth-Signature: bd42b945e095880e28d046846dbecf655fdf09d95a396a24fe6fe1df42f15d13"
|
||||
```
|
||||
48
docs/general/auth0.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Auth0 integration
|
||||
|
||||
## How to create an application
|
||||
|
||||
When you signed up for Auth0, a new application was created for you, or you could have created a new one (the most appropriate application for our structure is Single Page Application).
|
||||

|
||||
|
||||
You will need some details about that application to communicate with Auth0. You can get these details from the Application Settings section in the Auth0 dashboard.
|
||||
|
||||

|
||||
|
||||
You should put `auth0_domain` from the Domain field and `auth0_client_id` from the Client ID field
|
||||
|
||||
For a single page application better to use authorization code flow with proof key for code exchange.
|
||||
|
||||
## Authorization Code Flow with Proof Key for Code Exchange (PKCE)
|
||||
When public clients request Access Tokens, some additional security concerns are posed that are not mitigated by the Authorization Code Flow alone. This is because single-page apps cannot securely store a Client Secret because their entire source is available to the browser.
|
||||
|
||||
|
||||
### How it works
|
||||

|
||||
Because the PKCE-enhanced Authorization Code Flow builds upon the standard Authorization Code Flow, the steps are very similar.
|
||||
|
||||
1. The user clicks Login within the application.
|
||||
|
||||
2. Auth0's SDK creates a cryptographically-random code_verifier and from this generates a code_challenge.
|
||||
|
||||
3. Auth0's SDK redirects the user to the Auth0 Authorization Server (/authorize endpoint) along with the code_challenge.
|
||||
|
||||
4. Your Auth0 Authorization Server redirects the user to the login and authorization prompt.
|
||||
|
||||
5. The user authenticates using one of the configured login options and may see a consent page listing the permissions Auth0 will give to the application.
|
||||
|
||||
6. Your Auth0 Authorization Server stores the code_challenge and redirects the user back to the application with an authorization code, which is good for one use.
|
||||
|
||||
7. Auth0's SDK sends this code and the code_verifier (created in step 2) to the Auth0 Authorization Server (/oauth/token endpoint).
|
||||
|
||||
8. Your Auth0 Authorization Server verifies the code_challenge and code_verifier.
|
||||
|
||||
9. Your Auth0 Authorization Server responds with an ID Token and Access Token (and optionally, a Refresh Token).
|
||||
|
||||
10. Your application can use the Access Token to call an API to access information about the user.
|
||||
|
||||
11. The API responds with requested data.
|
||||
|
||||
You can try to call your [API using the authorization Code Flow with PKCE](https://auth0.com/docs/flows/call-your-api-using-the-authorization-code-flow-with-pkce).
|
||||
|
||||
Also you can find a link with [Authentication API description](https://auth0.com/docs/api/authentication#introduction) here.
|
||||
32
docs/general/captcha.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Barong Captcha Policy
|
||||
#### Overview
|
||||
A CAPTCHA (an acronym for "Completely Automated Public Turing test to tell Computers and Humans Apart") is a type of challenge–response test used in computing to determine whether or not the user is human) [Link to wiki](https://en.wikipedia.org/wiki/CAPTCHA)
|
||||
|
||||
Currently Barong versions 2.3+ supports 3 options in captcha policy on `sign up` and `sign in` API endpoints.
|
||||
|
||||
Configuration manages through environment variable - `BARONG_CAPTCHA`. Available values - `geetest`, `recaptcha`, `none`.
|
||||
With a wrong value barong will fail on start with error: `#{KEY} invalid, enabled values: NONE GEETEST RECAPTCHA`.
|
||||
|
||||
## Disabled (default)
|
||||
`none` - if ENV `BARONG_CAPTCHA` has this value - no captcha response will be required on sign in and sign up, so no bot traffic prevention.
|
||||
This option is not recommended to use in `production` environment.
|
||||
`None` policy was designed in testing and demo purposes, to start barong without any additional keys.
|
||||
|
||||
## Re CAPTCHA v2
|
||||
reCAPTCHA is a free service that protects your site from spam and abuse. It uses advanced risk analysis techniques to tell humans and bots apart. [Get started from google team](https://developers.google.com/recaptcha/intro)
|
||||
|
||||
`recaptcha` - this value in `BARONG_CAPTCHA` env enables re_captcha protection, designed and maintained by Google company. [Small developers tips from google team](https://developers.google.com/recaptcha/docs/display)
|
||||
|
||||
To properly configurate re_captcha you will need to set value for ENVs `recaptcha_site_key` and `recaptcha_secret_key`. Both of them you can generate [in google admin panel](https://www.google.com/recaptcha/admin/create)
|
||||
|
||||
After enabling and configuring captcha, `sign up` and `sign in` endpoint will require new parameter - `captcha_response`(`string`) and validate captcha response on server side, to protect from bots traffic.
|
||||
|
||||
## Geetest Captcha (Puzzle captcha)
|
||||
|
||||
GeeTest captcha is an user-friendly captcha with high security. GeeTest captcha enables digital businesses to secure control of their websites against bots. [geetest captcha site](https://www.geetest.com)
|
||||
|
||||
`geetest` - this value in BARONG_CAPTCHA env enables geetest captcha protection, designed and maintained by geetest.com
|
||||
|
||||
To properly configurate `geetest` you will need to set value for ENVs `geetest_id` and `geetest_key`. How to generate them, you can find in official [get started guide](https://docs.geetest.com/captcha/overview/guide)
|
||||
|
||||
After enabling and configuring geetest captcha, `sign up` and `sign in` endpoint will require new parameter - `captcha_response`(`hash` - with three keys `geetest_challenge`, `geetest_seccode`, `geetest_validate`) and validate captcha response on server side, to protect from bots traffic.
|
||||
46
docs/general/encryption.md
Normal file
@@ -0,0 +1,46 @@
|
||||
## Encryption
|
||||
|
||||
Data sensitivity will be defined as follow:\
|
||||
**Low**: IP address\
|
||||
**Medium**: Email address, Location data\
|
||||
**High**: Full name, Street address, phone number, date of birth\
|
||||
**Very High**: Passport number, Driver’s license number
|
||||
|
||||
Low and Medium will not be masked on the UI.
|
||||
|
||||
| Field | Mask | Comment |
|
||||
|---|---|---|
|
||||
| Street address | No mask | No need |
|
||||
| First Name | No mask | No need |
|
||||
| Last Name | B****** | Display first letter |
|
||||
| Phone Number | +380 **** 4556 | Display country code and last 4 digits |
|
||||
| Date of birth | 1980-01-** | Hide day |
|
||||
| Document Number | FG****64 | First 2 number and last 2 digits |
|
||||
|
||||
### Approach
|
||||
Rails offers a handy ActiveSupport::MessageEncryptor class, that hides away all the complexity of data encryption, and was wrapped in a simple to use service object or reusable module.
|
||||
|
||||
Service object class doing the actual heavy lifting, but only exposing two straightforward public class methods encrypt and decrypt.
|
||||
|
||||
System have weekly salt rotation, so encrypted keys in DB will be prepended with salt, which will be mix of year and week number starting from 0.
|
||||
|
||||
Make sure to store `SECRET_KEY_BASE` somewhere safe otherwise, you would not be able to decrypt your secure data, also you need to have this ENV variable at the start of your application as it will not create models (Profile, Phone, Documents) which have encrypted fields.
|
||||
|
||||
#### Searching by encrypted values
|
||||
|
||||
To have ability to search by encrypted fields, system implements additional field named `attribute_index` which use [crc32 algorithm](http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html) for storing attribute value.
|
||||
|
||||
Make sure you have `BARONG_CRC32_SALT` to make algrithm more powerful.
|
||||
|
||||
#### Rotation
|
||||
|
||||
To update all encrypted fields to latest key values (salt will be "#{current_year}#{current_week}"), you can use following rake tasks:
|
||||
|
||||
`rake rotate:phones`
|
||||
`rake rotate:profiles`
|
||||
`rake rotate:documents`
|
||||
|
||||
### Fields masking on user API
|
||||
|
||||
Sensitive data fields like `last name`, `dob`, `phone number`, `document number` are masked in user API by default.
|
||||
You can disable this masking by changing the environment variable `BARONG_API_DATA_MASKING_ENABLED` to `false`.
|
||||
179
docs/general/errors.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# Barong errors list
|
||||
|
||||
## Resource module errors
|
||||
|
||||
```
|
||||
resource.labels.private - Can't update Label.
|
||||
resource.user.no_activity No activity recorded or wrong topic
|
||||
resource.user.empty_otp_code Cant delete account. 2FA is on, but otp_code is empty
|
||||
resource.user.invalid_otp Cant delete account. 2FA is on, but otp_code is invalid
|
||||
resource.user.missing_otp_code Cant delete account. 2FA is on, but otp_code is missing
|
||||
resource.user.invalid_password Cant delete account. Password is wrong
|
||||
resource.profile.not_exist User has no profile
|
||||
resource.profile.exist Profile already exists
|
||||
resource.api_key.2fa_disabled Only accounts with enabled 2FA alowed
|
||||
resource.api_key.missing_otp Theaccount has enabled 2FA but OTP code is missing
|
||||
resource.api_key.invalid_otp OTP code is invalid
|
||||
resource.phone.twillio Something wrong with Twilio Client
|
||||
resource.phone.invalid_num Phone number is invalid
|
||||
resource.phone.number_exist Phone number already exists
|
||||
resource.phone.verification_invalid Phone is not found or verification code is invalid
|
||||
resource.documents.limit_reached Maximum number of documents already reached
|
||||
resource.documents.limit_will_be_reached Documents amount will reach limit by this upload
|
||||
resource.otp.already_enabled 2FA has been already enabled for this account
|
||||
resource.otp.invalid OTP code is invalid
|
||||
resource.password.doesnt_match New passwords don\'t match
|
||||
resource.password.prev_pass_not_correct Previous password is not correct
|
||||
resource.password.no_change_provided New password cant be the same, as old one
|
||||
```
|
||||
|
||||
## Identity module errors
|
||||
|
||||
```
|
||||
identity.user.invalid_referral_format Invalid referral uid format
|
||||
identity.user.referral_doesnt_exist Referral doesn't exist
|
||||
identity.user.active_or_doesnt_exist User doesn't exist or has already been activated'
|
||||
identity.password.user_doesnt_exist User doesn't exist
|
||||
identity.user.passwords_doesnt_match Passwords don't match
|
||||
identity.user.utilized_token JWT has already been used
|
||||
identity.session.invalid_params Invalid Email or Password
|
||||
identity.session.invalid Invalid Session
|
||||
identity.captcha.required captcha_response is required
|
||||
identity.captcha.mandatory_fields Mandatory fields must be filled in
|
||||
identity.session.deleted Your account is deleted
|
||||
identity.session.not_active Your account is not active
|
||||
identity.session.banned Your account is banned
|
||||
identity.session.invalid_params Invalid Email or Password
|
||||
identity.session.missing_otp The account has enabled 2FA but OTP code is missing
|
||||
identity.session.invalid_otp OTP code is invalid
|
||||
```
|
||||
|
||||
## Admin module errors
|
||||
|
||||
```
|
||||
admin.user.update_himself Admin can't update himself
|
||||
admin.user.enable_2fa Manual 2FA enabling not allowed
|
||||
admin.user.state_no_change Can't change state, as its already {active}
|
||||
admin.user.doesnt_exist User with such UID doesnt exist
|
||||
admin.label.doesnt_exist Label with such key doesnt exist or not assigned to chosen user
|
||||
admin.access.denied Access Denied: User is not Admin
|
||||
admin.user.non_user_field Search field is not a user attribute
|
||||
admin.user.no_matches Search result is empty array
|
||||
admin.user.label_no_matches Search result is empty array
|
||||
```
|
||||
|
||||
## General errors
|
||||
|
||||
```
|
||||
record.not_found Record is not found
|
||||
jwt.decode_and_verify Failed to decode and verify JWT
|
||||
authz.invalid_session Failed to decode cookies
|
||||
authz.user_not_active User is not active
|
||||
authz.invalid_signature API Key header 'signature' is invalid
|
||||
authz.apikey_not_active API Key state is 'inactive'
|
||||
authz.disabled_2fa API Key owner has disabled 2FA
|
||||
authz.invalid_api_key_headers Blank or missing API Key headers
|
||||
authz.permission_denied Path is blacklisted
|
||||
authz.unexistent_apikey X-Auth-Apikey header is invalid
|
||||
```
|
||||
|
||||
## Validation errors
|
||||
### Admin module
|
||||
|
||||
```
|
||||
admin.user.non_integer_page
|
||||
admin.user.non_positive_page
|
||||
admin.user.non_integer_limit
|
||||
admin.user.invalid_limit
|
||||
admin.user.missing_uid
|
||||
admin.user.empty_uid
|
||||
admin.user.empty_state
|
||||
admin.user.empty_otp
|
||||
admin.user.empty_role
|
||||
admin.user.one_of_state_otp
|
||||
admin.user.one_of_state_otp_email
|
||||
admin.user.missing_key
|
||||
admin.user.empty_key
|
||||
admin.user.missing_scope
|
||||
admin.user.empty_scope
|
||||
admin.user.missing_value
|
||||
admin.user.empty_value
|
||||
```
|
||||
|
||||
### Identity module
|
||||
|
||||
```
|
||||
identity.user.missing_email
|
||||
identity.user.empty_email
|
||||
identity.user.missing_password
|
||||
identity.user.empty_password
|
||||
identity.user.missing_token
|
||||
identity.user.empty_token
|
||||
identity.user.missing_reset_password_token
|
||||
identity.user.empty_reset_password_token
|
||||
identity.user.missing_confirm_password
|
||||
identity.user.empty_confirm_password
|
||||
|
||||
identity.session.missing_email
|
||||
identity.session.missing_password
|
||||
identity.session.invalid_captcha_format
|
||||
```
|
||||
|
||||
### Resource module
|
||||
|
||||
```
|
||||
resource.otp.missing_code
|
||||
resource.otp.empty_code
|
||||
|
||||
resource.labels.missing_key
|
||||
resource.labels.empty_key
|
||||
resource.labels.missing_value
|
||||
resource.labels.empty_value
|
||||
|
||||
resource.documents.expire_not_a_date
|
||||
resource.documents.invalid_format
|
||||
resource.documents.already_expired
|
||||
resource.documents.missing_doc_expire
|
||||
resource.documents.empty_doc_expire
|
||||
resource.documents.missing_doc_type
|
||||
resource.documents.empty_doc_type
|
||||
resource.documents.missing_doc_number
|
||||
resource.documents.empty_doc_number
|
||||
resource.documents.missing_upload
|
||||
|
||||
|
||||
resource.user.missing_topic
|
||||
resource.user.empty_topic
|
||||
resource.user.missing_old_password
|
||||
resource.user.empty_old_password
|
||||
resource.user.missing_new_password
|
||||
resource.user.empty_new_password
|
||||
resource.user.missing_confirm_password
|
||||
resource.user.empty_confirm_password
|
||||
|
||||
|
||||
resource.profile.missing_first_name
|
||||
resource.profile.missing_last_name
|
||||
resource.profile.missing_dob
|
||||
resource.profile.missing_address
|
||||
resource.profile.missing_postcode
|
||||
resource.profile.missing_city
|
||||
resource.profile.missing_country
|
||||
|
||||
|
||||
resource.api_key.missing_algorithm
|
||||
resource.api_key.empty_algorithm
|
||||
resource.api_key.empty_kid
|
||||
resource.api_key.empty_scope
|
||||
resource.api_key.missing_totp
|
||||
resource.api_key.empty_totp
|
||||
resource.api_key.missing_kid
|
||||
resource.api_key.empty_state
|
||||
|
||||
|
||||
|
||||
resource.phone.missing_phone_number
|
||||
resource.phone.empty_phone_number
|
||||
resource.phone.missing_verification_code
|
||||
resource.phone.empty_verification_code
|
||||
```
|
||||
593
docs/general/event_api.md
Normal file
@@ -0,0 +1,593 @@
|
||||
# RabbitMQ Barong Event API
|
||||
|
||||
## Overview of RabbitMQ details
|
||||
|
||||
Barong submits all events into three exchanges depending on event category (read next).
|
||||
|
||||
The exchange name consists of three parts:
|
||||
|
||||
1) application name (typically `barong`)
|
||||
|
||||
2) fixed keyword `events`.
|
||||
|
||||
3) category of event, like `system` (generic system event), `model` (the attributes of some record were updated)
|
||||
|
||||
The routing key looks like `user.password.reset.token`, `user.created`.
|
||||
The event name matches the routing key but with event category appended at the beginning, like `system.user.password.reset.token`, `market.user.created`.
|
||||
|
||||
## Overview of RabbitMQ message
|
||||
|
||||
Each produced message in `Event API` is JWT (complete format).
|
||||
|
||||
This is very similar to `Management API`.
|
||||
|
||||
The example below demonstrates both generation and verification of JWT:
|
||||
|
||||
```ruby
|
||||
require "jwt-multisig"
|
||||
require "securerandom"
|
||||
|
||||
jwt_payload = {
|
||||
iss: 'barong',
|
||||
jti: SecureRandom.uuid,
|
||||
iat: Time.now.to_i,
|
||||
exp: Time.now.to_i + 60,
|
||||
event: event_payload
|
||||
}
|
||||
|
||||
private_key = OpenSSL::PKey.read(Base64.urlsafe_decode64(private_key)
|
||||
algorithm = 'RS256'
|
||||
jwt = JWT::Multisig.generate_jwt jwt_payload, \
|
||||
{ barong: private_key },
|
||||
{ barong: algorithm }
|
||||
|
||||
Kernel.puts "GENERATED JWT", jwt.to_json, "\n"
|
||||
|
||||
verification_result = JWT::Multisig.verify_jwt jwt.deep_stringify_keys, \
|
||||
{ barong: public_key }, { verify_iss: true, iss: "barong", verify_jti: true }
|
||||
|
||||
decoded_jwt_payload = verification_result[:payload]
|
||||
|
||||
Kernel.puts "MATCH AFTER VERIFICATION: #{jwt_payload == decoded_jwt_payload}."
|
||||
```
|
||||
|
||||
The RabbitMQ message is stored in JWT field called `event`.
|
||||
|
||||
## Overview of Event API message
|
||||
|
||||
The typical event looks like (JSON):
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
foo: "ID30DD0DD986",
|
||||
bar: "example@barong.io",
|
||||
baz: "member",
|
||||
qux: 0
|
||||
},
|
||||
name: "model.user.created"
|
||||
}
|
||||
```
|
||||
|
||||
The field `event[:name]` contains event name (same as routing key).
|
||||
The fields `foo`, `bar`, `baz`, `qux` (example) are fields which carry useful information.
|
||||
|
||||
# Barong Event API messages
|
||||
|
||||
## Format of `model.user.created` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
uid: "ID30DD0DD986",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 0,
|
||||
otp: false,
|
||||
state: "pending",
|
||||
created_at: "2019-01-28T08:35:29Z",
|
||||
updated_at: "2019-01-28T08:35:29Z"
|
||||
},
|
||||
name: "model.user.created"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | ----------------------------------- |
|
||||
| `record` | Created user up-to-date attributes. |
|
||||
|
||||
## Format of `model.user.updated` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
uid: "ID30DD0DD986",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 1,
|
||||
otp: false,
|
||||
state: "pending",
|
||||
created_at: "2019-01-28T08:35:29Z",
|
||||
updated_at: "2019-01-28T08:35:29Z"
|
||||
},
|
||||
changes: {
|
||||
level: 0
|
||||
}
|
||||
name: "model.user.updated"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | ----------------------------------- |
|
||||
| `record` | Created user up-to-date attributes. |
|
||||
| `changes` | The changed user attributes and their values. |
|
||||
|
||||
|
||||
## Format of `model.user.created` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
address:"Illinois",
|
||||
city:"New Garfieldbury",
|
||||
country:"COD",
|
||||
dob:"1984-05-22",
|
||||
first_name:"Irina",
|
||||
last_name:"Heathcote",
|
||||
postcode:"10029",
|
||||
created_at:"2019-10-02T08:14:20Z",
|
||||
updated_at:"2019-10-02T08:14:20Z",
|
||||
user: {
|
||||
email: "clarisa_larkin@sawayn.info",
|
||||
level: 0,
|
||||
otp: false,
|
||||
referral_uid: nil,
|
||||
role: "member",
|
||||
state: "pending",
|
||||
uid: "IDEA819FB3F1",
|
||||
updated_at: "2019-10-02T08:14:20Z"
|
||||
created_at: "2019-10-02T08:14:20Z"
|
||||
}
|
||||
},
|
||||
name: "model.profile.created"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | -------------------------------------- |
|
||||
| `record` | Created profile up-to-date attributes. |
|
||||
|
||||
## Format of `model.user.updated` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
address:"Illinois",
|
||||
city:"New Garfieldbury",
|
||||
country:"COD",
|
||||
created_at:"2019-10-02T08:14:20Z",
|
||||
dob:"1984-05-22",
|
||||
first_name:"Irina",
|
||||
last_name:"Heathcote",
|
||||
postcode:"10029",
|
||||
updated_at:"2019-10-02T08:14:20Z",
|
||||
user: {
|
||||
email: "clarisa_larkin@sawayn.info",
|
||||
level: 0,
|
||||
otp: false,
|
||||
referral_uid: nil,
|
||||
role: "member",
|
||||
state: "pending",
|
||||
uid: "IDEA819FB3F1",
|
||||
updated_at: "2019-10-02T08:14:20Z"
|
||||
created_at: "2019-10-02T08:14:20Z"
|
||||
}
|
||||
},
|
||||
changes: {
|
||||
first_name: "Vernell"
|
||||
},
|
||||
name: "model.profile.updated"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | ----------------------------------- |
|
||||
| `record` | Profile up-to-date attributes. |
|
||||
| `changes` | The changed profile attributes and their values. |
|
||||
|
||||
## Format of `model.label.created` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
id: 1,
|
||||
key: "email",
|
||||
value: "verified",
|
||||
user: {
|
||||
uid: "ID30DD0DD986",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 2,
|
||||
otp: false,
|
||||
state: "active",
|
||||
created_at: "2019-01-28T08:35:29Z",
|
||||
updated_at: "2019-01-28T08:35:29Z"
|
||||
}
|
||||
},
|
||||
name: "model.label.created"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | ----------------------------------- |
|
||||
| `record` | Created label up-to-date attributes. |
|
||||
|
||||
## Format of `model.label.updated` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
id: 1,
|
||||
key: "new_key",
|
||||
value: "verified",
|
||||
user: {
|
||||
uid: "ID30DD0DD986",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 2,
|
||||
otp: false,
|
||||
state: "active",
|
||||
created_at: "2019-01-28T08:35:29Z",
|
||||
updated_at: "2019-01-28T08:35:29Z"
|
||||
}
|
||||
},
|
||||
changes: {
|
||||
key: "old_key"
|
||||
}
|
||||
name: "model.label.updated"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | ----------------------------------- |
|
||||
| `record` | Created label up-to-date attributes. |
|
||||
| `changes` | The changed label attributes and their values. |
|
||||
|
||||
## Format of `model.document.created` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
doc_type: 'Passport',
|
||||
doc_expire: '3020-01-22',
|
||||
doc_number: 'AA1234BB',
|
||||
upload: [],
|
||||
updated_at:"2019-01-28T08:35:29Z",
|
||||
created_at:"2019-01-28T08:35:29ZZ",
|
||||
user: {
|
||||
uid: "ID30DD0DD986",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 2,
|
||||
otp: false,
|
||||
state: "active",
|
||||
created_at: "2019-01-28T08:35:29Z",
|
||||
updated_at: "2019-01-28T08:35:29Z"
|
||||
}
|
||||
}
|
||||
name: "model.document.created"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ------------ | --------------------------------- |
|
||||
| `user` | The up-to-date user attributes. |
|
||||
| `doc_type` | Document type. |
|
||||
| `doc_expire` | Experation time for document. |
|
||||
| `doc_number` | Document number. |
|
||||
| `upload` | Array of updaded objects |
|
||||
| `updated_at` | Time of document object creation |
|
||||
| `created_at` | Time of last document update |
|
||||
|
||||
## Format of `system.user.email.confirmation.token` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
user: {
|
||||
uid: "ID739065AFD3",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 0,
|
||||
otp: false,
|
||||
state: "pending",
|
||||
created_at: "2019-01-28T09:03:50Z",
|
||||
updated_at: "2019-01-28T09:03:50Z"
|
||||
},
|
||||
language: "EN",
|
||||
domain: "www.barong.io",
|
||||
token: "eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1NDg2NjYyMzAsImV4cCI6MTU0ODY3MjIzMCwic3ViIjoiY29uZmlybWF0aW9uIiwiaXNzIjoiYmFyb25nIiwiYXVkIjpbInBlYXRpbyIsImJhcm9uZyJdLCJqdGkiOiI5OWJkNzFkMjU2NTdlMmI1YzI1MCIsImVtYWlsIjoiYWRtaW4xMjNAYmFyb25nLmlvIiwidWlkIjoiSUQ3MzkwNjVBRkQzIn0.OI5tL9kV6cA1JBAy7G5iqd3WplxcB-waHYKFjm83koMEpx2Hlw9fksq5lip5cIHTjR8i3ambFL40OaCwDNc1jAiDsHwuv2nLswgi88_M1G8KVFylboQdtgmH_cZiz-Y-51Fq2oqEID5QyJnsSMSJbfspb6A0JGT_V-SPK4WFZw43F_RKhlZBCrxojljMwd20rGqFPYirMgUpsfiW0_-mESXzQ7UK1eA8mYO7Id4y6JR2Yoo-JTloEnBL1M189tOz6LqmmQB0M_QjTiHG3y9I97Med3StgVziYo9qog9kJXyPuXbboddg__5WEhMcWbaToohoiT5UvpVJHKfgxEVaDg"
|
||||
},
|
||||
name: "system.user.email.confirmation.token"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | ------------------------------------------------ |
|
||||
| `user` | The up-to-date user attributes. |
|
||||
| `language` | The language. |
|
||||
| `domain` | The domain name of barong. |
|
||||
| `token` | Valid confirm-acc jwt token (mandatory param for user confirmation endpoint) `/identity/users/email/confirm_code`. |
|
||||
|
||||
## Format of `system.user.email.confirmed` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
user: {
|
||||
uid: "IDB1629BFE9E",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 0,
|
||||
otp: false,
|
||||
state: "active",
|
||||
created_at: "2019-01-28T10:17:27Z",
|
||||
updated_at: "2019-01-28T10:17:45Z"
|
||||
},
|
||||
language: "EN",
|
||||
domain: "www.barong.io"
|
||||
},
|
||||
name: "system.user.email.confirmed"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | -------------------------------- |
|
||||
| `user` | The up-to-date user attributes. |
|
||||
| `language` | The language. |
|
||||
| `domain` | The domain name of barong. |
|
||||
|
||||
## Format of `system.user.password.reset.token` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
user: {
|
||||
uid: "ID30DD0DD986",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 0,
|
||||
otp: false,
|
||||
state: "pending",
|
||||
created_at: "2019-01-28T08:35:29Z",
|
||||
updated_at: "2019-01-28T08:35:29Z"
|
||||
},
|
||||
language: "EN",
|
||||
domain: "www.barong.io",
|
||||
token: "eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1NDg2NjQ1OTUsImV4cCI6MTU0ODY3MDU5NSwic3ViIjoicmVzZXQiLCJpc3MiOiJiYXJvbmciLCJhdWQiOlsicGVhdGlvIiwiYmFyb25nIl0sImp0aSI6IjRhY2IzM2IzYmE2NDc0ZjY1YTI5IiwiZW1haWwiOiJhZG1pbjEyQGJhcm9uZy5pbyIsInVpZCI6IklEMzBERDBERDk4NiJ9.Rie4LCbkV0jVBbhMoceYx8a9uDA-ea9D1v790zlIqP_EY8Iue_OOKXYWiC1Y-55MPicFbknBILjZlPewvAF8ZrhqIt04ROsgBdDGEUGY_SnLWhXzqSx9-v_o_w2MVjLOUxvRBm6sD0RvL-_5LmOcLqhYtf7ZPUnPDwsvhDedqDfbXPEvI7OK2SZ-1uPAOg1IMOX1k7xaDt5I1Wp-Knr2DmEgwNYbIjaXraComYcMdtVSuYVJAufgA0kTADMeT3cV3jzGy9dNfs8heMCtf5tr72IbL0_N0VeUQj9uaPDUr4ntsYk7gOPmA3RSVrSismtYdBXA9oLA0b0YfOctiY9dqg"
|
||||
},
|
||||
name: "system.user.password.reset.token"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | ------------------------------------------------ |
|
||||
| `user` | The up-to-date user attributes. |
|
||||
| `language` | The language. |
|
||||
| `domain` | The domain name of barong. |
|
||||
| `token` | Valid reset-pass jwt token (mandatory param for password reset endpoint) `/identity/users/password/confirm_code`. |
|
||||
|
||||
## Format of `system.user.account.deleted` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
user: {
|
||||
uid: "IDB1629BFE9E",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 1,
|
||||
otp: false,
|
||||
state: "deleted",
|
||||
created_at: "2019-01-28T10:17:27Z",
|
||||
updated_at: "2019-01-28T10:17:45Z",
|
||||
}
|
||||
},
|
||||
name: "system.user.account.deleted"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | ------------------------------------------------ |
|
||||
| `user` | The up-to-date user attributes. |
|
||||
|
||||
## Format of `system.user.password.reset` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
user: {
|
||||
uid: "ID30DD0DD986",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 0,
|
||||
otp: false,
|
||||
state: "pending",
|
||||
created_at: "2019-01-28T08:35:29Z",
|
||||
updated_at: "2019-01-28T09:42:36Z"
|
||||
}
|
||||
},
|
||||
name: "system.user.password.reset"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | ------------------------------------------------ |
|
||||
| `user` | The up-to-date user attributes. |
|
||||
|
||||
## Format of `system.user.password.change` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
user: {
|
||||
uid: "IDC554ED1D0F",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 0,
|
||||
otp: false,
|
||||
state: "active",
|
||||
created_at: "2019-01-09T15:54:56Z",
|
||||
updated_at: "2019-01-28T09:59:03Z"
|
||||
}
|
||||
},
|
||||
name: "system.user.password.change"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| --------- | ------------------------------------------------- |
|
||||
| `user` | The up-to-date user attributes. |
|
||||
|
||||
## Format of `system.document.verified` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
user: {
|
||||
uid: "IDC554ED1D0F",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 0,
|
||||
otp: false,
|
||||
state: "active",
|
||||
created_at: "2019-01-09T15:54:56Z",
|
||||
updated_at: "2019-01-28T09:59:03Z"
|
||||
},
|
||||
id: 1,
|
||||
key: "something",
|
||||
value: "verified"
|
||||
},
|
||||
name: "system.document.verified"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| --------- | ------------------------------------------------- |
|
||||
| `user` | The up-to-date user attributes. |
|
||||
|
||||
## Format of `system.document.rejected` event
|
||||
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
user: {
|
||||
uid: "IDC554ED1D0F",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 0,
|
||||
otp: false,
|
||||
state: "active",
|
||||
created_at: "2019-01-09T15:54:56Z",
|
||||
updated_at: "2019-01-28T09:59:03Z"
|
||||
},
|
||||
id: 1,
|
||||
key: "something",
|
||||
value: "rejected"
|
||||
},
|
||||
name: "system.document.rejected"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
| --------- | ------------------------------------------------- |
|
||||
| `user` | The up-to-date user attributes. |
|
||||
|
||||
## Format of `system.session.create` event
|
||||
```ruby
|
||||
event: {
|
||||
record: {
|
||||
user: {
|
||||
uid: "ID30DD0DD986",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 0,
|
||||
otp: false,
|
||||
state: "pending",
|
||||
created_at: "2019-01-28T08:35:29Z",
|
||||
updated_at: "2019-01-28T08:35:29Z"
|
||||
},
|
||||
user_ip: "127.0.0.1",
|
||||
user_agent: "Chrome"
|
||||
},
|
||||
name: "system.session.create"
|
||||
}
|
||||
```
|
||||
|
||||
## Producing events using Ruby
|
||||
|
||||
```ruby
|
||||
require "bunny"
|
||||
|
||||
def generate_jwt(jwt_payload)
|
||||
Kernel.abort "Please, see «Overview of RabbitMQ message» for implementation guide."
|
||||
end
|
||||
|
||||
Bunny.run host: "localhost", port: 5672, username: "guest", password: "guest" do |session|
|
||||
channel = session.channel
|
||||
exchange = channel.direct("barong.events.model")
|
||||
jwt_payload = {
|
||||
iss: "barong",
|
||||
jti: SecureRandom.uuid,
|
||||
iat: Time.now.to_i,
|
||||
exp: Time.now.to_i + 60,
|
||||
event: {
|
||||
record: {
|
||||
uid: "ID30DD0DD986",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 0,
|
||||
otp: false,
|
||||
state: "pending",
|
||||
created_at: "2019-01-28T08:35:29Z",
|
||||
updated_at: "2019-01-28T08:35:29Z"
|
||||
},
|
||||
name: "model.user.created"
|
||||
}
|
||||
}
|
||||
exchange.publish(generate_jwt(jwt_payload), routing_key: "user.created")
|
||||
end
|
||||
```
|
||||
|
||||
IMPORTANT: Don't forget to implement the logic for JWT exception handling!
|
||||
|
||||
## Producing events using `rabbitmqadmin`
|
||||
|
||||
`rabbitmqadmin publish routing_key=user.created payload=JWT exchange=barong.events.model`
|
||||
|
||||
Don't forget to pass environment variable `JWT`.
|
||||
|
||||
## Consuming events using Ruby
|
||||
|
||||
```ruby
|
||||
require "bunny"
|
||||
|
||||
def verify_jwt(jwt_payload)
|
||||
Kernel.abort "Please, see «Overview of RabbitMQ message» for implementation guide."
|
||||
end
|
||||
|
||||
Bunny.run host: "localhost", port: 5672, username: "guest", password: "guest" do |session|
|
||||
channel = session.channel
|
||||
exchange = channel.direct("barong.events.model")
|
||||
queue = channel.queue("", auto_delete: true, durable: true, exclusive: true)
|
||||
.bind(exchange, routing_key: "user.created")
|
||||
queue.subscribe manual_ack: true, block: true do |delivery_info, metadata, payload|
|
||||
Kernel.puts verify_jwt(JSON.parse(payload)).fetch(:event)
|
||||
channel.ack(delivery_info.delivery_tag)
|
||||
rescue => e
|
||||
channel.nack(delivery_info.delivery_tag, false, true)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
IMPORTANT: Don't forget to implement the logic for JWT exception handling!
|
||||
71
docs/general/password_hashing.md
Normal file
@@ -0,0 +1,71 @@
|
||||
## Barong password hashing ##
|
||||
|
||||
### Overview ###
|
||||
|
||||
Barong since 2.0 version use OpenBSD bcrypt() password hashing algorithm, that allow us easily store a secure hash of users' passwords.
|
||||
|
||||
As a base Barong takes [bcrypt-ruby gem](https://github.com/codahale/bcrypt-ruby) - Ruby binding for the OpenBSD bcrypt()
|
||||
With [rails 5 has_secure_password](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html) it gives us full power of algorithm
|
||||
|
||||
### How it works ###
|
||||
|
||||
Hash algorithms take a chunk of data (e.g., user's password) and create a "digital fingerprint," or hash, of it.
|
||||
Because this process is not reversible, there's no way to go from the hash back to the password.
|
||||
|
||||
In other words:
|
||||
|
||||
hash(p) #=> <unique gibberish>
|
||||
|
||||
We store the hash and check it against a hash made of a potentially valid password:
|
||||
|
||||
<unique gibberish> =? hash(just_entered_password)
|
||||
|
||||
### Rainbow Tables
|
||||
|
||||
But even this has weaknesses -- attackers can just run lists of possible passwords through the same algorithm, store the
|
||||
results in a big database, and then look up the passwords by their hash:
|
||||
|
||||
PrecomputedPassword.find_by_hash(<unique gibberish>).password #=> "secret1"
|
||||
|
||||
Our solution to this is to add a small chunk of random data -- called a salt -- to the password before it's hashed:
|
||||
|
||||
hash(salt + p) #=> <really unique gibberish>
|
||||
|
||||
The salt is then stored along with the hash in the database, and used to check potentially valid passwords:
|
||||
|
||||
<really unique gibberish> =? hash(salt + just_entered_password)
|
||||
|
||||
bcrypt-ruby automatically handles the storage and generation of these salts for you.
|
||||
|
||||
Adding a salt means that an attacker has to have a gigantic database for each unique salt -- for a salt made of 4
|
||||
letters, that's 456,976 different databases. Pretty much no one has that much storage space, so attackers try a
|
||||
different, slower method -- throw a list of potential passwords at each individual password:
|
||||
|
||||
hash(salt + "aadvark") =? <really unique gibberish>
|
||||
hash(salt + "abacus") =? <really unique gibberish>
|
||||
etc.
|
||||
|
||||
This is much slower than the big database approach, but most hash algorithms are pretty quick -- and therein lies the
|
||||
problem. Hash algorithms aren't usually designed to be slow, they're designed to turn gigabytes of data into secure
|
||||
fingerprints as quickly as possible. `bcrypt()`, though, is designed to be computationally expensive:
|
||||
|
||||
Ten thousand iterations:
|
||||
user system total real
|
||||
md5 0.070000 0.000000 0.070000 ( 0.070415)
|
||||
bcrypt 22.230000 0.080000 22.310000 ( 22.493822)
|
||||
|
||||
If an attacker was using Ruby to check each password, they could check ~140,000 passwords a second with MD5 but only
|
||||
~450 passwords a second with `bcrypt()`.
|
||||
|
||||
## More Information
|
||||
|
||||
`bcrypt()` is currently used as the default password storage hash in OpenBSD, widely regarded as the most secure operating
|
||||
system available.
|
||||
|
||||
For a more technical explanation of the algorithm and its design criteria, please read Niels Provos and David Mazières'
|
||||
Usenix99 paper:
|
||||
https://www.usenix.org/events/usenix99/provos.html
|
||||
|
||||
If you'd like more down-to-earth advice regarding cryptography, I suggest reading <i>Practical Cryptography</i> by Niels
|
||||
Ferguson and Bruce Schneier:
|
||||
https://www.schneier.com/book-practical.html
|
||||
45
docs/general/profiles.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Barong
|
||||
|
||||
## Profiles story and administration
|
||||
|
||||
This document explain original profiles submit-n-verify process and possible customizations.
|
||||
|
||||
## Version
|
||||
|
||||
Story described in the document actual for latest 2.5 stable version and higher.
|
||||
|
||||
## User side of the story
|
||||
|
||||
`Comment`: Previously (in 2.3 and lower) user was able to submit only 1 profile, and all later modifications affect it. Starting from 2.4 we changed `user has_one profile` relation to `user has many profiles`. This was done first of all to be able to track history of modifications and to be able to control changes from admin panel. Meanwhile, it also brought additional manual verification step in the legacy KYC process.
|
||||
|
||||
`Story`:
|
||||
User can submit profile with following fields (all are optional by default): (via `POST /resource/profiles`)
|
||||
|
||||
```
|
||||
t.string "first_name"
|
||||
t.string "last_name"
|
||||
t.date "dob"
|
||||
t.string "address"
|
||||
t.string "postcode"
|
||||
t.string "city"
|
||||
t.string "country"
|
||||
t.text "metadata"
|
||||
```
|
||||
|
||||
Profile creates with `drafted` state in database. At this point user can edit the information (via `PUT /resource/profiles`), and administrators will not review it yet.
|
||||
Once all the information is edited and validated by user correctly, he can submit profile for verification (via `PUT /resource/profiles`) by passing `confirmation: true` in the params. Profile state changes to "submitted" in database and from now on this profile is pending for admin verification.
|
||||
|
||||
Meanwhile, there is a possibility to skip this "edit" step and create a profile directly with `submitted` state. For this user need to pass `confirmation: true` parameter directly in `POST /resource/profiles`.
|
||||
|
||||
After admin will verify the profile and mark it as `"verified"` or `"rejected"` user will be able to create a new profile with `drafted/submitted` state, if he need it. Flow mostly controls by a `server-side rule`: user can have `ANY` amount of profiles, but `ONLY ONE` of `drafted/submitted` at a time.
|
||||
|
||||
## Admin side of the story
|
||||
|
||||
Once user sumbit a profile (with state submitted) admin can verify or reject it, by changing a profile state and creating a correct label. Usually its `key: profile, value: verified/rejected'.
|
||||
|
||||
Also administrator has an access to the full profiles history, so he can check and compare new changes with old profiles, if the exist. As well he has an information about previous decisions about profile verification per each request.
|
||||
|
||||
Once profile is rejected or verified, admin can create new profile for user (via `POST admin/profiles`).
|
||||
In this case, profile will have a 'submitted' state and 'author' field with admin UID in DB.
|
||||
|
||||
`!!!Attention` By default, if admin creates a profile for user, the same admin account cant approve or reject this profile, he need to wait for second admin approval. However, this can be changed by env `BARONG_PROFILE_DOUBLE_VERIFICATION` which can receive 2 value: `true` for enabling and `false` for disabling the feature
|
||||
BIN
docs/images/amqp-mailer-schema.jpg
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
docs/images/api-keys-1.jpeg
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
docs/images/api-keys-2.jpeg
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
docs/images/auth0_dashboard.png
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
docs/images/auth0_pkce.png
Normal file
|
After Width: | Height: | Size: 223 KiB |
BIN
docs/images/auth0_settings.png
Normal file
|
After Width: | Height: | Size: 206 KiB |
BIN
docs/images/mailer-retry.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
47
docs/kycaid.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Barong KYCAID configuration
|
||||
In Barong 2.5 and higher you can use the external KyC provider (KYCAID)[https://www.kycaid.com/] to fully automated your KYC process.
|
||||
|
||||
### Basic configuration
|
||||
Barong now support 2 ways of managing KYC - `local` and `kycaid`. You can switch between them using `BARONG_KYC_PROVIDER` env. By default this ENV has `kycaid`, as a value. If you set `local`as a value, then legacy flow will be turned on. `Profile` and `Document` steps will require manual admin approve from tower.
|
||||
|
||||
### Credentials configuration
|
||||
Once every credential is setted up correctly `KYCAID` will work in Barong out of the box. Lets see what we need to set up to make it work properly:
|
||||
|
||||
1) We need to set up a bucket for storing docs (docs submitted by user will be stored both in barong and on KYCAID side)
|
||||
Basic creds needed for that should be set in envs: `barong_storage_provider`, `barong_storage_bucket_name`, `barong_storage_access_key`, `barong_storage_secret_key`.
|
||||
More about available options read here: [Barong storage configuration](https://www.openware.com/sdk/docs/barong/configuration.html#storage-configuration)
|
||||
2) We need to set up authorization creds for KYCAID (get one on official site https://www.kycaid.com/). ENVs for that available under namings:
|
||||
`barong_kycaid_authorization_token` - for auth secret token,
|
||||
`barong_kycaid_sandbox_mode` - for switching between test mode and prod mode (`true` by default)
|
||||
3) Be sure to check if `barong_domain` ENV has a correct value including `https:` at the beginning. This ENV configures the `callback` url, so its improtant.
|
||||
4) Be sure to check `BARONG_REQUIRED_DOCS_EXPIRE` ENV value to be `false` if you want to include `address` verification in your KYC process. You can set it to `true` if only document check needed.
|
||||
5) Check if in the `authz_rules.yml` file you have permitted path `- api/v2/barong/public` in the `pass` module. This allows platform to receive `callback`, as it is in the public module
|
||||
6) Check if in the `barong.yml` file you have correct list of `document_types`. Be sure, that you have at least this values inside:
|
||||
- Passport
|
||||
- Identity card
|
||||
- Driver license
|
||||
- Address
|
||||
|
||||
### Sidekiq
|
||||
Dont forget to check if your deployment / local installation has running sidekiq. As soon as all the jobs are running a-sync, we use sidekiq to interact with `KYCAID` in order to make user verification fast and clear from user point of view.
|
||||
|
||||
Sidekiq runs with a command `bundle exec sidekiq` with the same image and ENVs as barong.
|
||||
|
||||
### Verification flow explanation
|
||||
First 2 common steps of KYC remains unchanged. We still use internal email verification and phone verification using Twilio.
|
||||
#### Profile step
|
||||
After user has submitted profile - we send a request to KYCAID, registering this user in KYCAID database and creating a n `applicant` record for him. At this step no additional checks provided by KYCAID team.
|
||||
|
||||
#### Document step
|
||||
User can submit docs (2 or 3), depending on the type he choose. It can be `passport`, it can be `driver license`, etc.
|
||||
User need to provide photo of `first page` of document, `second page` if needed and `SELFIE`.
|
||||
After user has submitted all the docs, we send them to the `bucket`, configured by platform (to save them internally and show on `tower`) and also send files to `KYCAID`, downloading them to `KYCAID database`.
|
||||
|
||||
After that Barong triggers `verification request` with 2 types - `DOCUMENT` check and `FACIAL` check. From this moment verifications and checks are performing on `KYCAID` side (check their site and contact support to find out more about `algorithms` here https://www.kycaid.com/). KYCAID team sends back a `callback` with decision.
|
||||
In our system, both `FACIAL` and `DOCUMENT` resolutes to one label, with key = `document`, so if one of those verifications fails - end user will get `reject` on his verification `attempt`.
|
||||
If verification decision is `approve` user will automatically get updated label to `verified` and corresponding level.
|
||||
|
||||
#### Address step
|
||||
Address step implemented pretty the same, as previous, document one. User sumbits document, that proves his residence.
|
||||
After user has submitted all the docs, we send them to the `bucket`, configured by platform (to save them internally and show on `tower`) and also send files to `KYCAID`, downloading them to `KYCAID database`.
|
||||
After that Barong triggers `verification request` with only 1 type - `ADDRESS`. After all verification process on the `KYCAID` side `BARONG` receives callback with decision. If its positive - user get his level and `address`:`verified` label.
|
||||
239
docs/mailer.md
Normal file
@@ -0,0 +1,239 @@
|
||||
# Barong mailer
|
||||
|
||||
Mailer in the barong app is a deamon listening events from RabbitMQ, it renders emails using templates in the language set in user profile (if possible) and send emails.
|
||||
|
||||
This guide explains the basics of using mailer to manage events from rubykube Event API.
|
||||
|
||||
It is usually used by following components:
|
||||
|
||||
- [Barong](https://www.openware.com/sdk/docs.html#barong)
|
||||
- [Peatio](https://www.openware.com/sdk/docs.html#peatio)
|
||||
|
||||
Read more about [Peatio Event API](https://www.openware.com/sdk/docs/peatio/api/event-api.html).
|
||||
Read more about [Barong Event API](https://www.openware.com/sdk/docs/barong/event-api.html).
|
||||
|
||||
## Concepts
|
||||
|
||||
An _Event_ is a message produced to message broker in [RFC7515](https://tools.ietf.org/html/rfc7515).
|
||||
|
||||
Events have the following structure:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"payload": "string",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"kid":"string"
|
||||
},
|
||||
"protected":"string",
|
||||
"signature":"string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Deep dive
|
||||
|
||||
By specification defined in _RFC7515_ we can build a JSON Web Token.
|
||||
|
||||
After parsing of prebuilt JWT, you will receive this payload with this structure.
|
||||
|
||||
```JSON
|
||||
{
|
||||
"iss": "string",
|
||||
"jti": "string",
|
||||
"iat": 1567777420,
|
||||
"exp": 1567777480,
|
||||
"event": {
|
||||
"record": {
|
||||
"user": {
|
||||
"uid": "string",
|
||||
"email": "string",
|
||||
},
|
||||
"language": "string",
|
||||
},
|
||||
"name": "string"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** All events should be properly signed using RS256 private key.
|
||||
|
||||
Mailer validates the signature of each upcoming event.
|
||||
|
||||
Further, we will see that mailer user can work with this payload directly.
|
||||
|
||||
```JSON
|
||||
{
|
||||
"record": {
|
||||
"user": {
|
||||
"uid": "UID12345678",
|
||||
"email": "johndoe@example.com"
|
||||
},
|
||||
"language": "EN"
|
||||
},
|
||||
"changes": {},
|
||||
"name": "string"
|
||||
}
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
| Variable | Description | Required | Default |
|
||||
| ------------------------------------ | ------------------------------ | -------- | ------------------- |
|
||||
| `BARONG_EVENT_API_RABBITMQ_HOST` | Host of RabbitMQ daemon | _no_ | `localhost` |
|
||||
| `BARONG_EVENT_API_RABBITMQ_PORT` | Port of RabbitMQ daemon | _no_ | `5672` |
|
||||
| `BARONG_EVENT_API_RABBITMQ_USERNAME` | RabbitMQ username | _no_ | `guest` |
|
||||
| `BARONG_EVENT_API_RABBITMQ_PASSWORD` | RabbitMQ password | _no_ | `guest` |
|
||||
| `BARONG_SMTP_PASSWORD` | Password used for auth to SMTP | _yes_ | |
|
||||
| `BARONG_SMTP_PORT` | Post of SMTP server | _no_ | `25` |
|
||||
| `BARONG_SMTP_HOST` | Host of SMTP server | _no_ | `smtp.sendgrid.net` |
|
||||
| `BARONG_SMTP_USER` | User used for auth to SMTP | _no_ | `apikey` |
|
||||
| `BARONG_SENDER_EMAIL` | Email address of mail sender | _yes_ | |
|
||||
| `BARONG_SENDER_NAME` | Name of mail sender | _no_ | `Barong` |
|
||||
|
||||
```sh
|
||||
./bin/mailer --config=config/mailer.yml run
|
||||
```
|
||||
|
||||
Mailer creates one queue and bind pre-defined exchanges to it.
|
||||
|
||||
## Configuration
|
||||
|
||||
Mailer is a flexible tool, you can cusomize alomost everything. Biggest part of customizations defined in `mailer.yml`, but you can also modify templates.
|
||||
|
||||
Each Event API provider uses own AMQP exchange and algorithm to sign payload.
|
||||
|
||||
```yaml
|
||||
exchanges:
|
||||
barong:
|
||||
name: barong.events.system
|
||||
signer: peatio
|
||||
```
|
||||
|
||||
Using keychain algorithms and defined public keys for each provider mailer will validate the data.
|
||||
|
||||
```yaml
|
||||
keychain:
|
||||
barong:
|
||||
algorithm: RS256
|
||||
value: "public_key"
|
||||
```
|
||||
|
||||
In `events` you may define any event type from Event API providers and prepare email template for it.
|
||||
|
||||
```yaml
|
||||
events:
|
||||
- name: Email Confirmation
|
||||
key: user.email.confirmation.token
|
||||
exchange: barong
|
||||
templates:
|
||||
EN:
|
||||
subject: Registration Confirmation
|
||||
template_path: email_confirmation.en.html.erb
|
||||
RU:
|
||||
subject: Подтверждение Регистрации
|
||||
template_path: email_confirmation.ru.html.erb
|
||||
```
|
||||
|
||||
The simpliest mailer configuration will look like this one:
|
||||
|
||||
```yaml
|
||||
keychain:
|
||||
barong:
|
||||
algorithm: RS256
|
||||
value: "changeme"
|
||||
peatio:
|
||||
algorithm: RS256
|
||||
value: "changeme"
|
||||
|
||||
exchanges:
|
||||
barong:
|
||||
name: barong.events.system
|
||||
signer: barong
|
||||
|
||||
events:
|
||||
- name: Email Confirmation
|
||||
key: user.email.confirmation.token
|
||||
exchange: barong_system
|
||||
templates:
|
||||
en:
|
||||
subject: Registration Confirmation
|
||||
template_path: email_confirmation.en.html.erb
|
||||
ru:
|
||||
subject: Подтверждение Регистрации
|
||||
template_path: email_confirmation.ru.html.erb
|
||||
```
|
||||
|
||||
## Templates
|
||||
|
||||
Mailer exposes few variables for usage inside the templates.
|
||||
|
||||
| Variable | Description |
|
||||
| ---------- | -------------------------------------------- |
|
||||
| `@user` | User related to this email |
|
||||
| `@record` | Created user up-to-date attributes. |
|
||||
| `@changes` | The changed user attributes and their values |
|
||||
|
||||
### User
|
||||
|
||||
User with related profile.
|
||||
|
||||
| Variable | |
|
||||
| ----------- | ----------------------------- |
|
||||
| uid | Unique user id |
|
||||
| email | User email |
|
||||
| role | User role |
|
||||
| level | User KYC level |
|
||||
| state | State of user's account |
|
||||
| referral_id | UID of referrer |
|
||||
| profile | Information about KYC profile |
|
||||
|
||||
### Record
|
||||
|
||||
Record always containes `UID` and other attributes, that's why we can also expose user, by searching with unique user id.
|
||||
|
||||
Example:
|
||||
|
||||
```ruby
|
||||
record: {
|
||||
uid: "ID30DD0DD986",
|
||||
email: "example@barong.io",
|
||||
role: "member",
|
||||
level: 1,
|
||||
otp: false,
|
||||
state: "pending",
|
||||
created_at: "2019-01-28T08:35:29Z",
|
||||
updated_at: "2019-01-28T08:35:29Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Changes
|
||||
|
||||
When entity changed, this will contain attributes before an udpate.
|
||||
|
||||
Example:
|
||||
|
||||
```ruby
|
||||
changes: {
|
||||
level: 0
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Queues and exchanges schema
|
||||

|
||||
### How retries works
|
||||
|
||||
RabbitMQ Cluster is part of our infrastructure and the default queuing solution. RabbitMQ has Dead Letter Exchanges (DLX), which allows us to simulate message scheduling.
|
||||
|
||||
#### Steps to test the solution:
|
||||
1. Publish message to TargetQueue
|
||||
2. Consumer gets the message and tries to process it
|
||||
3. Process fails, consumer rejects the message
|
||||
4. Rabbit routes the message to RetryExchange
|
||||
5. Message moves to RetryQueue, sits for 2 minutes
|
||||
6. When message expires, it is resent to TargetExchange and routed to TargetQueue
|
||||
|
||||

|
||||
64
docs/migrations/2_6_migration.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# 2.6 Migration procedure
|
||||
|
||||
## Introduction
|
||||
2.6 version brings some important security improvments by allowing a better isolation of secrets in Vault.
|
||||
API keys secrets where moved from Vault kv secret engine to transit engine. API keys secrets are encrypted/decrypted by Vault and stored encrypted in the main database, reducing the size of vault storage.
|
||||
|
||||
## Setting a unique an meaningful application name
|
||||
The application name is used as prefix of secrets stored in vault, it allows you to configure proper isolation using vault policies, see [Vault](https://www.openware.com/sdk/docs/barong/vault.html) documentation for more details about ACL configuration.
|
||||
|
||||
The configuration entry for the application name is `barong_vault_app_name` (or the environment variable BARONG_VAULT_APP_NAME), see [Barong Configuration](https://www.openware.com/sdk/docs/barong/configuration.html) for more details.
|
||||
|
||||
## Vault token for the migration
|
||||
To export and import the TOTP you need to use the vault root token or a token with the following policies.
|
||||
Replace *opendax* with your vault application name.
|
||||
|
||||
```
|
||||
# Read api keys
|
||||
path "secret/barong/api_key/*" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
# Manage the transit secrets engine
|
||||
path "transit/keys/*" {
|
||||
capabilities = [ "create", "read", "list" ]
|
||||
}
|
||||
|
||||
# Encrypt engines secrets
|
||||
path "transit/encrypt/opendax_apikeys_*" {
|
||||
capabilities = [ "create", "read", "update" ]
|
||||
}
|
||||
|
||||
# Decrypt engines secrets
|
||||
path "transit/decrypt/opendax_apikeys_*" {
|
||||
capabilities = [ "create", "read", "update" ]
|
||||
}
|
||||
|
||||
# Export otp
|
||||
path "totp/export/*" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
# Create otp code
|
||||
path "totp/keys/*" {
|
||||
capabilities = ["create", "read", "delete"]
|
||||
}
|
||||
```
|
||||
|
||||
## Migrate the API keys
|
||||
This will fetch the API keys from Vault kv secrets store engine, encrypt them with transit, store the encrypted version in the database and finally delete the legacy version stored in vault.
|
||||
|
||||
```
|
||||
rake migrate:26-api-keys
|
||||
```
|
||||
|
||||
## Migrate the TOTP secrets
|
||||
TOTP secrets can't be exported by the official Vault build.
|
||||
To do so you must use the openware patched version available in the docker container *quay.io/openware/vault:1.5.3-openware*
|
||||
|
||||
|
||||
Then run the following command
|
||||
|
||||
```
|
||||
rake migrate:26-totp
|
||||
```
|
||||
9
docs/migrations/postgresql.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Use PostgreSQL with Barong
|
||||
|
||||
Barong supports PostgreSQL 13.0 and higher.
|
||||
To use PostgreSQL you need to set the following environment variables:
|
||||
|
||||
```bash
|
||||
export DATABASE_ADAPTER="postgresql"
|
||||
export DATABASE_PORT="5432"
|
||||
```
|
||||
85
docs/releases/2.1.0.md
Normal file
@@ -0,0 +1,85 @@
|
||||
## Barong 2.1.0 (April 22, 2019) ##
|
||||
|
||||
### Overview ###
|
||||
|
||||
Release includes significant new features, numerous functional fixes and stabilizing patches.
|
||||
Barong 2.2.0 comes without views, controllers, huge dependencies, but with clean, fast and readable API.
|
||||
Release is optimized, more compact and elegant version of OAuth server concept.
|
||||
Since we've removed dependencies like `devise` a lot of the flow was not only recoded but implemented in fully new way.
|
||||
|
||||
This release notes is must-read for migrating from 2.0 version.
|
||||
|
||||
### Release is NOT compatible with 1.9 or older versions of barong ###
|
||||
|
||||
### New features ###
|
||||
|
||||
* [#655](https://github.com/rubykube/barong/pull/655): Reworked (complaining to 1.9) seed feature. Supports seeding levels, users with optional parameters and labels
|
||||
|
||||
* [#679](https://github.com/rubykube/barong/pull/679): Adds an ability to upload N number of documents. Maximum number can be configured by ENV
|
||||
|
||||
* [#665](https://github.com/rubykube/barong/pull/665): Support of GeeTest captcha and captcha configuration
|
||||
|
||||
* [#681](https://github.com/rubykube/barong/pull/681): Move all admin functionality to API
|
||||
|
||||
* [#686](https://github.com/rubykube/barong/pull/686): New authorize endpoint (White- and Black- listing features, Rails Metal based (optimized), api keys and cookies logic)
|
||||
|
||||
* [#716](https://github.com/rubykube/barong/pull/716): Ability to specify and control CORS policy
|
||||
|
||||
* [#726](https://github.com/rubykube/barong/pull/726): Support asian language characters, rework validations
|
||||
|
||||
* [#734](https://github.com/rubykube/barong/pull/734): Add tokens blacklisting feature. Additional checks to avoid reusing tokens
|
||||
|
||||
* [741](https://github.com/rubykube/barong/pull/741): Unify errors format to prepare base for translations
|
||||
|
||||
|
||||
### Enhancements ###
|
||||
|
||||
* [#677](https://github.com/rubykube/barong/pull/677): Improve activities coverage
|
||||
* [#688](https://github.com/rubykube/barong/pull/688): Add change password endpoint
|
||||
* [#693](https://github.com/rubykube/barong/pull/693): Change multiple docs uploading logic from object to array to become compatible with browser files transfering policy
|
||||
* [#697](https://github.com/rubykube/barong/pull/697): Add label on profile adding without level increase to strictly
|
||||
* [#709](https://github.com/rubykube/barong/pull/709): Add referral_id to users table and as an optional param on signup
|
||||
* [#707](https://github.com/rubykube/barong/pull/707): Update to ruby 2.6.0
|
||||
* [#745](https://github.com/rubykube/barong/pull/745): Add event API documentation with examples
|
||||
* [#767](https://github.com/rubykube/barong/pull/767): Add language field in reset pass and confirm acc events
|
||||
* [#763](https://github.com/rubykube/barong/pull/763): User controller improvements
|
||||
** Fixed inconsistent indentation in user controller
|
||||
** Rework POST '/get' request to allow to receive email and phone num
|
||||
** Added several additional tests
|
||||
* [#771](https://github.com/rubykube/barong/pull/771): Add pagination on /resource/users/activity endpoint
|
||||
* [#769](https://github.com/rubykube/barong/pull/769): Search on user fields, admin API
|
||||
* [#785](https://github.com/rubykube/barong/pull/786): Add Entities::Activity model, include it Entities::UserWithFullInfo
|
||||
* [#789](https://github.com/rubykube/barong/pull/789): Use 'paginate' on api/v2/admin/users/search
|
||||
* [#804](https://github.com/rubykube/barong/pull/804): DESC order in user activity API
|
||||
* [#807](https://github.com/rubykube/barong/pull/807): Allow to list API Keys without providing OTP code
|
||||
* [#809](https://github.com/rubykube/barong/pull/809): Update rails-related gems versions in favor of vulnerability alerts
|
||||
|
||||
### Fixes ###
|
||||
* [#658](https://github.com/rubykube/barong/pull/658): Fix share cookies for development, fix Bump
|
||||
* [#664](https://github.com/rubykube/barong/pull/664): Fix user activity api endpoint bug https://github.com/rubykube/barong/issues/663
|
||||
* [#674](https://github.com/rubykube/barong/pull/674): Added missing validations on password update functionality
|
||||
* [#675](https://github.com/rubykube/barong/pull/675): Fix unhandled totp errors
|
||||
* [#683](https://github.com/rubykube/barong/pull/683): Hotfix for whitelisting public peatio and barong routes
|
||||
* [#684](https://github.com/rubykube/barong/pull/684): Add missing link_config script(required for deployment process)
|
||||
* [#685](https://github.com/rubykube/barong/pull/685): Update the production database configuration with DATABASE_NAME from env
|
||||
* [#694](https://github.com/rubykube/barong/pull/694): Add missing event with confirmation token on signup
|
||||
* [#699](https://github.com/rubykube/barong/pull/699): Add carrierwave config for production
|
||||
* [#702](https://github.com/rubykube/barong/pull/702): Small fixes (drone ci, event api updated_at bug)
|
||||
* [#706](https://github.com/rubykube/barong/pull/706): Add missing users entity on login and /me
|
||||
* [#718](https://github.com/rubykube/barong/pull/718): Move ActionDispatch::Session::CookieStore to sessions controller
|
||||
* [#720](https://github.com/rubykube/barong/pull/720): Add ability to configure expire_after time through env variable, fix hardcoded one
|
||||
* [#724](https://github.com/rubykube/barong/pull/724): Fix change password api action from post to put
|
||||
* [#713](https://github.com/rubykube/barong/pull/713): Split swagger doc into restful and management)
|
||||
* [#737](https://github.com/rubykube/barong/pull/737): Add storage envs in config store and update fetch logic
|
||||
* [#730](https://github.com/rubykube/barong/pull/730): Fix change code on phone initialize, remove code from logs
|
||||
* [#739](https://github.com/rubykube/barong/pull/739): Fix Barong::CORS load problem in production env
|
||||
* [#742](https://github.com/rubykube/barong/pull/742): Add missing user details in 2fa login response
|
||||
* [#749](https://github.com/rubykube/barong/pull/749): Fix session_id check & add bypass session lazy load
|
||||
* [#753](https://github.com/rubykube/barong/pull/753): Change default set-cookie header policy on authz to :skip
|
||||
* [#757](https://github.com/rubykube/barong/pull/757): Take only data from Vault::Secret object && minor refactoring
|
||||
* [#747](https://github.com/rubykube/barong/pull/747): Phone API improvements (additional error)
|
||||
* [#760](https://github.com/rubykube/barong/pull/760): Add additional error on login in case of banned user
|
||||
* [#768](https://github.com/rubykube/barong/pull/768): Add more API Key validations, fix error on creating with invalid algo
|
||||
* [#772](https://github.com/rubykube/barong/pull/772): Split activity no records error to wrong_topic and no_activity
|
||||
* [#776](https://github.com/rubykube/barong/pull/776): Use destroy instead of delete to enable missing validations
|
||||
* [#805](https://github.com/rubykube/barong/pull/805): Move event api jwt private key to Barong::App.config store
|
||||
114
docs/releases/2.3.0.md
Normal file
@@ -0,0 +1,114 @@
|
||||
## Barong 2.3.0 ##
|
||||
|
||||
### Overview ###
|
||||
|
||||
We are pleased to present Barong Open Source 2.3.0.
|
||||
|
||||
This release concentrated on improving overall project flexibility, security and session updates and several new storage/phone providers and updates
|
||||
|
||||
1. Server side sessions via rails cache
|
||||
2. Restrictions and related Admin API
|
||||
3. Support Twilio Verify service (without dropping legacy sms solution)
|
||||
4. Flexible state - labels flow
|
||||
5. Support Ali Cloud storage provider and S3 custom storages
|
||||
|
||||
This release notes is must-read for migrating from older versions.
|
||||
|
||||
### New Features ###
|
||||
- Add ability to configure sms content for phone verification [#877](https://github.com/rubykube/barong/pull/877) ([ec](https://github.com/ec))
|
||||
- This PR introduce an ability to configurate (via ENV) before deployment the future Twilio sms content:
|
||||
- "Your verification code for Barong: {{code}}"" - default one
|
||||
- You can change position of verification code, words and content in template
|
||||
- e.q. "Hoooray! Here is magic {{code}} for you to verify your account!""
|
||||
|
||||
- Simple rake task to create users and api keys [#816](https://github.com/rubykube/barong/pull/816) ([ec](https://github.com/ec))
|
||||
- [ATTENTION] The best usage for the rake task - testing purpose
|
||||
- You can generate up to N (1000 by default) users with valid api keys to simulate any platform actions
|
||||
- Add Resctrictions [#891](https://github.com/rubykube/barong/pull/891) ([dnfd](https://github.com/dnfd))
|
||||
- AuthZ level validations to ban traffic on a network base.
|
||||
- Available types of validations: IP IP_SUBNET CONTINENT COUNTRY
|
||||
- After being created restriction can be toggled to be turned ON or OF via admin api
|
||||
- Full support of CRUD functionality in the admin module
|
||||
- Feature Ability to change UID prefix with BARONG_UID_PREFIX=ABC [#893](https://github.com/rubykube/barong/pull/893) ([ec](https://github.com/ec))
|
||||
- This PR introduce an ability to configurate (via ENV) before deployment the future user UIDs:
|
||||
- ID{RANDOM_HASH} - default
|
||||
- MYAWESOMEAPP{RANDOM_HASH} - available to configurate
|
||||
- Add Management API: push document for user [#894](https://github.com/rubykube/barong/pull/894) ([ec](https://github.com/ec))
|
||||
- New management API call that gives an ability to push documents for the user in base64
|
||||
- Good base for any third-party KYC providers
|
||||
- Add endpoint for delete restriction [#902](https://github.com/rubykube/barong/pull/902) ([chumaknadya](https://github.com/chumaknadya))
|
||||
- Admin endpoint to delete Restriction (remove from DB, cant be rolled back)
|
||||
- Add state to Profile model [#910](https://github.com/rubykube/barong/pull/910) ([mnaichuk](https://github.com/mnaichuk))
|
||||
- Define 2 Profile states: partial and completed
|
||||
- Allow to create EMPTY profile (with empty fields)
|
||||
- Profile state - attributes dependency
|
||||
- Ability to update and delete users profiles [#913](https://github.com/rubykube/barong/pull/913) ([ec](https://github.com/ec))
|
||||
- New admin and user API endpoints that allows to update / delete profiles
|
||||
- Flexible state - labels flow [#907](https://github.com/rubykube/barong/pull/907) ([ec](https://github.com/ec))
|
||||
- State - Label dependency
|
||||
- Similar to levels configuration now you can configurate requirements for each of the user states
|
||||
- Separately - ACTIVE requirements
|
||||
- Now on every label change (update, remove, delete) user state recalculates and forces to update
|
||||
- Default values remains the same as in the <= 2.2 version
|
||||
- Add AliCloud Carrierwave storage provider [#911](https://github.com/rubykube/barong/pull/911) ([dnfd](https://github.com/dnfd))
|
||||
- Now Barong support Ali Cloud storages and easily deploys on AliBaba cloud
|
||||
- Add ability to restrict by geoip [#920](https://github.com/rubykube/barong/pull/920) ([dnfd](https://github.com/dnfd))
|
||||
- Add support of CONTINENT and COUNTRY restriction scopes
|
||||
- Add ability to skip label creation on doc save [#922](https://github.com/rubykube/barong/pull/922) ([dnfd](https://github.com/dnfd))
|
||||
- Add ability to disable 2fa [#925](https://github.com/rubykube/barong/pull/925) ([dnfd](https://github.com/dnfd))
|
||||
- Add AliCloud Uploader [#926](https://github.com/rubykube/barong/pull/926) ([dnfd](https://github.com/dnfd))
|
||||
- Now Barong support Ali Cloud storages and easily deploys on AliBaba cloud
|
||||
- Define DocumentTypes class for flexible doc type configuration [#935](https://github.com/rubykube/barong/pull/935) ([ec](https://github.com/ec))
|
||||
- This PR introduce an ability to predefine available document types before deployment. There is hardcoded freezed array anymore.
|
||||
- By default, abailable document type list remains the same as <= 2.2 versions
|
||||
- Make labels acts_as_eventable on: [create update] [#936](https://github.com/rubykube/barong/pull/936) ([ec](https://github.com/ec))
|
||||
- Spread events on label CUD
|
||||
- Add the support of twilio verify API [#928](https://github.com/rubykube/barong/pull/928) ([ec](https://github.com/ec))
|
||||
- Now Barong supports twilio verification service ( via CALL and SMS )
|
||||
- Should be switched from SMS to Twilio Verify via ENV before deployment
|
||||
- Server side sessions via cache_store [#949](https://github.com/rubykube/barong/pull/949) ([ec](https://github.com/ec))
|
||||
- Now session stores on the server side in the cache
|
||||
- User receives only 1 session cookie, that proves he got it from Barong
|
||||
- Session lifetime extends after every private call
|
||||
- Session will automatically close if user will try to reuse cookies in another browser or IP network
|
||||
- Session will expire in 24h
|
||||
|
||||
### Enhancements ###
|
||||
- Updating gem multisign and jwt [45f975](https://github.com/rubykube/barong/commit/45f975fcb489aaa3b0b4f56b1307258b8bc85d18) ([mod](https://github.com/mod))
|
||||
- Allow pending user to open session [#881](https://github.com/rubykube/barong/pull/881) ([ec](https://github.com/ec))
|
||||
- Update to ruby 2.6.3 and rails 5.2.3 [#867](https://github.com/rubykube/barong/pull/867) ([ec](https://github.com/ec))
|
||||
- Update models' annotations [#895](https://github.com/rubykube/barong/pull/895) ([dnfd](https://github.com/dnfd))
|
||||
- Small fixes in document and profile model [#901](https://github.com/rubykube/barong/pull/901) ([ec](https://github.com/ec))
|
||||
- Feature: Add redeploy on devkube step to drone [#874](https://github.com/rubykube/barong/pull/874) ([alinetskyi](https://github.com/alinetskyi))
|
||||
- Add validation for referral && Add ability to get referral uid [#882](https://github.com/rubykube/barong/pull/882) ([chumaknadya](https://github.com/chumaknadya))
|
||||
- Update nokogiri version [#906](https://github.com/rubykube/barong/pull/906) ([dnfd](https://github.com/dnfd))
|
||||
- Update Barong::App validations [#904](https://github.com/rubykube/barong/pull/904) ([dnfd](https://github.com/dnfd))
|
||||
- Support 'with replace' policy on labels update [#915](https://github.com/rubykube/barong/pull/915) ([ec](https://github.com/ec))
|
||||
- UPDATES: sessions delete, permissions update, log error on 500 [#917](https://github.com/rubykube/barong/pull/917) ([chumaknadya](https://github.com/chumaknadya))
|
||||
- Add :upload in list of params to be filtered [#919](https://github.com/rubykube/barong/pull/919) ([ec](https://github.com/ec))
|
||||
- Fix structure of event API messages [#912](https://github.com/rubykube/barong/pull/912) ([shal](https://github.com/shal))
|
||||
- Use Barong::App.config.barong_uid_prefix in referral validation [#923](https://github.com/rubykube/barong/pull/923) ([ec](https://github.com/ec))
|
||||
- Allow blank doc_expire for documents controllers [#927](https://github.com/rubykube/barong/pull/927) ([dnfd](https://github.com/dnfd))
|
||||
- Add system.session.create event with user and request_ip data [#916](https://github.com/rubykube/barong/pull/916) ([chumaknadya](https://github.com/chumaknadya))
|
||||
- Update seeds.yml [#934](https://github.com/rubykube/barong/pull/934) ([ec](https://github.com/ec))
|
||||
- Simple GET levels requirements endpoint for admin [#932](https://github.com/rubykube/barong/pull/932) ([ec](https://github.com/ec))
|
||||
- Get rid of 'serialize: JSON', accept 'metadata' as json instead of pure hash [#930](https://github.com/rubykube/barong/pull/930) ([ec](https://github.com/ec))
|
||||
- Add missing labels event api documentation [#937](https://github.com/rubykube/barong/pull/937) ([ec](https://github.com/ec))
|
||||
- Add session autorenew [#903](https://github.com/rubykube/barong/pull/903) ([dnfd](https://github.com/dnfd))
|
||||
- Introduce MockPhoneVerifyService [#941](https://github.com/rubykube/barong/pull/941) ([ec](https://github.com/ec))
|
||||
- Use uid instead of id on profile update && delete api [#943](https://github.com/rubykube/barong/pull/943) ([ec](https://github.com/ec))
|
||||
- Profile act as eventable on update [#945](https://github.com/rubykube/barong/pull/945) ([ec](https://github.com/ec))
|
||||
- Update ruby to 2.6.5 for security reasons [#946](https://github.com/rubykube/barong/pull/946) ([ec](https://github.com/ec))
|
||||
- Add ability to configure aws_signature_version && endpoint [#947](https://github.com/rubykube/barong/pull/947) ([ec](https://github.com/ec))
|
||||
- Feature: allow # \ () & ' : " in profile residental address field [#950](https://github.com/rubykube/barong/pull/950) ([ymasiuk](https://github.com/ymasiuk))
|
||||
- Add redis - hiredis dependency, specify driver in dev env [#951](https://github.com/rubykube/barong/pull/951) ([ec](https://github.com/ec))
|
||||
- Protect superadmin against changes from non-superadmin users [#955](https://github.com/rubykube/barong/pull/955) ([ec](https://github.com/ec))
|
||||
- Update storage-related gems [#957](https://github.com/rubykube/barong/pull/957) ([ec](https://github.com/ec))
|
||||
|
||||
### Bug Fixes ###
|
||||
- Use CGI::escape instead of pure url in documents event api [#942](https://github.com/rubykube/barong/pull/942) ([ec](https://github.com/ec))
|
||||
- fix binstubs issue [#867](https://github.com/rubykube/barong/pull/867) ([ec](https://github.com/ec))
|
||||
- Fix rollback to pending state, add missing data in entities [#914](https://github.com/rubykube/barong/pull/914) ([ec](https://github.com/ec))
|
||||
- Handle Vault errors on POST /api/v2/resource/api_keys [#918](https://github.com/rubykube/barong/pull/918) ([dnfd](https://github.com/dnfd))
|
||||
- Avoid no method error UTC for nil entities [#921](https://github.com/rubykube/barong/pull/921) ([ec](https://github.com/ec))
|
||||
- Event API changes: remove blocking check for on_update events [#933](https://github.com/rubykube/barong/pull/933) ([ec](https://github.com/ec))
|
||||
51
docs/restrictions.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Restrictions
|
||||
|
||||
### Introduction
|
||||
First version of restrictions appeared in 2.3 as simple blacklist feature, by IP in several scopes (by `country`, by `continent`, by `ip_subnet` and by `ip`).
|
||||
|
||||
Starting from latest 2.4 restrictions will act as system of traffic control. New fields added to restrictions table - `category`, `code`, and new available value for `scope` - `all`
|
||||
|
||||
##### Main points:
|
||||
Every request to the server will be validated (both `public` and `private` APIs, but not `management` one ). Request IP will match with existing restrictions and a first found rule will be applayed.
|
||||
`category` - one of `whitelist`, `maintenance`, `blacklist`, `blocklogin`.
|
||||
|
||||
The order of matching IP with existing rules is strict and cant be changed:
|
||||
1. Whitelist ( all -> ip -> ip_subnet -> country -> continent )
|
||||
2. Maintenance ( all -> ip -> ip_subnet -> country -> continent )
|
||||
3. Blacklist ( all -> ip -> ip_subnet -> country -> continent )
|
||||
4. Blocklogin ( all -> ip -> ip_subnet -> country -> continent )
|
||||
|
||||
`Whitelist` - rule, that marks IP as trusted, as IP that can have an access to the server APIs
|
||||
`Maintenance` - when enabled, will return an error - 471 (by default) to any request to server in a range of rules `scope` (Typically, should be used with `all` and in maintenance platform purposes)
|
||||
`Blacklist` - when enabled, will return an error - `code`, which can be customized by the rule. Code can be different for different `scopes`, and can be used to display different error or kind alert of UI. Default `code` for errors `{ continent: 423, country: 423, ip_subnet: 403, ip: 401, all: 401 }`
|
||||
`Blocklogin` - acts as `Blacklist`, but applies only on `sessions` endpoint.
|
||||
|
||||
##### How to configure
|
||||
Restrictions can be:
|
||||
1. Seeded via seed feature.
|
||||
Just put restrictions in format of `- { category: whitelist, scope: country, value: UA, state: disabled }` in seed.yml under `restrictions:` module
|
||||
2. Can be added by admin via `api/v2/barong/admin/restrictions`,
|
||||
requires `:scope`, requires `:value`, requires `:category`, optional `:state, default: 'enabled`', optional `:code `
|
||||
3. Can be added automatically (whitelist category) via whitelink feature
|
||||
|
||||
### Whitelink feature
|
||||
In order to make the process of whitelisting IPs easier starting from latest 2.4 admin can create a `whitelink_token` via
|
||||
`api/v2/barong/admin/restrictions/whitelink`. Created token can be sent to `api/v2/barong/identity/users/access` and if it is valid (every token has expiry time, which is 1 day by default) and it will automatically create a `whitelist` restriction with current request IP.
|
||||
Note: `api/v2/barong/identity/users/access` API available to call even if all other platform traffic is under blacklist or maintenance
|
||||
|
||||
### Restrictions Usage
|
||||
Combining whitelist, maintenance and blacklist rules can help in controlling platform traffic, maintaining platform, developing custom cases and complex UI structure.
|
||||
##### Several usecases:
|
||||
##### Maintenance - rules:
|
||||
`category: 'maintenance', scope: 'all', value: 'all', state: 'enabled', code: 471`
|
||||
`category: 'whitelist', scope: 'ip_subnet', value: '#{dev_team_office_ip}', state: 'enabled'`
|
||||
|
||||
In this case all users, that will try to access any API of the platform will get a responce with status `471` and body `authz.restrict.maintenance`. In this case frontend can show a maintenance page for users, so they will understand that platform is under service right now. Meanwhile, all requests from `#{dev_team_office_ip}` (as they are whitelisted) will still reach server and can test the update / validate any bug found, etc.
|
||||
|
||||
##### Blacklisting - rules:
|
||||
`category: 'blacklist', scope: 'country', value: 'US', state: 'enabled', code: 455`
|
||||
`category: 'blacklist', scope: 'continent', value: 'NA', state: 'enabled', code: 456`
|
||||
`category: 'whitelist', scope: 'ip', value: '#{investor_ip}', state: 'enabled'`
|
||||
|
||||
In this case all users from North America, that will try to access any API of the platform will get a responce with status `456` and body `authz.restrict.blacklist`. In this case frontend can show a page for users, so they will understand that they cant yet reach this platform from their current location, but it will come soon. All users from USA will have a different code - `455`, so UI can show the page, which will indicates, that platform is banned for USA residents and cant be reached from this country.
|
||||
Meanwhile, in testing and business purpose you can whitelist one concrete or subset of IPs, for you investors, for lawyers or any demo, using `whitelist` rule.
|
||||
32
docs/roadmap.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Barong
|
||||
|
||||
## v2.4
|
||||
|
||||
* Integration of Postmaster for translated emails
|
||||
* CSRF security support
|
||||
* Improve KYC Profile flow
|
||||
* Password strenght indicator with API
|
||||
* Unification of configuration and documentation
|
||||
* Public configuration endpoint to fetch non-sentive config from frontend
|
||||
* Refactor recaptcha with geetest integration
|
||||
|
||||
## v2.5
|
||||
|
||||
* Support of KyC provider (KyCAID)[https://kycaid.com/]
|
||||
* Admin comments on users
|
||||
* Double verification for user profile edit
|
||||
|
||||
## v2.6
|
||||
|
||||
* Vault prefix and policies
|
||||
* Configurable abilities
|
||||
|
||||
## v2.7
|
||||
|
||||
* Fast barong authorizer
|
||||
* Dynamic routing from database
|
||||
* Configuration storage in vault
|
||||
|
||||
## v3.0
|
||||
|
||||
* OAuth Sign-up and Login support
|
||||
55
docs/security.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Barong Security Hardening
|
||||
This document describes the available security options implemented in the application and advices for configuring with highlighting the main (high-risk) security options
|
||||
|
||||
### Password hashing
|
||||
Barong since 2.0 version use OpenBSD bcrypt() password hashing algorithm, that allow us easily store a secure hash of users' passwords.
|
||||
|
||||
As a base Barong takes [bcrypt-ruby gem](https://github.com/codahale/bcrypt-ruby) - Ruby binding for the OpenBSD bcrypt() With [rails 5 has_secure_password](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html) it gives us full power of algorithm.
|
||||
|
||||
Read more about [password hashing algorithm in barong](https://www.openware.com/sdk/docs/barong/general/password-hashing.html).
|
||||
|
||||
Read more about additional [password strength and regexp configuration](https://www.openware.com/sdk/docs/barong/configuration.html#password-configuration).
|
||||
|
||||
### Challenge–response test (captcha protection)
|
||||
|
||||
In order to prevent script attacks on API and possible brute force on session- and user- related endpoints we implement captcha protection.
|
||||
|
||||
Configuration manages through environment variable - BARONG_CAPTCHA. Available values - geetest, recaptcha, none. With a wrong value barong will fail on start with error: `#{KEY}` invalid, enabled values: `NONE GEETEST RECAPTCHA`.
|
||||
|
||||
!!NOTE: `NONE` is a default value, but its highly not recommended to use in `production` environment.
|
||||
|
||||
List of endpoints protected can be configured in `barong.yml` file, common (and the most secure) list of endpoints is:
|
||||
```
|
||||
captcha_protected_endpoints:
|
||||
- user_create
|
||||
- session_create
|
||||
- password_reset
|
||||
- email_confirmation
|
||||
```
|
||||
|
||||
Captcha will be verified on `SERVER` side. All requests without captcha will be denied with `error` `captcha_response.missing`
|
||||
|
||||
More about captcha you can read here [captcha policy documentation](https://www.openware.com/sdk/docs/barong/general/captcha.html).
|
||||
|
||||
### CSRF protection
|
||||
`Cross-Site Request Forgery` (`CSRF`) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data since the attacker has no way to see the response to the forged request.
|
||||
`CSRF` has become a huge deal in the recent years and it’s a part of `OWASP` top 10 common vulnerabilities
|
||||
|
||||
There are some common practices to protect your website.
|
||||
|
||||
First of all only `POST, PUT, PATCH, DELETE` and `TRACE` HTML requests have to be protected, since only these methods are destructive and can cause any unwanted or unauthorized damage.
|
||||
Therefore, every time we sent such a request we need to append a specific token to it, to verify that request is sent from a legit HTML form. The token has to be included in `X-CSRF-Token` (commonly used one).
|
||||
|
||||
This is the flow we went for:
|
||||
1. On session creation backend sends a unique crypto-function generated token
|
||||
2. Frontend stores that token in the DOM, typically it’s in the meta tag.
|
||||
3. Every time a destructive request is sent to the backend, this token is appended in the header
|
||||
4. Backend validates the header and performs the action. Error is returned if the header is invalid.
|
||||
5. When the session is destroyed, the token is also destroyed and can’t be used again.
|
||||
|
||||
This approach is called a per-session token method.
|
||||
|
||||
For further information check the links down below:
|
||||
* https://www.owasp.org/index.php/Main_Page
|
||||
* https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#javascript-guidance-for-auto-inclusion-of-csrf-tokens-as-an-ajax-request-header
|
||||
* https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project
|
||||
13
docs/service_accounts.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Service Accounts
|
||||
In Barong a service account belongs to a user.
|
||||
|
||||
Service accounts are currently created only via Management API (server to server API).
|
||||
There is no possibility to login into service account, it's used through API using an API Key.
|
||||
|
||||
User has an ability to list his service accounts. Also User can create, update, delete and list API Keys for these service accounts using his own OTP.
|
||||
|
||||
A user service account has the same level as the user, the role can be different.
|
||||
|
||||
If User disable OTP, all API Keys for his service accounts will become inactive.
|
||||
|
||||
If a user state changes, his service accounts state will change accordingly.
|
||||
23
docs/tasks/import.md
Normal file
@@ -0,0 +1,23 @@
|
||||
## How to import users and referrals to Barong database
|
||||
|
||||
1. Create `csv` file for users and referrals with template.
|
||||
|
||||
### Users table
|
||||
|
||||
| uid | email | level | role | state | referral_uid |
|
||||
|---------------|-----------------|-------|--------------|---------|---------------|
|
||||
| ID1000003837 | admin@barong.io | 3 | superadmin | active | ID1000003828 |
|
||||
|
||||
uid, email - require params
|
||||
|
||||
2. For import users
|
||||
|
||||
```ruby
|
||||
bundle exec rake import:users['file_name.csv']
|
||||
```
|
||||
|
||||
3. For import referrals
|
||||
|
||||
```ruby
|
||||
bundle exec rake import:referrals['file_name.csv']
|
||||
```
|
||||
24
docs/troubleshooting.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Troubleshooting
|
||||
## Permissions
|
||||
- `401 authz.invalid_permission` on specific endpoint
|
||||
1. Check list of your permissions on barong seeds.yml or tower admin panel
|
||||
2. If there are no such permission just add new permission on tower admin panel
|
||||
|
||||
- `401 authz.invalid_permission` after login
|
||||
1. Check your permissions on barong rails console
|
||||
```ruby
|
||||
irb(main)013:0> Permission.all
|
||||
irb(main)013:0> Rails.cache.read('permissions')
|
||||
```
|
||||
2. If there are no permissions on rails cache or these permissions are wrong you need to run following command
|
||||
When you delete permissions from rails cache they will be automatically fetched
|
||||
```ruby
|
||||
irb(main)013:0> Rails.cache.delete('permissions')
|
||||
```
|
||||
3. If there are no permissions on DB you need to seed permissions
|
||||
```
|
||||
bundle exec rake db:seed
|
||||
```
|
||||
***
|
||||
## Restictions
|
||||
*Be careful with testing restriction and don't ban your local IP!*
|
||||
135
docs/vault.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# Vault configuration
|
||||
|
||||
## Introduction
|
||||
|
||||
This document describes how to create vault tokens in order to restrict components access to vault as following
|
||||
|
||||
| Component | Abilities |
|
||||
| ------------ | ------------------------------------------------------- |
|
||||
| barong-rails | encrypt api keys<br />create TOTP<br />verify TOTP code |
|
||||
| barong-authz | decrypt api keys |
|
||||
|
||||
|
||||
|
||||
## Connect to vault
|
||||
The the following variables in your environment with correct values:
|
||||
|
||||
```bash
|
||||
export VAULT_ADDR='http://127.0.0.1:8200'
|
||||
export VAULT_TOKEN='s.ozytsgX1BcTQaR5Y07SAd2VE'
|
||||
```
|
||||
|
||||
You can test that it works running the following command:
|
||||
|
||||
```
|
||||
$ vault status
|
||||
Type: shamir
|
||||
Sealed: false
|
||||
Key Shares: 1
|
||||
Key Threshold: 1
|
||||
Unseal Progress: 0
|
||||
Unseal Nonce:
|
||||
Version: 1.3.4
|
||||
Cluster Name: vault-cluster-650930cf
|
||||
Cluster ID: 9f40327d-ec71-9655-b728-7588ce47d0b4
|
||||
|
||||
High-Availability Enabled: false
|
||||
```
|
||||
|
||||
## Create ACL groups
|
||||
|
||||
### Create the following policy files
|
||||
|
||||
**barong-rails.hcl**
|
||||
|
||||
Replace *opendax* with your vault application name. See [barong vault configuration](https://www.openware.com/sdk/docs/barong/configuration.html#vault-configuration) for more details.
|
||||
|
||||
```bash
|
||||
# Access system health status
|
||||
path "sys/health" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
|
||||
# Manage the transit secrets engine
|
||||
path "transit/keys/*" {
|
||||
capabilities = [ "create", "read", "list" ]
|
||||
}
|
||||
|
||||
# Encrypt engines secrets
|
||||
path "transit/encrypt/opendax_apikeys_*" {
|
||||
capabilities = [ "create", "read", "update" ]
|
||||
}
|
||||
|
||||
# Renew tokens
|
||||
path "auth/token/renew" {
|
||||
capabilities = [ "update" ]
|
||||
}
|
||||
|
||||
# Lookup tokens
|
||||
path "auth/token/lookup" {
|
||||
capabilities = [ "update" ]
|
||||
}
|
||||
|
||||
# Manage otp keys
|
||||
path "totp/keys/opendax_*" {
|
||||
capabilities = ["create", "read", "update", "delete"]
|
||||
}
|
||||
|
||||
# Verify an otp code
|
||||
path "totp/code/opendax_*" {
|
||||
capabilities = ["update"]
|
||||
}
|
||||
```
|
||||
|
||||
**barong-authz.hcl**
|
||||
|
||||
```bash
|
||||
# Access system health status
|
||||
path "sys/health" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
|
||||
# Manage the transit secrets engine
|
||||
path "transit/keys/*" {
|
||||
capabilities = [ "create", "read", "list" ]
|
||||
}
|
||||
|
||||
# Decrypt engines secrets
|
||||
path "transit/decrypt/opendax_apikeys_*" {
|
||||
capabilities = [ "create", "read", "update" ]
|
||||
}
|
||||
|
||||
# Renew tokens
|
||||
path "auth/token/renew" {
|
||||
capabilities = [ "update" ]
|
||||
}
|
||||
|
||||
# Lookup tokens
|
||||
path "auth/token/lookup" {
|
||||
capabilities = [ "update" ]
|
||||
}
|
||||
```
|
||||
|
||||
### Create the ACL groups in vault
|
||||
|
||||
```bash
|
||||
vault policy write barong-rails barong-rails.hcl
|
||||
vault policy write barong-authz barong-authz.hcl
|
||||
```
|
||||
|
||||
### Create applications tokens
|
||||
|
||||
```bash
|
||||
vault token create -policy=barong-rails -period=240h
|
||||
vault token create -policy=barong-authz -period=240h
|
||||
```
|
||||
|
||||
## Configure Barong
|
||||
|
||||
Set those variables according to your deployment:
|
||||
|
||||
```bash
|
||||
export BARONG_VAULT_ADDRESS=http://127.0.0.1:8200
|
||||
export BARONG_VAULT_TOKEN=s.jyH1vmrOmkZ0FZZ0NZtgRenS
|
||||
export BARONG_VAULT_APP_NAME=opendax
|
||||
```
|
||||
104
docs/zagros/2fa/2fa.md
Normal file
@@ -0,0 +1,104 @@
|
||||
#Registration: 2FA
|
||||
###### Sprint: 2
|
||||
|
||||
### Outcome:
|
||||
2 factor authentication is a feature that helps users to secure their activities.
|
||||
For critical activities the app needs a code to be completed.
|
||||
At first vault creates a code (that showed with QR) to sync with google authenticator.
|
||||
After adding code in the user's google authenticator, every time a user needs OTP(one-time-password) can read it in his app.
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
GET {$domain}/api/v2/barong/resource/otp/generate_qrcode
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/otp/enable
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/otp/enable_2fa
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/otp/disable
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/otp/disable_email
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/resource/otp.rb
|
||||
|
||||
#### Commits:
|
||||
bd7f980596
|
||||
dc95b308a6
|
||||
b3b5a08d60
|
||||
3c170120c1
|
||||
a79e06a71b
|
||||
8c821f1ba4
|
||||
e04a58b012
|
||||
99c2552404
|
||||
63f69ed0d6
|
||||
7010449976
|
||||
4d55a48572
|
||||
2da71b1097
|
||||
|
||||
#### What did we implement:
|
||||
|
||||
We add an authorization step to enable/disable 2FA. After entering the google authenticator code, an authorization email is sent to the user containing an OTP . Users only can enable or disable 2FA after entering the correct OTP from the email.
|
||||
|
||||
New flow:
|
||||
|
||||
System generates the code → User scan it with mobile → enters the google code → Receives the email →The user enters the code → 2FA enable/disable
|
||||
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: 2fa activation
|
||||
User->>Ranj: generate Qr Code
|
||||
Ranj-->>Dalan: get /generate_qrcode
|
||||
Dalan->>Ranj: 400, message: '2FA has been enabled for this account'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 400, message: '2FA has been already sent email for this account(enabling process started)'
|
||||
Dalan->>Ranj: 200, QR params
|
||||
Ranj->>User: QR
|
||||
User->>Ranj: User scan and enter code
|
||||
Ranj-->>Dalan: post /enable params:{code:string}
|
||||
Dalan->>Ranj: 400, message: '2FA has been enabled for this account or code is missing'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'OTP code is invalid'
|
||||
Dalan->>Ranj: 422, message: '2FA has been already sent email for this account(enabling process started)'
|
||||
Ranj->>User: show result
|
||||
Dalan->>User: send email in case of success
|
||||
User->>Ranj: enter authorization code
|
||||
Ranj-->>Dalan: post '/enable_2fa' params:{code:string}
|
||||
Dalan->>Ranj: 400, message: '2FA has been enabled for this account or code is missing
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 400. message: '2FA has been already enabled for this account'
|
||||
Dalan->>Ranj: 400, message: '2FA hasnt been enable'(didnt start enabling process)
|
||||
Dalan->>Ranj: 422, message: 'OTP code is invalid'
|
||||
Dalan->>Ranj: 200
|
||||
Ranj->>User: success
|
||||
```
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: 2fa deactivation
|
||||
User->>Ranj: enter google authentication code
|
||||
Ranj-->>Dalan: post /disable params:{code:string}
|
||||
Dalan->>Ranj: 400, message: '2FA has not been enabled for this account or code is missing'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'OTP code is invalid'
|
||||
Dalan->>Ranj: 422, message: '2FA has been already sent email for this account(disabling process started)'
|
||||
Ranj->>User: show result
|
||||
Dalan->>User: send email in case of success
|
||||
User->>Ranj: enter authorization code
|
||||
Ranj-->>Dalan: post '/disable_email' params:{code:string}
|
||||
Dalan->>Ranj: 400, message: '2FA has not been enabled for this account or code is missing
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 400. message: '2FA has been already disabled for this account'
|
||||
Dalan->>Ranj: 400, message: '2FA has been already sent email for this account'(didnt start enabling process)
|
||||
Dalan->>Ranj: 422, message: 'OTP code is invalid'
|
||||
Dalan->>Ranj: 200
|
||||
Ranj->>User: success
|
||||
```
|
||||
|
||||
|
||||
BIN
docs/zagros/Dalan-document.pdf
Normal file
95
docs/zagros/KYC-steps/level-one/access-mobile.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# KYC: Access mobile
|
||||
|
||||
###### Sprint: 3
|
||||
|
||||
### Outcome:
|
||||
|
||||
User should enter his number, after the validation app sends a sms with an otp code, the user must enter the code to prove to us that he has access to the entered number.
|
||||
|
||||
|
||||
#### Endpoints:
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/mobiles
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/mobiles/send_code
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/mobiles/verify
|
||||
|
||||
#### File destination:
|
||||
|
||||
{$Dalan_Path}/app/api/v2/resource/phones.rb
|
||||
|
||||
#### Commits:
|
||||
|
||||
bd7f980596
|
||||
695b0b56e2
|
||||
6dd40a9c42
|
||||
e04a58b012
|
||||
36167eda10
|
||||
2089690fe0
|
||||
90cbc48649
|
||||
17a5bce849
|
||||
63722fe22a
|
||||
63977c330d
|
||||
bff2746686
|
||||
75490dcb22
|
||||
f13ee3f4d5
|
||||
2c05522f77
|
||||
46c053b435
|
||||
551e7cdba2
|
||||
77d7b9a9b3
|
||||
2da71b1097
|
||||
|
||||
#### What did we implement:
|
||||
|
||||
First of all we added a new service for our sms&call third party service(kavenegar).it needs its own initializer for private keys.in this service we also handle caching data(for storing keys and codes with expiration time) and creating OTP code by vault.
|
||||
|
||||
We created a new api for phones with our rules.
|
||||
after verification every number, app create a new label(access_phone) if there were not that label.
|
||||
note:
|
||||
|
||||
if user wants to enter new number:
|
||||
|
||||
1.if user has pending number --> legacy number will be update with new number
|
||||
|
||||
2.If user has verified access label --> new number must get access label to create in db and legacy one replaced
|
||||
|
||||
3.If user has verified ownership label --> new number must get both labels to create in db and legacy one replaced
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: access phone
|
||||
User->>Ranj: enter phone number with +98
|
||||
Ranj-->>Dalan: post /mobiles params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'code_doesnt_expired'(there is an active process for addding new mobile)
|
||||
Dalan->>Ranj: 200, message: 'New phone was added'
|
||||
note left of Dalan: if there is a pending number it will be replaced with new one
|
||||
Dalan->>KaveNegar: send sms to User in case of success
|
||||
KaveNegar->>User: SMS with code
|
||||
Ranj->>User: show result
|
||||
note right of User: if didnt catch sms
|
||||
|
||||
User->>Ranj: resend code
|
||||
Ranj->>Dalan: Post mobiles/send_code params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found', 'phone.doesnt_exist'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'code_doesnt_expired' (expiration time doesnt finish)
|
||||
Dalan->>KaveNegar: send sms to User in case of success
|
||||
KaveNegar->>User: SMS with code
|
||||
Ranj->>User: show result
|
||||
User->>Ranj:enter code
|
||||
Ranj->>Dalan: Post mobiles/verify params
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found', 'phone.doesnt_exist'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 400, message: phone.verification_invalid
|
||||
note right of Ranj: if user wants to replace a new verified phone and the legacy phone has owner_phone label, we should check ownership. if it doesnt legacy phone labels all changes will be rollback.
|
||||
Dalan->>Ranj: success 2xx
|
||||
Ranj->>User: show result
|
||||
```
|
||||
45
docs/zagros/KYC-steps/level-one/bank-information.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# KYC: Bank information
|
||||
|
||||
### Outcome:
|
||||
we checking ownership of card-numbers and ibans.
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
Post {$domain}/api/v2/barong/resource/profiles/treasury
|
||||
|
||||
#### File destination:
|
||||
- {$Dalan_Path}/app/api/v2/resource/profiles.rb
|
||||
- {$Dalan_Path}/app/workers/kyc/local/treasury_worker.rb
|
||||
- {$Dalan_Path}/app/services/jibit_service.rb
|
||||
|
||||
|
||||
#### Commits:
|
||||
- 40177a4f
|
||||
- 816fb00e
|
||||
- 9e17677b
|
||||
- 63977c33
|
||||
- c76f72fe
|
||||
- 90cbc486
|
||||
|
||||
#### What did we implement:
|
||||
We implemented a new model and table to keep users bank information and called it treasury.<br />
|
||||
After users entered their card_number or IBAN, we are sending this information to the Jibit service,<br />
|
||||
and then the Jibit Service returns the first name and last name of the real owner.<br />
|
||||
Now we can check this returned information to users' profile information to find out everything is ok.<br />
|
||||
It is worth mentioning that the steps of getting information from the Jibit and checking it with the profile are done in the background.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: bank information (treasury)
|
||||
note over User,Dalan: Users enter their bank information
|
||||
note over User,Dalan: `data` is card-number or iban value, `kind` is 'card' or 'iban'
|
||||
User->>Dalan:data, kind, title
|
||||
|
||||
note over Dalan,Jibit: Dalan send request to Jibbit service (as worker)
|
||||
Dalan->>Jibit:GET: iban value or card value (data)
|
||||
Jibit->>Dalan:Response: first-name and last-name of real owner
|
||||
Dalan->>Dalan: checking returned information with users profile data
|
||||
Dalan->>User: add a confirmed label if the names matched, otherwise rejected label was created.
|
||||
```
|
||||
38
docs/zagros/KYC-steps/level-one/personal-info.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# KYC: Personal info
|
||||
###### Sprint: 3
|
||||
|
||||
### Outcome:
|
||||
Users add the below information to their profile
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
POST {$domain}/api/v2/barong/resource/profiles
|
||||
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/resource/profiles.rb
|
||||
|
||||
#### Commits:
|
||||
9f1cde76
|
||||
2422f5d1
|
||||
|
||||
#### What did we implement:
|
||||
In the Opendax, users can create their profiles by personal info and Address info in one step, also in this step there is no way to upload identity card
|
||||
|
||||
So In Zagros, we separate the step of adding personal info from adding address info step, and also we add upload identity card features
|
||||
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: KYC - Profile Step
|
||||
note over User,Ranj:**upload** is a picture of front identity card
|
||||
User->>Ranj:first_name, last_name, dob, national_code, upload
|
||||
Ranj->>Dalan:Post: after client side checking
|
||||
Dalan->>Ranj:4xx if any required params are empty
|
||||
Dalan->>Ranj:4xx if Profile model validity fails
|
||||
Dalan->>Ranj:4xx if Document model validity fails
|
||||
Dalan->>Ranj:2xx the profile create successfully
|
||||
Ranj->>User:notify user that profile created
|
||||
```
|
||||
91
docs/zagros/KYC-steps/level-two/landline.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# KYC: landline
|
||||
|
||||
###### Sprint: 3
|
||||
|
||||
### Outcome:
|
||||
|
||||
User should enter his number, after the validation app sends a call with an otp code, the user must enter the code to prove to us that he has access to the entered number.
|
||||
|
||||
#### Endpoints:
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/phones
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/phones/send_code
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/phones/verify
|
||||
|
||||
#### File destination:
|
||||
|
||||
{$Dalan_Path}/app/api/v2/resource/phones.rb
|
||||
|
||||
#### Commits:
|
||||
|
||||
bd7f980596
|
||||
695b0b56e2
|
||||
6dd40a9c42
|
||||
e04a58b012
|
||||
36167eda10
|
||||
2089690fe0
|
||||
90cbc48649
|
||||
17a5bce849
|
||||
63722fe22a
|
||||
63977c330d
|
||||
bff2746686
|
||||
75490dcb22
|
||||
f13ee3f4d5
|
||||
2c05522f77
|
||||
46c053b435
|
||||
551e7cdba2
|
||||
77d7b9a9b3
|
||||
2da71b1097
|
||||
|
||||
|
||||
#### What did we implement:
|
||||
|
||||
in access mobile told about KaveNegarService
|
||||
user entered landline number then system send call by kave negar with otp code
|
||||
user must enter send code to prove us that has access.
|
||||
|
||||
if user wants to enter new number:
|
||||
|
||||
1.if user have verified phone: response error
|
||||
|
||||
2.if user has pending number: update that number with new one
|
||||
|
||||
3.if user doesnt have number in our system: create new one
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: access landline
|
||||
User->>Ranj: enter landline number with +98
|
||||
Ranj-->>Dalan: post /phones params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'code_doesnt_expired'(there is an active process for addding new landline) and phone.exists(has verified number in system)
|
||||
Dalan->>Ranj: 200, message: 'New phone was added'
|
||||
note left of Dalan: if there is a pending number it will be replaced with new one
|
||||
Dalan->>KaveNegar: send call to User in case of success
|
||||
KaveNegar->>User: call with code
|
||||
Ranj->>User: show result
|
||||
note right of User: if didnt catch call
|
||||
|
||||
User->>Ranj: resend code
|
||||
Ranj->>Dalan: Post phones/send_code params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found', 'phone.doesnt_exist'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 422, message: 'code_doesnt_expired' (expiration time doesnt finish)
|
||||
Dalan->>KaveNegar: send call to User in case of success
|
||||
KaveNegar->>User: call with code
|
||||
Ranj->>User: show result
|
||||
User->>Ranj:enter code
|
||||
Ranj->>Dalan: Post phones/verify params
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'Record is not found', 'phone.doesnt_exist', 'verification_invalid
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: success 2xx
|
||||
Ranj->>User: show result
|
||||
```
|
||||
42
docs/zagros/KYC-steps/level-two/mobile-ownership.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# KYC: mobile ownership
|
||||
|
||||
### Outcome:
|
||||
we checking ownership of mobile.
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
PUT {$domain}/api/v2/barong/admin/profiles/label
|
||||
|
||||
#### File destination:
|
||||
- {$Dalan_Path}/app/workers/kyc/local/owner_mobile_worker.rb
|
||||
- {$Dalan_Path}/app/models/phone.rb
|
||||
- {$Dalan_Path}/app/services/kyc_service.rb
|
||||
- {$Dalan_Path}/app/api/v2/admin/profiles.rb
|
||||
- {$Dalan_Path}/app/services/jibit_service.rb
|
||||
|
||||
#### Commits:
|
||||
- 7f06a2e3
|
||||
- 816fb00e
|
||||
- 2c05522f
|
||||
- 90cbc486
|
||||
- 91e75604
|
||||
- bdfc578d
|
||||
|
||||
#### What did we implement:
|
||||
Ownership of mobile is done in background (worker) after last step (selfie confirmation).<br />
|
||||
The national code of verified profile with phone number , is sent to Jibit Service for matching.<br />
|
||||
The label key in the `labels` table is **owner_phone**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: mobile ownership
|
||||
note over Admin,Dalan: admin user confirm users selfie
|
||||
Admin->>PUT Dalan:user_uid, label_key, label_value
|
||||
|
||||
note over Dalan,Jibit: Dalan send request to Jibbit service (as worker)
|
||||
Dalan->>Jibit:GET: natonal_code, phone_number
|
||||
Jibit->>Dalan:Response: matched, false or true
|
||||
Dalan->>Dalan: create ownership label with reject label or verified label
|
||||
```
|
||||
72
docs/zagros/KYC-steps/level-two/residence.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# KYC: Residence
|
||||
|
||||
###### Sprint: ?
|
||||
|
||||
### Outcome:
|
||||
|
||||
User can add address with complete information(city and province and etc..)
|
||||
|
||||
|
||||
#### Endpoints:
|
||||
|
||||
POST {$domain}/api/v2/barong/resource/profiles/address
|
||||
|
||||
#### File destination:
|
||||
|
||||
{$Dalan_Path}/app/api/v2/resource/profiles.rb
|
||||
|
||||
#### Commits:
|
||||
|
||||
f7820d8
|
||||
3e0fff4
|
||||
67c41b3
|
||||
f420fa4
|
||||
bff2746
|
||||
63977c3
|
||||
|
||||
#### What did we implement:
|
||||
|
||||
Opendax just implements address as a string but we need more information like city and province and document for residency.
|
||||
|
||||
So first of all we implemented city and province as below steps:
|
||||
|
||||
##### 1.create migrations:
|
||||
|
||||
20210420111532_create_provinces.rb → have just a name
|
||||
|
||||
20210420111629_create_cities.rb → have name and must connect to province(foreign key) references :province, foreign_key: true
|
||||
|
||||
|
||||
|
||||
##### 2.create models
|
||||
|
||||
Province model:
|
||||
|
||||
* Create validation for name: only allows letters, digits "-", "\'", and space. length: 1..255
|
||||
|
||||
* Mention to rails that this model has many cities
|
||||
|
||||
City model:
|
||||
* Mention to rails that this model belongs to province and this column is required.
|
||||
* Create validation for name: only allows letters, digits "-", "\'", and space. length: 1..255
|
||||
|
||||
we need seeds to fill city and province tables. So we used a JSON file from git and create a seed. data of the seed was put in config/seeds.yml file and the functions are in lib/barong/seed.rb.(seed_provinces and seed_cities) they check the existence of the data(city or province) then create it in db.
|
||||
|
||||
After these steps, we were ready to create a new API. we check the existence of the city and province that the user has been sent and create poa label. if user submitted another doc for poa and it has not been accepted, the new document will be replaced.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: residence
|
||||
User->>Ranj: residence information
|
||||
Ranj-->>Dalan: post /profiles/address params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token'
|
||||
Dalan->>Ranj: 404, message: 'needed data doesnt exist'
|
||||
Dalan->>Ranj: 422, message: 'Validation errors',(address.already_exist,province_doesnt_exist)
|
||||
Dalan->>Ranj: 422, message: 'code_doesnt_expired'(there is an active process for addding new mobile)
|
||||
Dalan->>Ranj: 200, message: 'New phone was added'
|
||||
note left of Dalan: if there is a pending address it will be replaced with new one
|
||||
```
|
||||
|
||||
|
||||
|
||||
38
docs/zagros/KYC-steps/level-two/selfie.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# KYC: Selfie
|
||||
###### Sprint: 3
|
||||
|
||||
### Outcome:
|
||||
Users can upload image for certification (the image includes selfie and signed text of the agreement )
|
||||
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
POST{$domain}/api/v2/barong/resource/profiles/selfie
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/resource/profiles.rb
|
||||
|
||||
#### Commits:
|
||||
ac083d21
|
||||
ea79c211
|
||||
|
||||
#### What did we implement:
|
||||
Users can upload images for the Selfie KYC step. In the first place that image is in a `pending` state.
|
||||
In the Admin panel, this image must be change state from `pending` to `confirm` or `reject`
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: KYC - Selfie
|
||||
|
||||
note over User,Ranj: **upload** must be valid format of image (jpg, jpeg, png)
|
||||
User->>Ranj: upload
|
||||
Ranj->>Dalan:Post: after client side checking
|
||||
Dalan->>Ranj:4xx if does not exist verified profile for the current user
|
||||
Dalan->>Ranj:4xx if before exist verified selfie image for the current user
|
||||
Dalan->>Ranj:2xx update (if exist unconfirmed ) or create new selfie
|
||||
Ranj->>User:notify user that password changed
|
||||
```
|
||||
78
docs/zagros/KYC-steps/leveling.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# KYC level logic
|
||||
|
||||
###### Sprint: 3
|
||||
|
||||
### Outcome:
|
||||
Users can upgrade their level by doing KYC processes
|
||||
|
||||
|
||||
### Implementation description:
|
||||
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/models/user.rb<br />
|
||||
{$Dalan_Path}/app/models/document.rb<br />
|
||||
{$Dalan_Path}/app/models/label.rb<br />
|
||||
{$Dalan_Path}/app/models/level.rb<br />
|
||||
{$Dalan_Path}/app/models/treasury.rb<br />
|
||||
{$Dalan_Path}/app/models/profile.rb<br />
|
||||
{$Dalan_Path}/app/services/kyc_service.rb
|
||||
|
||||
|
||||
#### Commits:
|
||||
2422f5d1
|
||||
40177a4f
|
||||
ac083d21
|
||||
7f06a2e3
|
||||
816fb00e
|
||||
2c05522f
|
||||
9e17677b
|
||||
bff27466
|
||||
63977c33
|
||||
c76f72fe
|
||||
90cbc486
|
||||
6dd40a9c
|
||||
695b0b56
|
||||
b3b5a08d
|
||||
bd7f9805
|
||||
|
||||
#### What did we implement:
|
||||
in the Opendax, KYC level handled by labels that id of them (label) shows user level,
|
||||
but not support feature that per-user level has own steps
|
||||
(each label is database record as Label model)
|
||||
obviously per step has its own label too and the label has a unique id itself.
|
||||
|
||||
so by considering this rule in the Opendax, we kept it but change some things to support multi-steps.<br />
|
||||
we implement some kind of giving-points system.
|
||||
users can achieve a new level If the sum of their label IDs reaches a certain limit that defines in the code.
|
||||
|
||||
as you know, each step is a kind of record database that controlling by model so:<br />
|
||||
bank information step is `Treasury` model
|
||||
selfie and address step is `Document` model (for uploading)
|
||||
mobile and landline steps are `Telephone` model
|
||||
profile is `Profile` model
|
||||
|
||||
so if one of the above kind records, is updated or created, we will create or update the corresponding label recording,
|
||||
and if the label is created or updated we will change the users level by calculating their points (points are the sum of label ids)
|
||||
|
||||
also, we keep levels (steps for KYC) in the Level model with the below data that was entered by seed
|
||||
|
||||
|
||||
levels:
|
||||
- key: email, id: 1 ,value: verified, description: "User enter a valid code after registration"
|
||||
- key: profile, id: 2, value: verified, description: "User personal documents have been verified"
|
||||
- key: access_phone, id: 3, value: verified, description: "User entered a valid code from sms"
|
||||
- key: card, id: 4, value: verified, description: "User card number have been verified"
|
||||
- key: iban, id: 5, value: verified, description: "User iban have been verified"
|
||||
- key: poa id: 6, value: verified, description: "User card bank have been verified"
|
||||
- key: telephone id: 7, value: verified, description: "User entered a valid code from ring call"
|
||||
- key: selfie id: 8, value: verified, description: "User selfie documents have been verified"
|
||||
- key: owner_phone id: 9, value: verified description: "User owner mobile have been verified"
|
||||
- key: vip id: 10, value: verified, description: "User Vip have been verified"
|
||||
|
||||
### TODO
|
||||
now if the label being confirmed accidental in the admin panel, they can not delete it,<br />
|
||||
so must implement new codes to handle this stuff
|
||||
|
||||
|
||||
|
||||
38
docs/zagros/admin/KYC-confirm.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# KYC: admin
|
||||
###### Sprint: ?
|
||||
|
||||
### Outcome:
|
||||
admin can verify or reject(change state(selfie,poa)) of documents.
|
||||
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
|
||||
POST {$domain}/api/v2/barong/admin/users/documents
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/admin/users.rb
|
||||
|
||||
#### Commits:
|
||||
bd7f980
|
||||
|
||||
#### What did we implement:
|
||||
for admin apis, we should check access of user(authorization) at first.
|
||||
after checking authorization, we checked existence of document and profile for related user.
|
||||
update state of document.
|
||||
we wrote some callbacks for every doc type to update labels state .
|
||||
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
title: admin document update
|
||||
User->>Ranj: user and new state of doc
|
||||
Ranj-->>Dalan: post /admin/users/documents params
|
||||
Dalan->>Ranj: 400, message: 'Required params are empty'
|
||||
Dalan->>Ranj: 401, message: 'Invalid bearer token', 'admin.ability.not_permitted'
|
||||
Dalan->>Ranj: 404, message: 'doesnt exist'(document.user_doesnt_exist,document.document_doesnt_exist)
|
||||
Dalan->>Ranj: 422, message: 'Validation errors'
|
||||
Dalan->>Ranj: 200, message: 'New phone was added'
|
||||
Ranj->>User: show admin result
|
||||
```
|
||||
28
docs/zagros/admin/treasury-list.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Admin API: list treasuries
|
||||
|
||||
### Outcome:
|
||||
list (Array) of users treasuries
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
GET {$domain}/api/v2/barong/admin/profiles/treasury/list
|
||||
|
||||
#### File destination:
|
||||
- {$Dalan_Path}/app/api/v2/admin/profiles.rb
|
||||
|
||||
#### Commits:
|
||||
- 0654aa1a04
|
||||
|
||||
#### What did we implement:
|
||||
We implemented one API in the panel that admin users can see a list of users' treasuries by entering user_id.<br />
|
||||
also, admin users can filter responses as IBAN or card treasuries by sending kind value.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: list treasuries
|
||||
note over Admin,Dalan: **kind** is optional
|
||||
Admin->>Dalan:GET user_uid, kind
|
||||
Dalan->>Admin:Array of treasuries [id, title, state, data, created_at, updated_at]
|
||||
```
|
||||
63
docs/zagros/change-password/change-password.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Registration: Change password
|
||||
###### Sprint: 2
|
||||
|
||||
### Outcome:
|
||||
Users can change login password by entering old and new password and confirm OTP code
|
||||
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
PUT {$domain}/api/v2/barong/resource/users/password
|
||||
|
||||
POST {$domain}/api/v2/barong/identity/confirm_password
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/resource/users.rb
|
||||
|
||||
#### Commits:
|
||||
fb5162e5
|
||||
8b16cc49
|
||||
fb9db4ee
|
||||
70104499
|
||||
63f69ed0
|
||||
0ee97595
|
||||
9e17677b
|
||||
5bb29d79
|
||||
|
||||
#### What did we implement:
|
||||
In the Opendax, users can change their current password without confirming the OTP code that must be sent to its mail. Also, there is not any limitation for attempting to enter the current password.
|
||||
|
||||
In Zagros, if users enter the wrong current password more than 3 times, they are kicked out from the logged state and the new password is just accepted after entering the valid OTP code.
|
||||
|
||||
```
|
||||
TODO:
|
||||
Number of failed attempts to enter the current password must be dynamic and
|
||||
changeable by the admin panel
|
||||
```
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: Change password
|
||||
|
||||
note over User,Ranj: old password parameter is the same as current password
|
||||
User->>Ranj:old_password, new_password, confirm_password
|
||||
Ranj->>Dalan:Put: after client side checking
|
||||
Dalan->>Ranj:4xx if attempt number for entering the valid current password is over
|
||||
Dalan->>Ranj:4xx if new_password is not same to confirm_password
|
||||
Dalan->>Ranj:4xx if old_password is not valid
|
||||
Dalan->>Ranj:4xx if new_password is same to old_password
|
||||
Dalan->>Ranj:4xx if length of new password is not valid
|
||||
Dalan->>User:2xx send otp to his or her mail
|
||||
Ranj->>User:Ask OTP code for confirming
|
||||
User-->>Ranj:if OTP code not received, try for resend after <color:#red>120</color> seconds
|
||||
Ranj-->>Dalan: Ask for sending OTP code again
|
||||
Dalan-->>User:2xx send otp to his or her mail
|
||||
User->>Ranj: enter OTP code
|
||||
Dalan->>Ranj:4xx if user does not exist in the system
|
||||
Ranj->>Dalan:Post : OTP code for checking ice
|
||||
Dalan->>Ranj:4xx if OTP code expired
|
||||
Dalan->>Ranj:2xx change user password
|
||||
Ranj->>User:notify user that password changed
|
||||
```
|
||||
53
docs/zagros/reset-password/reset-password.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Registration: Reset password
|
||||
###### Sprint: 2
|
||||
|
||||
### Outcome:
|
||||
Users can reset login password by entering email and confirm by OTP code
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
POST {$domain}/api/v2/barong/identity/users/password/generate_code
|
||||
POST {$domain}/api/v2/barong/identity/users/password/confirm_code
|
||||
POST {$domain}/api/v2/barong/identity/users/password/reset
|
||||
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/identity/users.rb
|
||||
|
||||
#### Commits:
|
||||
9e17677b
|
||||
42b34ae2
|
||||
e04a58b0
|
||||
|
||||
#### What did we implement:
|
||||
In the Opendax, users get a reset token by entering their email, after in reset password page user can reset the password by entering a valid reset token and a new password
|
||||
|
||||
In Zagros, the reset password process is done in 3 steps, the first step is to generate OTP code by Vault, then is a step to check the OTP code in by separate API, and then reset the password
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: Reset password
|
||||
|
||||
User->>Ranj:email
|
||||
Ranj->>Dalan:Post: after client side checking
|
||||
Dalan->>Ranj:4xx if the user does not exist
|
||||
Dalan->>User:2xx send otp to his or her mail
|
||||
Ranj->>User:Ask OTP code for confirming
|
||||
User-->>Ranj:if OTP code not received, try for resend after <color:#red>120</color> seconds
|
||||
Ranj-->>Dalan: Ask for sending OTP code again
|
||||
Dalan-->>User:2xx send otp to his or her mail
|
||||
User->>Ranj: enter OTP code
|
||||
Ranj->>Dalan: OTP code for checking
|
||||
Dalan->>Ranj:4xx if user does not exist in the system
|
||||
Dalan->>Ranj:4xx if OTP code expired
|
||||
Dalan->>Ranj:2xx OTP code is check\n
|
||||
Ranj->>User: show reset password page
|
||||
Ranj->>Dalan: email, password, confirm_password
|
||||
Dalan->>Ranj:4xx if user does not exist in the system
|
||||
Dalan->>Ranj:4xx if new_password is not same to confirm_password
|
||||
Dalan->>Ranj:4xx if new password is not strong
|
||||
Dalan->>Ranj:2xx reset user password
|
||||
Ranj->>User:notify user that password changed
|
||||
```
|
||||
56
docs/zagros/sign-up/sign-up.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Registration: Sign-up
|
||||
###### Sprint: 2
|
||||
|
||||
### Outcome:
|
||||
Users can register via an email and a strong password, then we send OTP code to this email, the user must confirm the email by entering the OTP code.
|
||||
|
||||
|
||||
### Implementation description:
|
||||
|
||||
#### Endpoints:
|
||||
POST: {$domain}/api/v2/barong/identity/users
|
||||
|
||||
POST: {$domain}/api/v2/barong/identity/confirm_email
|
||||
|
||||
#### File destination:
|
||||
{$Dalan_Path}/app/api/v2/identity/users.rb
|
||||
|
||||
#### Commits:
|
||||
42602037
|
||||
Fb5162e5
|
||||
f57aaf35
|
||||
fb9db4ee
|
||||
70104499
|
||||
63f69ed0
|
||||
99c25524
|
||||
0ee97595
|
||||
|
||||
#### What did we implement?
|
||||
In the Opendax, users confirm their email by a unique link that is sent to their email, also in the registration process if one person uses an incorrect email, the email locks forever so the real owner of the email can not register ever.
|
||||
In the Zagros, the email will lock when confirming it and this confirming happens when the user enters the Six digits OTP code in the website.
|
||||
To send OTP code, we use Vault Service and adding action variable to distinguish every use of the Vault (for example to use it in following processes: Sign up, Change password, reset password and etc) also, email duplication in the registration process is allowed until the email confirmation or ban email in the system
|
||||
|
||||
`Ps: action is a new variable that passes to ruby vault service.`
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Title: Sign up
|
||||
|
||||
note over User,Ranj:starred parameters are optional
|
||||
User->>Ranj:email, password, *refid*
|
||||
Ranj->>Dalan:Post : after client side checking
|
||||
Dalan->>Ranj:4xx if user status is active or ban
|
||||
Dalan->>Ranj:4xx if email or password not valid
|
||||
Dalan->>User:2xx send otp to his or her mail
|
||||
Ranj->>User:Ask OTP code for confirming
|
||||
User-->>Ranj:if OTP code not received, try for resend after 120 seconds
|
||||
Ranj-->>Dalan:Ask for sending OTP code again
|
||||
Dalan-->>User:2xx send otp to his or her mail
|
||||
User->>Ranj: enter OTP code
|
||||
Ranj->>Dalan:Post : OTP code for checking
|
||||
Dalan->>Ranj:4xx if OTP code expired
|
||||
Dalan->>Ranj:4xx if user not exist in system
|
||||
Dalan->>Ranj:2xx create user, return user information
|
||||
Ranj->>User:Redirect user to the main page
|
||||
```
|
||||
31
docs/zagros/uploader/uploader.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Uploader
|
||||
|
||||
The uploader **principle** defines that who is responsible for saving any document type in the system and how does it.
|
||||
|
||||
the Opendax support these providers as uploader type
|
||||
`local` `google` `aws` `alicloud`
|
||||
|
||||
for `google`, `aws`, and `local` type, the UploadUploader class is a provider,
|
||||
this class is a child from this gem :
|
||||
[carrierwave](https://github.com/carrierwaveuploader/carrierwave)
|
||||
|
||||
**path of file** : app/uploaders/upload_uploader.rb
|
||||
|
||||
but for `alicloud` type, the provider is `AliUploader` class
|
||||
|
||||
**path of file** : app/uploaders/ali_uploader.rb that this class in the child of carrierwave gem too.
|
||||
|
||||
|
||||
in the `Dalan` version, we save files without any encryption
|
||||
and use only `local` type for uploader and this config exist in alvand/config/app.yml
|
||||
|
||||
the path of uploaded file is :
|
||||
|
||||
```"public/uploads/#{model.class.to_s.underscore}/upload/#{model.id}"
|
||||
example : public/uploads/document/upload/1/front_card.png
|
||||
```
|
||||
###TODO
|
||||
#### [Fog](https://fog.io/storage/)
|
||||
in app/uploaders/upload_uploader.rb , we change the config code to hardcode to always use `local` type,
|
||||
if you want to use fog type you must revert these lines:
|
||||
line 4 to 12
|
||||