Merge branch 'master' into registry-790

This commit is contained in:
Artur Beljajev 2018-08-20 21:20:52 +03:00
commit c48cdf68b6
16 changed files with 918 additions and 56 deletions

11
doc/registrant-api.md Normal file
View file

@ -0,0 +1,11 @@
# Registrant API integration specification
Test API endpoint: TBA
Production API endpoint: TBA
Main communication specification through Registrant API:
[Authentication](registrant-api/v1/authentication.md)
[Domains](registrant-api/v1/domain.md)
[Domain Lock](registrant-api/v1/domain_lock.md)
[Contacts](registrant-api/v1/contact.md)

View file

@ -0,0 +1,109 @@
# Authentication
## Authenticating with mobileID or ID-card
For specified partners the API allows for use of data from mobile ID for
authentication. API client should perform authentication with eID according to
the approriate documentation, and then pass on values from the webserver's
certificate to the API server.
## POST /api/v1/registrant/auth/eid
Returns a bearer token to be used for further API requests. Tokens are valid for 2 hours since their creation.
#### Paramaters
Values in brackets represent values that come from the id card certificate.
| Field name | Required | Type | Allowed values | Description |
| ----------------- | -------- | ---- | -------------- | ----------- |
| ident | true | String | | Identity code of the user (`serialNumber`) |
| first_name | true | String | | Name of the customer (`GN`) |
| last_name | true | String | | Name of the customer (`SN`) |
#### Request
```
POST /api/v1/auth/token HTTP/1.1
Accept: application/json
Content-type: application/json
{
"ident": "30110100103",
"first_name": "Jan",
"last_name": "Tamm",
}
```
#### Response
```
HTTP/1.1 201
Content-Type: application.json
{
"access_token": "<SOME TOKEN>",
"expires_at": "2018-07-13 11:30:51 UTC",
"type": "Bearer"
}
```
## POST /api/v1/auth/username -- NOT IMPLEMENTED
#### Paramaters
Values in brackets represent values that come from the id card certificate
| Field name | Required | Type | Allowed values | Description |
| ----------------- | -------- | ---- | -------------- | ----------- |
| username | true | String | Username as provided by the user | |
| password | true | String | Password as provided by the user | |
#### Request
```
POST /api/v1/auth/token HTTP/1.1
Accept: application/json
Content-type: application/json
```
#### Response
```
HTTP/1.1 201
Content-Type: application.json
{
"access_token": "<SOME TOKEN>",
"expires_at": "2018-07-13 11:30:51 UTC",
"type": "Bearer"
}
```
## Implementation notes:
We do not need to store the session data at all, instead we can levarage AES encryption and use
Rails secret as the key. General approximation:
```ruby
class AuthenticationToken
def initialize(secret = Rails.application.config.secret_key_base, values = {})
end
def create_token_hash
data = values.to_s
cipher = OpenSSL::Cipher::AES.new(256, :CBC)
cipher.encrypt
encrypted = cipher.update(data) + cipher.final
base64_encoded = Base64.encode64(encrypted)
{
token: base64_encoded,
expires_in = values[:expires_in]
type: "Bearer"
}
end
end
```

View file

