User Service

Overview

User service is responsible for user data management, and providing functionality to login and logout in the DIGIT system.

Pre-requisites

Before you proceed with the configuration, make sure the following pre-requisites are met:

  • Java 8

  • Kafka server is up and running

  • Encryption and MDMS services are running

  • PSQL server is running and database

  • Redis is running

Key Functionalities

  • Store, update and search user data

  • Provide authentication

  • Provide login,logout functionality into DIGIT platform

  • Store user data PIIs in encrypted form

Interaction Diagram

Deployment Details

  1. Set up latest version of egov-enc-service and egov-mdms- service.

  2. Deploy latest version of egov-user service.

  3. Add role action mapping for APIs.

Configuration Details

Following are the properties in application.properties file in user service which are configurable:

Property

Value

Remarks

egov.user.search.default.size

10

Default search record number limit

citizen.login.password.otp.enabled

true

Whether citizen login is OTP-based

employee.login.password.otp.enabled

false

Whether employee login is OTP-based

citizen.login.password.otp.fixed.value

123456

Fixed OTP for citizens

citizen.login.password.otp.fixed.enabled

false

Allow fixed OTP for citizens

otp.validation.register.mandatory

true

Whether OTP is compulsory for registration

access.token.validity.in.minutes

10080

Validity time of access token

refresh.token.validity.in.minutes

20160

Validity time of refresh token

default.password.expiry.in.days

90

Expiry date of a password

account.unlock.cool.down.period.minutes

60

Unlock time

max.invalid.login.attempts.period.minutes

30

Window size for counting attempts for lock

max.invalid.login.attempts

5

Max failed login attempts before account is locked

egov.state.level.tenant.id

pb

Integration

Integration Scope

User data management and functionality to login and logout into Digit system using OTP and password.

Integration Benefits

Employee

  • User registration

  • Search user

  • Update user details

  • Forgot password

  • Change password

  • User role mapping (single ULB to multiple roles)

  • Enable employee to login into DIGIT system based on password

Citizen

  • Create user

  • Update user

  • Search user

  • User registration using OTP

  • OTP-based login

Steps to Integration

  • To integrate, the host of the egov-user should be overwritten in helm chart.

  • Use /citizen/_create endpoint for creating users into the system. This endpoint requires the user to validate his/her mobile number using OTP. The OTP will be send to his/her mobile number, and then that OTP will be send as otpReference in the request body.

  • Use /v1/_search and /_search endpoints to search users in the system depending on various search parameters.

  • Use /profile/_update for updating the user profile. The user will be validated (either by OTP-based validation or password validation) when this API is called.

  • /users/_createnovalidate and /users/_updatenovalidate are endpoints to create user data into the system without any validations (no OTP or password required). They should be strictly used only for creating/updating users internally and should not be exposed outside.

  • Forgot password: In case the user forgets the password, it can be reset by calling /user-otp/v1/_send which will generate and send the OTP to the employee’s mobile number. The password can then be updated using this OTP by calling the API /password/nologin/_update in which new password along with the OTP has to be sent.

  • Use /password/_update to update the existing password by logging in. In the request body, both the old and new passwords hace to be sent. Details of the API can be found in the attached swagger documentation.

  • Use /user/oauth/token for generating token, /_logoutfor logout and /_details for getting user information from the token.

  • Multi-tenant user: This functionality allows a user to perform actions across multiple ULBs. For example, an employee belonging to Amritsar can perform a role of say a trade license approver for Jalandhar by assigning a tenant-level role of tenantId pb.jalandhar to him/her.

{
        "id": 24226,
        "uuid": "11t0e02b-0145-4de2-bc42-c97b96264807",
        "userName": "xyz",
        "name": "abc",
        "mobileNumber": "9999999999",
        "emailId": "abc@gmail.com",
        "locale": null,
        "type": "EMPLOYEE",
        "roles": [
            {
                "name": "Employee",
                "code": "EMPLOYEE",
                "tenantId": "pb.amritsar"
            },
            {
                "name": "TL Approver",
                "code": "TL_APPROVER",
                "tenantId": "pb.jalandhar"
            }
        ],
        "active": true,
        "tenantId": "pb.amritsar"
    }
  • If an employee has a role with a state-level tenantId he/she can perform actions corresponding to that role across all tenants.

  • Refresh token: Whenever the /user/oauth/token is called to generate the access_token, along with the access_token one more token is generated called refresh_token. The refresh token is used to generate a new access_token whenever the existing one expires. Till the refresh token is valid, the user will not have to login even if his/her access_token gets expired as it will be generated using refresh_token. The validity time of the refresh token is configurable and can be configured using the property: refresh.token.validity.in.minutes

User Data Privacy

MDMS configuration for security policy

