Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This document describes graphQL createAuthMethRequest mutation purpose and validations.

Table of Contents
minLevel1
maxLevel7

Purpose

To allow NHS Admin/Data Stuart (NHS employee with assigned appropriate scopes) to CREATE/UPDATE/DEACTIVATE authentication methods for a Person, based on Person’s official request to NHS, which is actually a legal authorisation for changes in his personal data. Without Digital signature.

Schemas

Processing of request

...

Flow of statuses

...


Specification

Expand
titleindex.graphql
Code Block
"Create/Update/Deactivate an authentication method for a single `Person` using its globally unique ID. IL.Authentication_method_requests entity is used"
  createAuthMethRequest(input: createAuthMethRequestInput!): createAuthMethRequestPayload

Expand
titlepersonAuthenticationMethods.ghraphql
Code Block
Input for `createAuthMethRequest` mutation.

In order to Create/Update/Deactivate patient authentication methods user must have a scope `authentication_method_request:write_nhs`
"""
input createAuthMethRequestInput {
  "Primary key identifier from MPI.persons.id"
  personId: ID!
  "Action"
  action: AuthMethRequestAction!
  authenticationMethod: {
    "The ID of an authentication method (mandatory when action `\"UPDATE\"` and `\"DEACTIVATE\"`, for `\"INSERT\"` - absent)"
    id: ID!
    "Alias name. I.e. `\"Father\"`, `\"Mother\"`"
    alias: String
    "Phone number of a person (mandatory for action `\"INSERT\"` and when `type` is `\"OTP\"` or `\"THIRD_PERSON\"`)."
    phoneNumber: String
    "ID of a Third Person (mandatory for action `\"INSERT\"`. when `type` is `\"THIRD_PERSON\"` authentication method. For types `\"OTP\"` and `\"OFFLINE\"` it should not be defined"
    value: ID
    "Type of authentication method created (mandatory when action is `\"INSERT\"`)."
    type: AuthMethType
  }
}

"""
Actions which user can use to Create/Update/Deactivate authenticatin methods of a Person
"""

enum AuthMethRequestAction {
  "Action for Creation of an auth method"
  INSERT
  "Action for Update of a certain auth method"
  UPDATE
  "Action for Deactivation of a certain auth method"
  DEACTIVATE

}

"""
Type of authentication/authorisation methods which Person can use.
This types exist in the `AUTHENTICATION_METHOD` dictionary.
"""

enum AuthMethType {
  "Online authentication method. OTP and OFFLINE cannot be togeather "
  OTP
  "Offline authentication method. OTP and OFFLINE cannot be togeather"
  OFFLINE
  "Authentication using authentication methods of a Third person"
  THIRD_PERSON

}

"""
Return type for `createAuthMethRequest` mutation. User must have a scope `authentication_method_request:read
"""
type createAuthMethRequestPayload {
  "Authentication method of a Person"
  authenticationMethod: PersonAuthenticationMethod!
}

Key points

The process is initiated by any NHS employee with necessary scopes and involves the transfer (by graphQL mutation) of data, needed for the following actions: INSERT, UPDATE, DEACTIVATE. Message (request) includes:

...

  1. Authentication_method_request record is created in BE directly in status COMPLETED based JSON from FE. Without interim records to DB with such statuses as NEW.

  2. During update process of Person’s authentication method in MPI.person_authentication_methods table (by using IL.authentication_method_requestsentity), there is no need in ONLINE/OFFLINE approve from Person. I.e. not necessary to generate OTPs and links for uploading of documents to Bucket.

    1. authentication_method_requests.(new record).authentication_method_current = null

    2. It is allowed to create new auth method for Person with not verified phone.

  3. DEACTIVATION can be done for OTP, OFFLINE, THIRD_PERSON (not only for THIRD_PERSON, as it is in the standard process). So AUTH_REQUEST_SECURITY_REDUCTION parameter is not used as a control in this mutation.

  4. Scope is used: authentication_method_request:write_nhs

  5. And there are other differences in fields, values and controls:

    1. IL.authentication_method_request.(new record).channel = 'NHS'

Scope and roles

scope

New

authentication_method_request:write_nhs

roles

  1. ADMIN

  2. NHS ADMIN VERIFIER

description

Scope for creation of authentication methods for person record. Without online/offline approve by Person. As Person’s paper request to NHS - is actually a legal authorisation for changes in Person’s personal data.

...

Authorize

  1. Verify the validity of access token

    1. Return 401 in case validation fails

  2. Verify that token is not expired

    • in case of error - return (401, 'Invalid access token')

  3. Check user scope authentication_method_request:write_nhs in order to perform this action

    1. Return 403 in case invalid scope(s)

Validate legal entity

  • Extract client_id from token.

  • Check client scopes has authentication_method_request:write_nhs

    • in case of error - return 403 (“Your scope does not allow to access this resource. Missing allowances: authentication_method_request:write_nhs”)

  • Check legal entity status (status = ACTIVE)

    • In case of error - return 409 ('client_id refers to legal entity that is not active')

Get global parameters

Invoke Global parameters to get parameters, used for validations during creation (action: INSERT) of new authentication method for Person:

...

Code Block
curl -X GET \
  {:host}/api/global_parameters

Validate request

  • personID is a text:

    • Person:9f45775f-2dc8-472f-bd98-b072780f7482 coded in base64

  • authentication_method’s id is a text:

    • PersonAuthenticationMethod:86ee6615-7c19-71ce-35e6-2337fb9894fd coded in based64

  • value is an id of a third person, which is a text Person:UUID coded in base64

...

Code Block
{
  "$schema": "http://json-schema.org/draft-05/schema#",
  "type": "object",
  "properties": {
  "personId": "UGVyc29uOjlmNDU3NzVmLTJkYzgtNDcyZi1iZDk4LWIwNzI3ODBmNzQ4Mg=="
  "action": "INSERT",
  "authenticationMethod": {
    "type": "OTP",
    "phoneNumber" : "+380656779678",
    "alias": "railway"
    }
  }
}

{
  "$schema": "http://json-schema.org/draft-05/schema#",
  "type": "object",
  "properties": {
  "personId": "UGVyc29uOjlmNDU3NzVmLTJkYzgtNDcyZi1iZDk4LWIwNzI3ODBmNzQ4Mg=="
  "action": "INSERT",
  "authenticationMethod": {
    "type": "OFFLINE",
    "alias": "mydocs"
    }
  }
}

Validate $.personId

Check $.personId is ID from MPI.person.id

  • validate $.personId is UUID and UUID is version 4

    • in case of error, return 422

  • search person $.personId in MPI.person.(id = $.personId) andMPI.person.(id = $.personId).is_active = true then ok

    • in case of error, return 404, "Such person doesn't exist"

  • validate that person is active MPI.person.(id = $.personId).status = ‘active’

    • in case of error, return 409, "Such person isn't active"

Validation and processing of message by actions

Definition

  1. OTP and OFFLINE - are Primary auth method

  2. Person can have only one Primary auth method

  3. Secondary auth method - THIRD_PERSON. Person can have many of them.

if action = deactivate

Primary auth method can be deactivated also

  1. validate $.authenticationMethod.id is UUID and UUID is version 4

    1. in case of error, return 422

  2. validate availability in MPI.person_authentication_methods where

    1. is_active = true and person_id = $.personId and id = $.authenticationMethod.id then ok

      1. in case of error, return 404, "such authentication method was not found for this person"

  3. validate ended_At in MPI.person_authentication_methods where

    1. ended_At > now ()

      1. in case of error, return 422, "Such method is expired"

  4. validate $.authenticationMethod.type in(OTP, OFFLINE, THIRD_PERSON).

No necessity to check current method of Person: auth_method_current ($.personId)

if action = update

  1. validate $.authenticationMethod.id is UUID and UUID is version 4

    1. in case of error, return 422

  2. validate availability in MPI.person_authentication_methods where

    1. is_active = true and person_id = $.personId and id = $.authenticationMethod.id then ok

      1. in case of error, return 404, "such authentication method was not found for this person"

  3. validate ended_At in MPI.person_authentication_methods where

    1. ended_At > now ()

      1. in case of error, return 422, "Such method is expired"

  4. alias is required.

No necessity to check current method of Person: auth_method_current ($.personId)

if action = insert

1

if $.authenticationMethod.type = OTP

  1. phone_number is required and value shouldn’t be set. And field alias is optional.

  2. validate that person.age > gp.no_self_auth_age

  3. If USE_PHONE_NUMBER_AUTH_LIMIT = true then validate

    1. Check if count(*) < gp.phone_number_auth_limit in MPI.person_authentication_methods table where ((is_active = true and ended_At > now) and type = OTP ), then ok

      1. in case of error, return 422, "such phone already exists N times"

2

if $.authenticationMethod.type = OFFLINE

  1. phone_numberand value shouldn’t be set . And field alias is optional.

  2. validate that person.age > gp.no_self_auth_age

3

if $.authenticationMethod.type = THIRD_PERSON

  1. value, alias are required. phone_number - might be optional and mandatory depending on THIRD_PERSON_OFFLINE parameter.

  2. validate $.authenticationMethod.value(third person’s id):

    1. validate $.authenticationMethod.value is UUID

      • in case error return 404

    2. search person by $.authenticationMethod.value in MPI with filter person.is_active = true

      1. If found then

        1. (if person.status = active then ok

          1. in case error return 422, "Third person must be active" )

      2. Else not found then return 422, "Such person doesn't exist"

    3. check if count(*) >= gb.third_person_limit in MPI.person_authentication_methods with ( type = THIRD_PERSON  and value = $.authenticationMethod.value and ended_at > now() and is_active = true), then error 422 "Third person cannot be added for authentication purpose for current person as that person already authenticates other persons N times "

    4. search third_person.age > gp.no_self_auth_age years:

      • in case error return 422, "third person must be adult"

  3. validate (third_person.auth_method = N/A or third_person.auth_method has only active THIRD_PERSONs) then

    • if THIRD_PERSON_OFFLINE = false then

      • Error 422 "Third person must have auth method OTP"

    • elseif THIRD_PERSON_OFFLINE = true then

      • Error 422 "Third person must have auth method either OTP or OFFLINE"

  4. Validation of third person’s auth methods.

    • If primary method of Third person = Offline then

      • if $.authenticationMethods.phone_number is not empty and THIRD_PERSON_OFFLINE = true then

        1. 422 "Third person does not have such authentication method"

      • if $.authenticationMethods.phone_number is empty and THIRD_PERSON_OFFLINE = true then Ok

      • elseif THIRD_PERSON_OFFLINE = false then

        1. 422 "Third person does not have authentication method OTP, which is mandatory for such operation"

    • If primary method of Third person = OTP

      1. if $.authenticationMethods.phone_number is empty then

        1. 422 "Phone number should be specified. Third person has OTP method"

      2. if $.authenticationMethods.phone_number is not empty then

        1. Check phone_number whether MPI.person_authentication_methods.(person_id = $.authenticationMetod.value).phone_number = $.authenticationMethod.phoneNumber

          1. in case of error, 422 "Phone number does not match third person's phone number"

  5. validate count(*) < gp.person_with_third_person_limit where ( person_id = $.personId and is_active = true and ended_at > now()and third_type = THID_PERSON)

    1. in case of error, return 422, "Quantity of existing authentication methods with type of THIRD_PERSON for this Person exceeds allowed"

Processing (execution)

Cancel pending auth requests

Search by $.personId and cancel pending auth requests

 To prevent requests duplication:

...

Code Block
SET   IL_DB.authentication_method_requests.status = 'CANCELED'
WHERE IL_DB.authentication_method_requests.id IN (:LIST)

Create new record in IL.authentication_method_requests

Assignment of “authorisation with” field (auth_method_current)

Set default auth method of person on IL.auth_method_request.auth_method_current = null

Explanation: Based on authentication_method_request:write_nhs scope NHS Admin has right to create/update/deactivate authentication methods without online/offline authorisation by Person. I.e. without OTP and without uploading of documents

Create/Update/Deactivate method in MPI.person_authentication_methods

Based on $.action methods are created/updated/deactivated in MPI.person_authentication_methods

With setting of fields updated_at, inserted_at, inserted_by, updated_by

Deactivate methods

Action insert

  1. if $.type = OTP or $.type = OFFLINE then all active methods of a Person in MPI.person_authentication_methods where (person_id = $.personId and is_active = true and ended_At > now()) with (type in OTP, OFFLINE) deactivated .

    1. set MPI.person_authentication_methods.(:LIST).ended_at = now()

  2. if $.type = THIRD_PERSON then active method of a Person in MPI.person_authentication_methods where (person_id = $.personId and is_active = true and ended_At > now() and value = $.authenticationMethod.value and type = 'THIRD_PERSON') deactivated .

    1. set MPI.person_authentication_methods.(found id).ended_at = now()

Action deactivate

  1. Appropriate method deactivate by setting auth method’s ended_At to now()

    1. MPI.person_authentication_methods.(person_id = $.personId and id = $.id).ended_at = now()

Set is_active field

  1. In case of INSERT action

    1. is_active = true

  2. In case of UPDATE/DEACTIVATE action

    1. Do not change is_active
      As UPDATE/DEACTIVATION is possible only for fields with is_active = true, as it was described earlier within this document.

Set the started_at, end date of the person_ausentication_method.ended_at

For action insert.

These params set only if auth method is being created

...

Code Block
if (person.age < gp.no_self_auth_age) {
  end_date = end_date =birth_date + gp.no_self_auth_age - 1d;
} else {
  end_date = start_date + gp.third_person_term;
}

Check if Person should be sent for verification

If action = insertthen Update Person’s record in MPI.persons according to the following validations https://edenlab.atlassian.net/wiki/spaces/EH/pages/2986803342/Approve+auth+method+request+copied+from+pub#Validations-and-processing-related-to-Verification-of-a-Person-process

...