@ -0,0 +1,194 @@
## GET /api/v1/registrant/contacts
Returns contacts of the current registrar.
#### Parameters
| Field name | Required | Type | Allowed values | Description |
| ---------- | -------- | ---- | -------------- | ----------- |
| limit | false | Integer | [1..200] | How many contacts to show |
| offset | false | Integer | | Contact number to start at |
#### Request
```
GET /api/v1/registrant/contacts?limit=1 HTTP/1.1
Accept: application/json
Authorization: Bearer Z2l0bGFiOmdoeXQ5ZTRmdQ==
Content-Type: application/json
```
#### Response
```
HTTP/1.1 200
Content-Type: application/json
{
"contacts": [
{
"uuid": "84c62f3d-e56f-40fa-9ca4-dc0137778949",
"domain_names": ["example.com"],
"code": "REGISTRAR2:SH022086480",
"phone": "+372.12345678",
"email": "hoyt@deckowbechtelar.net",
"fax": null,
"created_at": "2015-09-09T09:11:14.130Z",
"updated_at": "2015-09-09T09:11:14.130Z",
"ident": "37605030299",
"ident_type": "priv",
"auth_info": "password",
"name": "Karson Kessler0",
"org_name": null,
"registrar_id": 2,
"creator_str": null,
"updator_str": null,
"ident_country_code": "EE",
"city": "Tallinn",
"street": "Short street 11",
"zip": "11111",
"country_code": "EE",
"state": null,
"legacy_id": null,
"statuses": [
"ok"
],
"status_notes": {
}
}
],
"total_number_of_records": 2
}
```
## GET /api/v1/registrant/contacts/$UUID
Returns contacts of the current registrar.
#### Request
```
GET /api/v1/registrant/contacts/84c62f3d-e56f-40fa-9ca4-dc0137778949 HTTP/1.1
Accept: application/json
Authorization: Bearer Z2l0bGFiOmdoeXQ5ZTRmdQ==
Content-Type: application/json
```
#### Response
```
HTTP/1.1 200
Content-Type: application/json
{
"uuid": "84c62f3d-e56f-40fa-9ca4-dc0137778949",
"domain_names": ["example.com"],
"code": "REGISTRAR2:SH022086480",
"phone": "+372.12345678",
"email": "hoyt@deckowbechtelar.net",
"fax": null,
"created_at": "2015-09-09T09:11:14.130Z",
"updated_at": "2015-09-09T09:11:14.130Z",
"ident": "37605030299",
"ident_type": "priv",
"auth_info": "password",
"name": "Karson Kessler0",
"org_name": null,
"registrar_id": 2,
"creator_str": null,
"updator_str": null,
"ident_country_code": "EE",
"city": "Tallinn",
"street": "Short street 11",
"zip": "11111",
"country_code": "EE",
"state": null,
"legacy_id": null,
"statuses": [
"ok"
],
"status_notes": {}
}
```
## PATCH /api/v1/registrant/contacts/$UUID
Update contact details for a contact.
#### Parameters
| Field name | Required | Type | Allowed values | Description |
| ---- | --- | --- | --- | --- |
| email | false | String | | New email address |
| phone | false | String | | New phone number |
| fax | false | String | | New fax number |
| city | false | String | | New city name |
| street | false | String | | New street name |
| zip | false | String | | New zip code |
| country_code | false | String | | New country code in 2 letter format ('EE', 'LV') |
| state | false | String | | New state name |
#### Request
```
PATCH /api/v1/registrant/contacts/84c62f3d-e56f-40fa-9ca4-dc0137778949 HTTP/1.1
Authorization: Bearer Z2l0bGFiOmdoeXQ5ZTRmdQ==
Accept: application/json
Content-type: application/json
{
"email": "foo@bar.baz",
"phone": "+372.12345671",
"fax": "+372.12345672",
"city": "New City",
"street": "Main Street 123",
"zip": "22222",
"country_code": "LV",
"state": "New state"
}
```
#### Response on success
```
HTTP/1.1 200
Content-Type: application.json
{
"uuid": "84c62f3d-e56f-40fa-9ca4-dc0137778949",
"domain_names": ["example.com"],
"code": "REGISTRAR2:SH022086480",
"phone": "+372.12345671",
"email": "foo@bar.baz",
"fax": "+372.12345672",
"created_at": "2015-09-09T09:11:14.130Z",
"updated_at": "2018-09-09T09:11:14.130Z",
"ident": "37605030299",
"ident_type": "priv",
"auth_info": "password",
"name": "Karson Kessler0",
"org_name": null,
"registrar_id": 2,
"creator_str": null,
"updator_str": null,
"ident_country_code": "EE",
"city": "New City",
"street": "Main Street 123",
"zip": "22222",
"country_code": "LV",
"state": "New state"
"legacy_id": null,
"statuses": [
"ok"
],
"status_notes": {}
}
```
### Response on failure
```
HTTP/1.1 400
Content-Type: application.json
{
"errors": [
{ "phone": "Phone nr is invalid" }
]
}
```