{
  "tenantId": "pb",
  "moduleName": "DataSecurity",
  "SecurityPolicy": [
    {
      "model": "User",
      "uniqueIdentifier": {
        "name": "uuid",
        "jsonPath": "uuid"
      },
      "attributes": [
        {
          "name": "name",
          "jsonPath": "name",
          "patternId": "002",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "mobileNumber",
          "jsonPath": "mobileNumber",
          "patternId": "001",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "emailId",
          "jsonPath": "emailId",
          "patternId": "004",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "username",
          "jsonPath": "username",
          "patternId": "002",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "altContactNumber",
          "jsonPath": "altContactNumber",
          "patternId": "001",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "alternatemobilenumber",
          "jsonPath": "alternatemobilenumber",
          "patternId": "001",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "pan",
          "jsonPath": "pan",
          "patternId": "001",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "aadhaarNumber",
          "jsonPath": "aadhaarNumber",
          "patternId": "001",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "guardian",
          "jsonPath": "guardian",
          "patternId": "002",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "permanentAddress",
          "jsonPath": "permanentAddress/address",
          "patternId": "003",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "correspondenceAddress",
          "jsonPath": "correspondenceAddress/address",
          "patternId": "003",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "fatherOrHusbandName",
          "jsonPath": "fatherOrHusbandName",
          "patternId": "002",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "searchUsername",
          "jsonPath": "userName",
          "patternId": "002",
          "defaultVisibility": "PLAIN"
        }
      ],
      "roleBasedDecryptionPolicy": [
        {
          "roles": [
            "PGR_LME",
            "GRO"
          ],
          "attributeAccessList": [
            {
              "attribute": "name",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "mobileNumber",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "username",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "permanentAddress",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            }
          ]
        },
        {
          "roles": [
            "TLCEMP"
          ],
          "attributeAccessList": [
            {
              "attribute": "mobileNumber",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            }
          ]
        }
      ]
    },
    {
      "model": "UserSelf",
      "uniqueIdentifier": {
        "name": "uuid",
        "jsonPath": "uuid"
      },
      "attributes": [
        {
          "name": "name",
          "jsonPath": "name",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "mobileNumber",
          "jsonPath": "mobileNumber",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "emailId",
          "jsonPath": "emailId",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "username",
          "jsonPath": "username",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "altContactNumber",
          "jsonPath": "altContactNumber",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "alternatemobilenumber",
          "jsonPath": "alternatemobilenumber",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "pan",
          "jsonPath": "pan",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "aadhaarNumber",
          "jsonPath": "aadhaarNumber",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "guardian",
          "jsonPath": "guardian",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "permanentAddress",
          "jsonPath": "permanentAddress/address",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "correspondenceAddress",
          "jsonPath": "correspondenceAddress/address",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "fatherOrHusbandName",
          "jsonPath": "fatherOrHusbandName",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        }
      ],
      "roleBasedDecryptionPolicy": []
    }
  ]
}

There are two security policy model for user data: User and UserSelf. In model User, field attributes contain a list of fields from the User object that needs to be secured and field roleBasedDecryptionPolicy is an attribute-level role-based policy. It will define visibility for each attribute.

UserSelf model contains the same structure of security policy, but User security model is used for Search API response and UserSelf is used for Create/Update API response.

Visibility of the PII data is based on the above MDMS configuration. There are three types of visibility mentioned in the configuration:

  1. PLAIN - Show text in plain form.

  2. MASKED - The returned text will contain masked data. The masking pattern will be applied as defined in the Masking Patterns master data.

  3. NONE - The returned text will not contain any data. It would contain string like “Confidential Information”.

Plain access request

{
  "RequestInfo": {
    "plainAccessRequest": {
      "recordId": "d5ee3d45-13a1-4aa5-bd86-9b8dae34b900"
      "fields": [ "name", "mobileNumber" ]
    }
  }
}

Any user will be able to get plain access to the secured data (citizen’s PII) by requesting through the plainAccessRequest parameter. It takes the following parameters:

  1. recordId - It is the unique identifier of the record that is requested for plain access.

  2. fields - It defines a list of attributes that are requested for plain access.

To know more about the encryption policy, refer to document Encryption Service mentioned in the reference docs.

Reference Docs

Title

Link

User data encryption promotion details

Encryption Service

API List

Title

Link

/citizen/_create

/users/_createnovalidate

/_search

/v1/_search

/_details

/users/_updatenovalidate

/profile/_update

/password/_update

/password/nologin/_update

/_logout

/user/oauth/token

Note: All APIs are in the same postman collection, and hence, the same link has been added in each row.

Last updated

All content on this page by eGov Foundation is licensed under a Creative Commons Attribution 4.0 International License.