View file

@ -0,0 +1,161 @@
# Domain related actions
## GET /api/v1/registrant/domains
Returns domains of the current registrant.
#### Parameters
| Field name | Required | Type | Allowed values | Description |
| ---------- | -------- | ---- | -------------- | ----------- |
| limit | false | Integer | [1..200] | How many domains to show |
| offset | false | Integer | | Domain number to start at |
| details | false | String | ["true", "false"] | Whether to include details |
#### Request
```
GET api/v1/registrant/domains?limit=1&details=true HTTP/1.1
Accept: application/json
Authorization: Bearer Z2l0bGFiOmdoeXQ5ZTRmdQ==
Content-Type: application/json
```
#### Response
```
HTTP/1.1 200
Content-Type: application/json
{
"domains": [
{
"uuid": "98d1083a-8863-4153-93e4-caee4a013535",
"name": "domain0.ee",
"registrar_id": 2,
"registered_at": "2015-09-09T09:11:14.861Z",
"status": null,
"valid_from": "2015-09-09T09:11:14.861Z",
"valid_to": "2016-09-09T09:11:14.861Z",
"registrant_id": 1,
"transfer_code": "98oiewslkfkd",
"created_at": "2015-09-09T09:11:14.861Z",
"updated_at": "2015-09-09T09:11:14.860Z",
"name_dirty": "domain0.ee",
"name_puny": "domain0.ee",
"period": 1,
"period_unit": "y",
"creator_str": null,
"updator_str": null,
"legacy_id": null,
"legacy_registrar_id": null,
"legacy_registrant_id": null,
"outzone_at": "2016-09-24T09:11:14.861Z",
"delete_at": "2016-10-24T09:11:14.861Z",
"registrant_verification_asked_at": null,
"registrant_verification_token": null,
"pending_json": {
},
"force_delete_at": null,
"statuses": [
"ok"
],
"reserved": false,
"status_notes": {
},
"statuses_backup": [
]
}
],
"total_number_of_records": 2
}
```
## GET api/v1/registrant/domains
Returns domain names with offset.
#### Request
```
GET api/v1/registrant/domains?offset=1 HTTP/1.1
Accept: application/json
Authorization: Bearer Z2l0bGFiOmdoeXQ5ZTRmdQ==
Content-Type: application/json
```
#### Response
```
HTTP/1.1 200
Content-Type: application/json
{
"domains": [
"domain1.ee"
],
"total_number_of_records": 2
}
```
## GET api/v1/registrant/domains/$UUID
Returns a single domain object.
#### Request
```
GET api/v1/registrant/domains/98d1083a-8863-4153-93e4-caee4a013535 HTTP/1.1
Accept: application/json
Authorization: Bearer Z2l0bGFiOmdoeXQ5ZTRmdQ==
Content-Type: application/json
```
#### Response for success
```
HTTP/1.1 200
Content-Type: application/json
{
"uuid": "98d1083a-8863-4153-93e4-caee4a013535",
"name": "domain0.ee",
"registrar_id": 2,
"registered_at": "2015-09-09T09:11:14.861Z",
"status": null,
"valid_from": "2015-09-09T09:11:14.861Z",
"valid_to": "2016-09-09T09:11:14.861Z",
"registrant_id": 1,
"transfer_code": "98oiewslkfkd",
"created_at": "2015-09-09T09:11:14.861Z",
"updated_at": "2015-09-09T09:11:14.860Z",
"name_dirty": "domain0.ee",
"name_puny": "domain0.ee",
"period": 1,
"period_unit": "y",
"creator_str": null,
"updator_str": null,
"legacy_id": null,
"legacy_registrar_id": null,
"legacy_registrant_id": null,
"outzone_at": "2016-09-24T09:11:14.861Z",
"delete_at": "2016-10-24T09:11:14.861Z",
"registrant_verification_asked_at": null,
"registrant_verification_token": null,
"pending_json": {},
"force_delete_at": null,
"statuses": [
"ok"
],
"reserved": false,
"status_notes": {},
"statuses_backup": []
}
```
#### Response for failure
```
HTTP/1.1 404
Content-Type: application/json
{ "errors": ["Domain not found"] }
```

View file

@ -0,0 +1,163 @@
# Domain locks
## POST api/v1/registrant/domains/$UUID/registry_lock
Set a registry lock on a domain.
#### Request
```
POST api/v1/registrant/domains/98d1083a-8863-4153-93e4-caee4a013535/registry_lock HTTP/1.1
Accept: application/json
Authorization: Bearer Z2l0bGFiOmdoeXQ5ZTRmdQ==
Content-Type: application/json
```
#### Response for success
```
HTTP/1.1 200
Content-Type: application/json
{
"uuid": "98d1083a-8863-4153-93e4-caee4a013535",
"name": "domain0.ee",
"registrar_id": 2,
"registered_at": "2015-09-09T09:11:14.861Z",
"status": null,
"valid_from": "2015-09-09T09:11:14.861Z",
"valid_to": "2016-09-09T09:11:14.861Z",
"registrant_id": 1,
"transfer_code": "98oiewslkfkd",
"created_at": "2015-09-09T09:11:14.861Z",
"updated_at": "2015-09-09T09:11:14.860Z",
"name_dirty": "domain0.ee",
"name_puny": "domain0.ee",
"period": 1,
"period_unit": "y",
"creator_str": null,
"updator_str": null,
"legacy_id": null,
"legacy_registrar_id": null,
"legacy_registrant_id": null,
"outzone_at": "2016-09-24T09:11:14.861Z",
"delete_at": "2016-10-24T09:11:14.861Z",
"registrant_verification_asked_at": null,
"registrant_verification_token": null,
"pending_json": {},
"force_delete_at": null,
"statuses": [
"serverUpdateProhibited",
"serverDeleteProhibited",
"serverTransferProhibited"
],
"reserved": false,
"status_notes": {},
"statuses_backup": []
}
```
#### Response for failure
```
HTTP/1.1 400
Content-Type: application/json
{
"errors": [
{ "base": "domain cannot be locked" }
]
}
```
```
HTTP/1.1 404
Content-Type: application/json
{
"errors": [
{ "base": "domain does not exist" }
]
}
```
## DELETE api/v1/registrant/domains/$UUID/registry_lock
Remove a registry lock.
#### Request
```
DELETE api/v1/registrant/domains/98d1083a-8863-4153-93e4-caee4a013535/registry_lock HTTP/1.1
Accept: application/json
Authorization: Bearer Z2l0bGFiOmdoeXQ5ZTRmdQ==
Content-Type: application/json
```
#### Response for success
```
HTTP/1.1 200
Content-Type: application/json
{
"uuid": "98d1083a-8863-4153-93e4-caee4a013535",
"name": "domain0.ee",
"registrar_id": 2,
"registered_at": "2015-09-09T09:11:14.861Z",
"status": null,
"valid_from": "2015-09-09T09:11:14.861Z",
"valid_to": "2016-09-09T09:11:14.861Z",
"registrant_id": 1,
"transfer_code": "98oiewslkfkd",
"created_at": "2015-09-09T09:11:14.861Z",
"updated_at": "2015-09-09T09:11:14.860Z",
"name_dirty": "domain0.ee",
"name_puny": "domain0.ee",
"period": 1,
"period_unit": "y",
"creator_str": null,
"updator_str": null,
"legacy_id": null,
"legacy_registrar_id": null,
"legacy_registrant_id": null,
"outzone_at": "2016-09-24T09:11:14.861Z",
"delete_at": "2016-10-24T09:11:14.861Z",
"registrant_verification_asked_at": null,
"registrant_verification_token": null,
"pending_json": {},
"force_delete_at": null,
"statuses": [
"ok"
],
"reserved": false,
"status_notes": {},
"statuses_backup": []
}
```
#### Response for failure
```
HTTP/1.1 400
Content-Type: application/json
{
"errors": [
{ "base": "domain cannot be unlocked" }
]
}
```
```
HTTP/1.1 404
Content-Type: application/json
{
"errors": [
{ "base": "domain does not exist" }
]
}
```