DIGIT Docs
  • DIGIT Knowledge Base
  • Local Governance
  • šŸ‘‹Introducing Local Governance
    • Release Notes
      • Master Migration Document
        • DIGIT SAAS Guideline - Central Instance
      • MDMS & Configuration Updates
      • Service Build Updates
      • Test Cases
      • Gate 2 Release Checklist
      • Implementation Checklist
      • Program Roll Out Plan
      • Product Release Notes
        • Property Tax System Release Notes
        • Residential Construction Permit System UI/UX Revamp Release Notes
        • Local Business License Issuing System - Release Notes
        • Water & Sanitation UI/UX Revamp Release Notes
        • Bill Amendment UI/UX Revamp Release Notes
        • Bill Genie UI/UX Revamp Release Notes
        • Birth & Death Reports Release Notes
        • National Dashboard Enhancement Release Notes
        • Survey Release Notes
        • Product Specific Pages Release Notes
  • Local Governance
    • Understanding Local Governance
    • Value Proposition
  • Local Governance Product Suite
    • Local Governance Stack
      • Local Business License Issuing System
        • Local Business License Issuing Module Functional Specifications
        • Local Business License Issuing User Manual
          • Business License - Citizen User Manual
            • Apply For New Trade Licence
            • Renew Trade License
            • View Application Status & Pay
          • Business License - Employee User Manual
            • Create Applications
            • Collect Payment
            • Renew Licence
            • Process Application
              • Verify Documents
              • Field Inspection
              • Approve Applications
          • TL Assessment Quiz
        • Local Business License - Master Data Templates
          • Trade Type
          • Trade Sub Type
          • Trade Category
          • Trade License Fee
          • Structure Type
          • Structure Sub Type
          • Trade License Document Attachment
        • Local Business License Service Configuration
          • Local Business License Issuing Service - Steps To Upload Data
          • Business License Calculator
          • Business License UI Configuration
            • Employee Inbox UI Details
            • Business License Renewal UI Flow
            • Send Back - Edit UI Flow
            • TL Apply Flow UI Details
            • My Applications UI Flow
            • Employee Search Application Search License UI Flow
            • New Trade License UI Flow
            • Application Details - Trade Details UI Flows
            • Renew Edit Application
        • Local Business License Issuing System Implementation Guide
      • Property Tax System
        • Property Tax System - Functional Specifications
        • Property Tax System - Product Requirements Document
          • Property Amalgamation
          • Capital Value System
          • Property Bifurcation
        • Property Tax System User Manual
          • Property Tax System Citizen User Manual
            • Register Property
            • Search & Pay
            • View My Bills
            • View My Payments
            • View My Properties
            • View My Applications
            • Update Property
            • Transfer Property Ownership
            • Update Mobile Number
            • Amalgamate Property
          • Property Tax System Employee User Manual
            • View Employee Inbox
            • Search Property
            • View Property Details
            • Search Application
            • Collect Property Tax
            • View Payment History
            • Register Property
            • Edit Property
            • Assess Property
            • Transfer Property Ownership
            • Edit Application
            • Reopen Application
            • Send Back Applications
            • Send Back To Citizen
            • Verify & Forward
            • Reject Applications
            • Approve Applications
        • Property Tax System Master Data Templates
          • Mutation Fee
          • Rebate Rates
          • Penalty Rates
          • Interest Rates
          • Tax Rates
          • Unit Rates
          • Special Category Documents
          • Owner Special Category
          • Ownership Sub Category
          • Ownership Category
          • Usage Category Detail
          • Road Type
          • Construction Type
          • Property Type
          • Property Sub Type
          • Usage Category Major
          • Usage Category Minor
          • Usage Category Sub Minor
        • Property Tax System Service Configuration
          • Property Mutation & Mutation Calculator
          • PT Update Number & Alternate Number
            • Update Primary Mobile Number & Alternate Mobile Number
          • Assessment of Property
          • PT Calculator
          • Fuzzy Search
            • Fuzzy Search Reindexing
          • Common PT
          • PT Privacy Changes
            • PT - Steps To Configure Privacy
          • PT - Create Property UI Details
            • Edit-Update Property
            • Property Tax - My Applications
            • Property Tax - My Properties
            • Property Tax - Search Applications
            • Property Tax - Quick Pay for Citizen
            • Property Tax - Search And Pay My Bills
            • Property Tax - My Payments
            • Create Application - Employee UI/UX Revamp
            • Employee Edit Application Flow
            • Employee - Search Property, Property Details Page & Assessment
            • Employee - Inbox & Application Details
            • Employee Inbox (Old UI)
            • Citizen Mutation Flow
            • Employee - Mutation (Ownership Transfer)
          • PT Data Migration
        • Property Tax System Implementation Guide
      • Water & Sewerage Connections
        • Water & Sewerage Connections Functional Specifications
        • Water & Sewerage Connections User Manual
          • Water & Sewerage Connections Citizen User Manual
            • Apply For New Connection
            • Pay Application Fees
            • View Application Details
            • Edit Application
            • View Connection Details
            • View Consumption Details
            • Search & Pay
            • View & Pay Bills
            • View Payment Details
            • Apply For Disconnection
          • Water & Sewerage Connections Employee User Manual
            • Apply For New Connections
            • Search Applications/Connections
            • Add Meter Readings
            • Activate New Connections
            • Collect Bill Payments
            • Modify Connection Details
            • Edit Applications
            • Send Applications Back To Citizen
            • Reject Applications
            • Verify & Forward Applications
            • Approve Connections
        • Water Charges Master Data Templates
          • Water Rates (Metered)
          • Pipe Size Types
          • Water Source Types
          • Water Rates (Non-Metered)
          • Water Penalty Rates
          • Water Interest Rates
        • Sewerage Charges Master Data Templates
          • Sewerage Rates
          • Sewerage Penalty Rates
          • Sewerage Interest Rates
        • Water Service Configuration
          • Legacy/Re-Indexing the Water & Sewerage Service
          • State DSS - Water & Sewerage
          • Water Calculator Service
          • Water Service Disconnection
          • Water Disconnection Calculator Service
          • Water & Sewerage Service UI Docs
            • Citizen: Disconnection Application Create
            • Citizen: My Connections
            • Citizen: Create Application
            • Citizen: My Applications
            • Employee: Application Details
            • Employee: Connection Details
            • Employee: Modify Create Flow
            • Employee: Modify Application Details
            • Employee: Disconnection Create Flow
            • Employee: Disconnection Application Details
            • Employee: Ad-hoc Rebate/Penalty & View Breakup
            • Privacy UI
          • Water & Sewerage Reports
          • Workflow Config-Replacement Data
          • Water & Sewerage Privacy Changes
            • W&S - Steps To Configure Privacy
          • Sewerage Service Configuration
            • Sewerage Service Disconnection
            • Sewerage Disconnection Calculator Service
            • Sewerage Calculator Service
        • Water & Sewerage Connections Implementation Guide
      • Citizen Complaint Resolution System
        • Citizen Complaint Resolution Module Functional Specifications
        • Citizen Complaint Resolution System Workflows
        • Complaint Types List
        • Citizen Complaint Resolution User Manual
          • Citizen Complaint Resolution Citizen User Manual
            • File Complaints
            • View/Track Complaints
            • Rate Complaints
            • Reopen Complaints
          • Citizen Complaint Resolution Employee User Manual
            • CSR - File Complaints
            • CSR - Search/Track Complaints
            • CSR - Reopen Complaints
            • GRO - Assign Complaints
            • GRO - Reassign Complaints
            • GRO - Share Complaints
            • GRO - Reject Complaints
            • FME - Request Reassign
            • FME - Resolve Complaints
          • Citizen Complaint Resolution Assessment Quiz
        • Citizen Complaint Resolution System Demo Script
        • Citizen Complaint Resolution System Master Data Templates
          • Grievance Type
          • Grievance Sub Type
          • Routing Matrix
          • Escalation Matrix
        • Citizen Complaint Resolution System Service Configuration
          • Citizen Complaint Resolution System Migration
      • Residential Construction Permit System
        • Residential Construction Permit System User Manual
          • Residential Construction Permit System Citizen User Manual
            • Register Stakeholders
            • View Application Status
            • Request Edits & Approve Applications
            • Make Payment
          • Residential Construction Permit System - Stakeholders User Manual
            • Register Other Stakeholders
            • Submit For DIGIT-DCR Scrutiny
            • Submit For OC Plan Scrutiny
            • Apply For Building Permits for New Construction
            • Apply For Occupancy Certificate
          • Residential Construction Permit System Employee User Manual
            • Send Applications Back To Citizens
            • Reject Application/Revoke Application
            • Verify & Forward Application
            • Prepare Inspection Report
            • Approve/Reject Applications
        • Residential Construction Permit System Demo Script
        • Residential Construction Permit Module Functional Specifications
        • Residential Construction Permit Service Configuration
          • Data Loading Steps For Residential Construction Permit System
          • BPA Service Configuration
          • BPA Stakeholder Registration
          • Legacy/Re-Indexing For OBPS
          • BPA Calculator Service
          • Setting Up eDCR Service
          • eDCR Integration
          • Noc Services
          • Land Services
          • State DSS - OBPS
          • OBPAS DIGIT UI
            • Stakeholder - Registration Flow
            • OBPS-BPA/OC-BPA Employee Flow
              • OBPS Inbox
              • OBPS Search Application
            • OBPS-BPA/OC-BPA Architect
            • OBPS EDCR /OC-EDCR
            • OBPS BPA / OCBPA Citizen
            • Employee - Stakeholder
              • Stakeholder Inbox
              • Stakeholder Search Application
        • Residential Construction Permit Master Data Templates
          • Fee Structure
          • NOC Departments
          • Stakeholders Type
          • List Of Services
          • Service-Wise Documents
          • Building Occupancy
          • Building Sub Occupancy
          • Building Usage
          • Inspection Checklist
          • Town Planning Schemes
        • Residential Construction Permit System Implementation Guide
      • mCollect - Demand-based Revenue Collection
        • mCollect Functional Specifications
        • mCollect User Manual
          • MCS Citizen User Manual
          • MCS Employee User Manual
        • mCollect Service Configuration
          • e-Challan Service
            • e-Challan Calculator Service
          • Re-Indexing The mCollect Service
          • State DSS - mCollect
          • Current Bill Cancellation UI Flow
            • Bill Details UI Flow
            • Cancel Bill UI Flow
          • Receipt Cancellation UI Flow
            • View Receipt - Cancel UI Flow
          • e-Challan UI Details
            • Edit - Cancel Challan
            • Search and Pay Challan
            • mCollect UI Flow
            • Update - Cancel Challan UI Flow
            • Challan Creation
        • mCollect Master Data Templates
          • Service Category
          • Service Sub Category
          • Service Sub Category GL Code Mapping
      • Faecal Sludge Management (FSM)
      • Finance
        • Finance Module Functional Specifications
        • Finance User Manual
          • Finance Employee User Manual
          • Admin User Manual
            • Finance Reports Manual
        • Finance Service Configuration
          • Finance Collections Voucher Consumer Service
        • Bill Genie Service Configuration
          • UI Configuration
            • Group Bills Screen
            • Employee Search Bills
            • Employee Group Bills
            • Employee Download Bill
        • Bill Amendment Service Configuration
          • UI Configuration
            • Employee: Bill Amendment - Create Flow
            • Employee: Bill Amendment - Search, Edit & Resubmit, Approve, Reject & Send-Back Flows
        • Billing And Payments Data Templates
          • Tax Heads
          • Receipt Format
          • Demand Bill Format
        • Finance Master Data Templates
          • Bank Account
          • Chart Of Accounts
          • Funds
          • Function
          • Contractors
          • Suppliers
          • Schemes
          • Sub Schemes
          • Banks
          • Bank Branch
          • Deduction
          • Opening Balances
          • Sub Ledger Category
          • Sub Ledger Master
        • Finance Implementation Guide
      • Fire Safety Certification (NOC)
        • Fire Safety Certification (NOC) Functional Specifications
        • Fire Safety Certification (NOC) User Manual
          • Fire Safety Certification (NOC) Citizen User Manual
            • Apply For Fire Safety Certificate (NOC)
            • Pay NOC Fees & View Application Status
          • Fire Safety Certification (NOC) Employee User Manual
            • Create New Application
            • View Application Status
            • Forward Applications
            • Reject Applications
            • Refer Applications
            • Send Back Applications
            • Approve Applications
            • Reject Applications
        • Fire Safety Certification (NOC) Service Configuration
          • Re-Indexing the Fire NOC Service
          • State DSS - Fire NOC
          • Fire NOC Calculator Service
          • NOC DIGIT UI
            • NOC Inbox
            • Application Overview
        • Fire Safety Certification (NOC) Master Data Templates
          • Building Usage Type
          • Building Sub Usage Type
          • Fire Station Master
          • Areas Served Master
          • Fire Station Mapping
          • Fire NOC Fee
      • Citizen Engagement Module
        • Consent Form Citizen User Manual
        • Feedback Rating Citizen User Manual
        • Survey
          • Survey User Manual
            • Survey Employee User Manual
            • Surveys Citizen User Manual
          • Survey Service Configuration
            • Help/FAQ Section - Citizen UI
            • Document Uploader Service
        • Documents: Implementation Details
        • Product Specific Pages
        • Citizen Engagement Configuration
          • Service Request
          • Citizen Feedback Service
          • Citizen Feedback UI
          • Citizen Consent Form UI
      • Birth & Death Certificate Issuance
        • Birth & Death Certificate Issuance User Manual
          • Birth & Death Citizen User Manual
          • Birth & Death Employee User Manual
        • Birth & Death Certificate Issuance Service Configuration
          • Birth and Death Service Setup
          • State DSS - Birth and Death
          • Birth and Death: Reports
      • Dashboards & Analytics
        • Dashboards & Analytics User Manual
        • Dashboards & Analytics Functional Specifications
        • Dashboards & Analytics Service Configuration
          • Dashboards - UI Configuration
            • Dashboards - About & FAQs
            • Dashboards - UI Flow
          • New KPIs
          • KPIs: Pendancy, Citizen Feedback & SLA Changes
          • National Dashboards & Analytics Configuration
          • State Dashboards & Analytics Configuration
          • National Dashboard Ingest Service
            • National Dashboard Adaptor Service
          • W&S - National Dashboard
          • Property Tax - National Dashboard
          • Fire NOC - National Dashboard
          • Trade License - National Dashboard
          • OBPS - National Dashboard
          • PGR - National Dashboard
          • mCollect National Dashboard
          • National Dashboard API Performance Testing and Benchmark
          • National Dashboard: Index Creation Steps
        • DSS Configuration And Setup
          • Building New Dashboards
        • DSS Data Templates
          • KPI Acceptance
      • HRMS
        • HRMS Functional Specifications
        • HRMS Service Configuration
          • HRMS UI Configuration
            • HRMS Employee Create-Edit UI Flow
            • Employee Details UI Flow
            • Employee Activation-Deactivation UI Flow
            • Search Employee By Multiple Criteria UI Flow
            • Employees Count UI Flow
            • Auto Escalation UI Flow
        • HRMS Data Templates
          • User Roles
          • System Users
  • Technology
    • Architecture
      • Specifications
    • Building Blocks & Services
    • Security
      • Security Guidelines
  • Setup
    • Implementation Plan
    • Installation
    • Configuration
      • Git Repos
      • Setting up Master Data
        • MDMS Overview
        • Configuring Tenants
        • Configuring Master Data
        • Adding New Master
        • State Level Vs City Level Master
      • Master Data Collection Templates
        • Environment Setup
          • State Level Setup
            • Tenants Information
            • SMS Account Configuration
            • Email Account Configuration
            • Google Play Store Account
            • Payment Gateway Configuration
            • POS Integration Configuration
            • Domain Name Configuration
            • SSL Configuration
            • ULB Departments
            • ULB Designations
            • Localization
            • Google Map Configuration
          • ULB Level Setup
            • Boundary Hierarchies
            • Boundary Data
            • Cross Hierarchy Mapping
            • ULB Bank Accounts
        • Module Setup
          • Web Portals Templates
            • State Portal
            • ULB Portal
          • Workflow Data Templates
            • Workflow Actions
            • Workflow Levels
            • Workflow Process
          • Common Configuration Details
            • Standard Document List
            • Checklist
            • Configuring Data FAQs
      • Configuring DIGIT Service Stack
        • Core Services
        • Business Service
          • Appropriation Service
          • Billing Service
            • Bill Amendment Service Configuration
          • Collection Service
            • Collection Service Migration
            • Collection Service V2
          • Billing Collection Integration
          • Dashboard Analytics - Backend
            • DSS Features Enhancements
            • DSS Dashboard - Technical Document for UI
            • DSS Technical Documentation
          • Steps For Migration Process
        • Municipal Service
          • Turn-Io-Adapter
          • Inbox Service
      • Configuring Urban Services
        • Central Instance Configuration
          • UI Build Preparation For New Instance
        • Configuring Common Services
          • Deployment Of App on Play Store
          • Mapping Roles With APIs
          • Setting up a Language
            • Adding New Language
            • Setting Up Default Language For SMS & Emails
          • Setting Up Service Locally
          • Adding Roles To System
          • Adding New APIs For Access
          • User Events Services
          • SMS Template Approval Process
          • DIGIT: Internal Datamart Deployment Steps
          • Customizing PDF Notices And Certificates
            • Integration Of PDF In UI For Download And Print PDF
            • Customizing PDF Receipts & Certificates
          • Notification Enhancement For Different Channels
        • Common UI Docs
          • Events & Notifications UI Docs
            • Employee Flow - Events
            • Employee Flow - Messages
            • Citizen Flow
          • Navigation Between Old & New UI
          • User Profile
            • Citizen Profile
            • Employee Profile
            • Employee City Change
          • Update Number & Invalid Number
          • Troubleshoot Using Browser Network Tab
      • QA Automation
        • Kafka Consumer Producer Approach
        • Jenkins Setup for Automation
        • Automation Framework Knowledge Base
          • Automation Test Tags
          • Automation Test Reporting
        • State-Level UI Customization
    • Customization
      • Writing A New Customer
      • Enhancing Existing Service
    • Operational Support
      • eGov Enablement Support
      • Partner Program Guide
  • General
    • Access DIGIT
    • Partner Toolkit
      • Infra Calculator
      • Resource Calculator
    • Training Resources
      • Training Videos
      • Technical Enablement Areas
      • eDCR Training Plan
    • Source Code
    • Roadmap
Powered by GitBook

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

On this page
  • Overview
  • Pre-requisites
  • MDMS Changes
  • Backend Service Changes
  • Application Properties Changes
  • Important Methods To Be Added In Service
  • Encryption of Old Data In The DB
  • Re-indexing Old Data In Base Indexes
  • Enabling / Disabling Privacy

Was this helpful?

Export as PDF
  1. Local Governance Product Suite
  2. Local Governance Stack
  3. Property Tax System
  4. Property Tax System Service Configuration

PT Privacy Changes

Backend technical documentation

Overview

This document highlights the changes that need to be done in a Property module to support the privacy feature.

Pre-requisites

  • Prior Knowledge of Java/J2EE.

  • Prior Knowledge of Spring Boot.

  • MDMS Service

  • Encryption Service

MDMS Changes

Update the SecurityPolicy.json file.

The Security Policy MDMS file must have the model configuration for fields to be encrypted/decrypted. The following models have been used for W&S in SecurityPolicy.json file:

    {
      "model": "Property",
      "uniqueIdentifier": {
        "name": "uuid",
        "jsonPath": "/owners/0/uuid"
      },
      "attributes": [
        {
          "name": "street",
          "jsonPath": "address/street",
          "patternId": "005",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "doorNo",
          "jsonPath": "address/doorNo",
          "patternId": "005",
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "landmark",
          "jsonPath": "address/landmark",
          "patternId": "005",
          "defaultVisibility": "PLAIN"
        }
      ],
      "roleBasedDecryptionPolicy": [
        {
          "roles": ["WS_CEMP","WS_DOC_VERIFIER","WS_FIELD_INSPECTOR","WS_APPROVER","WS_CLERK","SW_CEMP","SW_DOC_VERIFIER","SW_FIELD_INSPECTOR","SW_APPROVER","SW_CLERK","PT_APPROVER", "PT_CEMP", "PT_COLLECTION_EMP", "PT_FIELD_INSPECTOR", "PT_DOC_VERIFIER"],
          "attributeAccessList": [
            {
              "attribute": "street",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "doorNo",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "landmark",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            }
          ]
        },
        {
          "roles": ["REINDEXING_ROLE"],
          "attributeAccessList": [
            {
              "attribute": "street",
              "firstLevelVisibility": "ENCRYPTED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "doorNo",
              "firstLevelVisibility": "ENCRYPTED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "landmark",
              "firstLevelVisibility": "ENCRYPTED",
              "secondLevelVisibility": "PLAIN"
            }
          ]
        }
      ]
    },
    {
      "model": "PropertyDecrypDisabled",
      "uniqueIdentifier": {
        "name": "propertyId",
        "jsonPath": "/propertyId"
      },
      "attributes": [
        {
          "name": "street",
          "jsonPath": "address/street",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "doorNo",
          "jsonPath": "address/doorNo",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        },
        {
          "name": "landmark",
          "jsonPath": "address/landmark",
          "patternId": null,
          "defaultVisibility": "PLAIN"
        }
      ],
      "roleBasedDecryptionPolicy": []
    },

Next, add the following (if not already there) under roleBasedDecryptionPolicy of User model (already existing):

"roleBasedDecryptionPolicy": [
        {
          "roles": ["REINDEXING_ROLE"],
          "attributeAccessList": [
            {
              "attribute": "mobileNumber",
              "firstLevelVisibility": "ENCRYPTED",
              "secondLevelVisibility": "PLAIN"
            }
          ]
        },
        {
          "roles": ["WS_CEMP","WS_DOC_VERIFIER","WS_FIELD_INSPECTOR","WS_APPROVER","WS_CLERK","SW_CEMP","SW_DOC_VERIFIER","SW_FIELD_INSPECTOR","SW_APPROVER","SW_CLERK"
          ],
          "attributeAccessList": [
            {
              "attribute": "mobileNumber",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "fatherOrHusbandName",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "correspondenceAddress",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "name",
              "firstLevelVisibility": "PLAIN",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "emailId",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "permanentAddress",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            },
            {
              "attribute": "guardian",
              "firstLevelVisibility": "MASKED",
              "secondLevelVisibility": "PLAIN"
            }
          ]
        }
     ]      

2.) For Property we have a model Property which is for Address fields like street, doorNo, landmark encryption and decryption.

NOTE: For adding of new attribute for encryption, the following things need to be kept in mind:

We do not have a direct approach to it, but a workaround is as follows:

  1. We need to make sure which property has to be encrypted and what is the path of the property in the Request/Response object of Property. We can add a new property to the existing model Property. The inclusion of any new attribute here would need encryption of the old data for this new property. For that, in MDMS, we will have to replace the existing model attributes with only new attributes and hit the _encryptOldData API. Once old data encryption is done, we can put back all the required attributes (old and +new) in the model. Also, before starting the encryption of old data, we will have to check the latest record of the table eg_pt_enc_audit. If the latest record has offset and record count value other than 0 then insert a random record with offset and record count as 0 and createdtime and encryptiontime as a current timestamp in millis in utc.

Backend Service Changes

Update the pom.xml file.

  • Upgrade services-common library version.

<dependency>
    <groupId>org.egov.services</groupId>
    <artifactId>services-common</artifactId>
    <version>1.1.0-SNAPSHOT</version>
</dependency>
  • Upgrade the tracer library version.

<dependency>
    <groupId>org.egov.services</groupId>
    <artifactId>tracer</artifactId>
    <version>2.0.0-SNAPSHOT</version>
</dependency>
  • Add enc-client library

<dependency>
	<groupId>org.egov</groupId>
		<artifactId>enc-client</artifactId>
		<version>2.0.4-SNAPSHOT</version>
		<exclusions>
			<exclusion>
				<groupId>org.springframework.kafka</groupId>
				<artifactId>spring-kafka</artifactId>
			</exclusion>
			<exclusion>
				<groupId>org.apache.kafka</groupId>
				<artifactId>kafka-clients</artifactId>
			</exclusion>
		</exclusions>
</dependency>

Application Properties Changes

In property-services encryption and decryption endpoints should be declared as follows:

#--------enable/disable ABAC in encryption----------#
property.decryption.abac.enabled=true

encryption.batch.value=500
encryption.offset.value=0

#-------Persister topics for oldDataEncryption-------#
property.oldDataEncryptionStatus.topic=pt-enc-audit
persister.update.property.oldData.topic=update-property-encryption
persister.update.property.audit.oldData.topic=update-property-audit-enc
persister.save.property.fuzzy.topic=save-property-fuzzy-data

Now, update the following existing property in application-properties: property.es.index=pt-fuzzy-search-index

EncryptionDecryptionUtil.java:

We need an interfacing file for handling the encryption and decryption of attributes and for interacting with enc-client library directly.

For reference follow the below code snippet

package org.egov.pt.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import lombok.extern.slf4j.Slf4j;
import org.egov.common.contract.request.RequestInfo;
import org.egov.common.contract.request.Role;
import org.egov.common.contract.request.User;
import org.egov.encryption.EncryptionService;
import org.egov.encryption.audit.AuditService;
import org.egov.pt.config.PropertyConfiguration;
import org.egov.tracer.model.CustomException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.ResourceAccessException;

import java.io.IOException;
import java.util.*;

@Slf4j
@Component
public class EncryptionDecryptionUtil {

    private EncryptionService encryptionService;

    @Autowired
    private PropertyConfiguration config;

    @Autowired
    private AuditService auditService;

    @Autowired
    private ObjectMapper objectMapper;

    @Value(("${state.level.tenant.id}"))
    private String stateLevelTenantId;

    @Value(("${property.decryption.abac.enabled}"))
    private boolean abacEnabled;
    public EncryptionDecryptionUtil(EncryptionService encryptionService) {
        this.encryptionService = encryptionService;
    }

    public <T> T encryptObject(Object objectToEncrypt, String key, Class<T> classType) {
        try {
            if (objectToEncrypt == null) {
                return null;
            }
            T encryptedObject = encryptionService.encryptJson(objectToEncrypt, key, config.getStateLevelTenantId(), classType);
            if (encryptedObject == null) {
                throw new CustomException("ENCRYPTION_NULL_ERROR", "Null object found on performing encryption");
            }
            return encryptedObject;
        } catch (Exception e) {
            log.error("Unknown Error occurred while encrypting", e);
            throw new CustomException("UNKNOWN_ERROR", "Unknown error occurred in encryption process");
        }
    }

    public <E, P> P decryptObject(Object objectToDecrypt, String key, Class<E> classType, RequestInfo requestInfo) {

        try {
            boolean objectToDecryptNotList = false;
            if (objectToDecrypt == null) {
                return null;
            }

           if (!(objectToDecrypt instanceof List)) {
                objectToDecryptNotList = true;
                objectToDecrypt = Collections.singletonList(objectToDecrypt);
            }

            Map<String, String> keyPurposeMap = getKeyToDecrypt(objectToDecrypt);
            String purpose = keyPurposeMap.get("PropertyEncDisabledSearch");

            if(key.equalsIgnoreCase(PTConstants.PROPERTY_MODEL))
                key = keyPurposeMap.get("key");

            P decryptedObject = (P) encryptionService.decryptJson(requestInfo, objectToDecrypt, key, purpose, classType);

            if (decryptedObject == null) {
                throw new CustomException("DECRYPTION_NULL_ERROR", "Null object found on performing decryption");
            }

            if (objectToDecryptNotList) {
                decryptedObject = (P) ((List<E>) decryptedObject).get(0);
            }
            return decryptedObject;
        } catch (IOException | HttpClientErrorException | HttpServerErrorException | ResourceAccessException e) {
            log.error("Error occurred while decrypting", e);
            throw new CustomException("DECRYPTION_SERVICE_ERROR", "Error occurred in decryption process");
        } catch (Exception e) {
            log.error("Unknown Error occurred while decrypting", e);
            throw new CustomException("UNKNOWN_ERROR", "Unknown error occurred in decryption process");
        }
    }

    /**
     * Setting a fake user Info in case of open API calls
     * 
     * @param requestInfo
     * @return
     */
	private RequestInfo copyRequestInfoForEncryption(RequestInfo requestInfo) {
		
		RequestInfo requestInfoForDecryption;
		User fakeUSerInfo = User.builder().uuid("no uuid").type("EMPLOYEE").build();
		
		if ( requestInfo != null ) {
			
			 requestInfoForDecryption = RequestInfo.builder()
		    			.correlationId(requestInfo.getCorrelationId())
		    			.authToken(requestInfo.getAuthToken())
		    			.apiId(requestInfo.getApiId())
		    			.msgId(requestInfo.getMsgId())
		    			.build();
			 
				if (requestInfo.getUserInfo() == null)
					requestInfoForDecryption.setUserInfo(fakeUSerInfo);
				else
					requestInfoForDecryption.setUserInfo(requestInfo.getUserInfo());

		} else {
			
			requestInfoForDecryption = RequestInfo.builder().
					userInfo(fakeUSerInfo)
					.build();
		}
		

		return requestInfoForDecryption;
	}

	private User getEncrichedandCopiedUserInfo(User userInfo) {

		List<Role> newRoleList = new ArrayList<>();
		Boolean isUserTypeRoleFound = false;
		List<Role> roles = userInfo.getRoles();

		if (!CollectionUtils.isEmpty(roles)) {

			for (Role role : roles) {

				if (role.getCode().equalsIgnoreCase(userInfo.getType()))
					isUserTypeRoleFound = true;

                Role newRole = Role.builder()
                		.tenantId(role.getTenantId())
                		.code(role.getCode())
                		.name(role.getName())
                		.id(role.getId())
                		.build();
                
                newRoleList.add(newRole);
            }
        }

        if (!isUserTypeRoleFound) {
        	
            Role roleFromtype = Role.builder()
            		.tenantId(userInfo.getTenantId())
            		.code(userInfo.getType())
            		.name(userInfo.getType())
            		.build();
            newRoleList.add(roleFromtype);
        }
        
        return User.builder()
        		.roles(newRoleList)
        		.id(userInfo.getId())
        		.name(userInfo.getName())
                .type(userInfo.getType())
                .uuid(userInfo.getUuid())
                .emailId(userInfo.getEmailId())
                .userName(userInfo.getUserName())
                .tenantId(userInfo.getTenantId())
                .mobileNumber(userInfo.getMobileNumber())
                .build();
    }

    public Map<String,String> getKeyToDecrypt(Object objectToDecrypt) {
        Map<String,String> keyPurposeMap = new HashMap<>();

        if (!abacEnabled){
            keyPurposeMap.put("key","PropertyDecrypDisabled");
            keyPurposeMap.put("purpose","AbacDisabled");
        }
        else{
            keyPurposeMap.put("key","Property");
            keyPurposeMap.put("purpose","PropertySearch");
        }

        return keyPurposeMap;
    }
}

UnmaskingUtil.java:

UnmaskingUtil.java file helps in extracting the plain data of the owner from the user service.

For reference follow the below code snippet

package org.egov.pt.util;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.egov.common.contract.request.PlainAccessRequest;
import org.egov.common.contract.request.RequestInfo;
import org.egov.pt.models.Address;
import org.egov.pt.models.OwnerInfo;
import org.egov.pt.models.Property;
import org.egov.pt.models.PropertyCriteria;
import org.egov.pt.models.user.UserDetailResponse;
import org.egov.pt.models.user.UserSearchRequest;
import org.egov.pt.service.PropertyService;
import org.egov.pt.service.UserService;
import org.egov.pt.validator.PropertyValidator;
import org.egov.pt.web.contracts.PropertyRequest;
import org.egov.tracer.model.CustomException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

@Component
public class UnmaskingUtil {
	
	private static List<String> ownerPlainRequestFieldsList;
	

	@Autowired
	private UserService userService;
	
	@Autowired 
	private PropertyService service;
	
	@Autowired
	private PropertyValidator validator;
	
	public Property getPropertyUnmasked(PropertyRequest request) {
		
		Property propertyFromRequest = request.getProperty(); 
        PropertyCriteria criteria = validator.getPropertyCriteriaForSearch(request);
        List<Property> propertiesFromSearchResponse = service.searchProperty(criteria, request.getRequestInfo());
		if (CollectionUtils.isEmpty(propertiesFromSearchResponse)) {
			throw new CustomException("EG_PT_PROPERTY_NOT_FOUND", "The property to be updated does not exist in the system");
		}
		Property propertyFromSearch = propertiesFromSearchResponse.get(0);
		
		Address addressFromRequest = propertyFromRequest.getAddress();
		
		if (null != addressFromRequest.getDoorNo() && addressFromRequest.getDoorNo().contains("*"))
			addressFromRequest.setDoorNo(propertyFromSearch.getAddress().getDoorNo());
		if (null != addressFromRequest.getStreet() && addressFromRequest.getStreet().contains("*"))
			addressFromRequest.setStreet(propertyFromSearch.getAddress().getStreet());
		if (null != addressFromRequest.getLandmark() && addressFromRequest.getLandmark().contains("*"))
			addressFromRequest.setLandmark(propertyFromSearch.getAddress().getLandmark());
		
		
		getOwnerDetailsUnmasked(request.getProperty(), request.getRequestInfo());
		return propertyFromSearch;
	}
	
	public void getOwnerDetailsUnmasked (Property property, RequestInfo requestInfo) {
		
		PlainAccessRequest apiPlainAccessRequest = requestInfo.getPlainAccessRequest();
		
		List<String> plainRequestFieldsList = getAllFieldsPlainAccessList();
		PlainAccessRequest plainAccessRequest = PlainAccessRequest.builder()
				.plainRequestFields(plainRequestFieldsList)
				.build();
		requestInfo.setPlainAccessRequest(plainAccessRequest);
		
		UserSearchRequest userSearchRequest = userService.getBaseUserSearchRequest(property.getTenantId(), requestInfo);
		
		Set<String> ownerIds = new HashSet<>();
		
		for (OwnerInfo ownerInfo : property.getOwners()) {
			
			String currentOwnerId = ownerInfo.getUuid();
			if(currentOwnerId == null)
				continue;
			
			/*
			 * once user module is updated to handle masked update 
			 * users will be unmasked on need, currently all. 
			 */
			ownerIds.clear();
			ownerIds.add(currentOwnerId);
			userSearchRequest.setUuid(ownerIds);
			plainAccessRequest.setRecordId(currentOwnerId);

			UserDetailResponse userDetailResponse = userService.getUser(userSearchRequest);

			OwnerInfo unmaskedUser = userDetailResponse.getUser().get(0);
			updateMaskedOwnerInfoWithUnmaskedFields(ownerInfo, unmaskedUser);
			requestInfo.setPlainAccessRequest(apiPlainAccessRequest);
		}

	}

	private void updateMaskedOwnerInfoWithUnmaskedFields(OwnerInfo ownerInfo, OwnerInfo unmaskedUser) {

		if (!StringUtils.isEmpty(ownerInfo.getFatherOrHusbandName()) && ownerInfo.getFatherOrHusbandName().contains("*")) {
			ownerInfo.setFatherOrHusbandName(unmaskedUser.getFatherOrHusbandName());
		}
		if (ownerInfo.getMobileNumber().contains("*")) {
			ownerInfo.setMobileNumber(unmaskedUser.getMobileNumber());
		}
		
		if (ownerInfo.getPermanentAddress() != null 
				&& ownerInfo.getPermanentAddress().contains("*")) {
			ownerInfo.setPermanentAddress(unmaskedUser.getPermanentAddress());
		}
		
		if (ownerInfo.getCorrespondenceAddress() != null 
				&& ownerInfo.getCorrespondenceAddress().contains("*")) {
			ownerInfo.setCorrespondenceAddress(unmaskedUser.getCorrespondenceAddress());
		}
		if (!StringUtils.isEmpty(ownerInfo.getUserName()) && ownerInfo.getUserName().contains("*")) {
			ownerInfo.setUserName(unmaskedUser.getUserName());
		}
		if (!StringUtils.isEmpty(ownerInfo.getName()) &&  ownerInfo.getName().contains("*")) {
			ownerInfo.setName(unmaskedUser.getName());
		}
		if (!StringUtils.isEmpty(ownerInfo.getGender()) && ownerInfo.getGender().contains("*")) {
			ownerInfo.setGender(unmaskedUser.getGender());
		}
	}

	public static List<String> getAllFieldsPlainAccessList() {

		if (ownerPlainRequestFieldsList == null) {
			
			ownerPlainRequestFieldsList = new ArrayList<>();
			ownerPlainRequestFieldsList.add("mobileNumber");
			ownerPlainRequestFieldsList.add("guardian");
			ownerPlainRequestFieldsList.add("fatherOrHusbandName");
			ownerPlainRequestFieldsList.add("correspondenceAddress");
			ownerPlainRequestFieldsList.add("userName");
			ownerPlainRequestFieldsList.add("name");
			ownerPlainRequestFieldsList.add("gender");
		}
		return ownerPlainRequestFieldsList;
	}
}

Important Methods To Be Added In Service

If you want to get all the PII data in the plain format then in the search request add the search param ā€œisSearchInternalā€œ as ā€œtrueā€

If the user wants only specific fields to be unmasked then add the plainAccessRequest in the RequestBody in the following format:

{
    "RequestInfo": {
        "apiId": "Rainmaker",
        "authToken": "03df03a9-58c4-47a7-96eb-e745570ac6b7",
        "userInfo": {
            "id": 12105,
            "uuid": "6d29df57-c2bd-4fd5-ab6c-2815749ebff8",
            "userName": "QAWSSU",
            "name": "Lata Naik",
            "mobileNumber": "9090909091",
            "emailId": "lata@gmail.com",
            "locale": null,
            "type": "EMPLOYEE",
            "roles": [
                {
                    "name": "PT Doc Verifier",
                    "code": "PT_DOC_VERIFIER",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "WS Document Verifier",
                    "code": "WS_DOC_VERIFIER",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "SW Field Inspector",
                    "code": "SW_FIELD_INSPECTOR",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "SW Document Verifier",
                    "code": "SW_DOC_VERIFIER",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "PT Counter Employee",
                    "code": "PT_CEMP",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "WS Approver",
                    "code": "WS_APPROVER",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "PT Counter Approver",
                    "code": "PT_APPROVER",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "PT Field Inspector",
                    "code": "PT_FIELD_INSPECTOR",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "WS Counter Employee",
                    "code": "WS_CEMP",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "SW Counter Employee",
                    "code": "SW_CEMP",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "SW Clerk",
                    "code": "SW_CLERK",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "WS Field Inspector",
                    "code": "WS_FIELD_INSPECTOR",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "WS Clerk",
                    "code": "WS_CLERK",
                    "tenantId": "pb.amritsar"
                },
                {
                    "name": "SW Approver",
                    "code": "SW_APPROVER",
                    "tenantId": "pb.amritsar"
                }
            ],
            "active": true,
            "tenantId": "pb.amritsar",
            "permanentCity": null
        },
        "msgId": "1667459745751|en_IN",
        "plainAccessRequest": {
            "recordId": "e7989e70-b5cc-4361-8837-64f47bd297b5",
            "plainRequestFields": [
                "street","doorNo","landmark"
            ]
        }
    }
}

plainAccessRequest contains :

  1. recordId which will take the uuid of the user as an input for which PII data has to be unmasked, and

  2. plainRequestFields will take an array of attributes that need to be unmasked. These attributes should comply with the attributes used in the Mdms SecurityPolicy.json’s models created.

Encryption of Old Data In The DB

Before using the privacy feature in any environment the encryption of existing data in the dB should be done.

An API for the same is written in the service and needs to be triggered by port-forwarding the respective service pod.

The data encryption API uses the existing plainSearch method and the encryption shall take place tenantId-wise. If tenantId is not specified then all the tenants are picked from the MDMS repository and the encryption happens for all the tenants. However, if the tenantId is specified, then the encryption happens only for that tenantId.

The following method is added to execute the oldDataEncryption

In PropertyController.java

/**
     * Encrypts existing property records
     *
     * @param requestInfoWrapper RequestInfoWrapper
     * @param propertyCriteria PropertyCriteria
     * @return list of updated encrypted data
     */
    /* To be executed only once */
    @RequestMapping(value = "/_encryptOldData", method = RequestMethod.POST)
    public ResponseEntity<PropertyResponse> encryptOldData(@Valid @RequestBody RequestInfoWrapper requestInfoWrapper,
                                                         @Valid @ModelAttribute PropertyCriteria propertyCriteria) {
        propertyCriteria.setIsRequestForOldDataEncryption(Boolean.TRUE);
        List<Property> properties = propertyEncryptionService.updateOldData(propertyCriteria, requestInfoWrapper.getRequestInfo());
        PropertyResponse response = PropertyResponse.builder().properties(properties).responseInfo(
                        responseInfoFactory.createResponseInfoFromRequestInfo(requestInfoWrapper.getRequestInfo(), true))
                .build();
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

Re-indexing Old Data In Base Indexes

There is no need to re-indexing the base indexes(viz. property-services) once the API for old data encryption is executed as this will happen during the API execution itself. For any new data getting created, the new data will get saved in the encrypted format only in the indexes.

When talking about privacy changes, we would need 2 additional indexes to be added. both of them would be the copy of existing indexes. 1. A fuzzy index: Copy of index config under existing save topic

Enabling / Disabling Privacy

To enable or disable decryption in privacy, we need to make changes to only the privacy variable present in the environment file in DevOps. For enabling, its value should be ā€œtrueā€ else ā€œfalseā€.

For property-services:

property-decryption-abac-enabled: "true"

For user-service:

decryption-abac-enabled: "true"

Note: Privacy decryption means: For any new application creation/ old application updation Internal data will be stored in the encrypted form itself, just that during decryption disabled it would give PLAIN text rather than masked one.

All the above changes need to be done for sw-services as well.

PreviousCommon PTNextPT - Steps To Configure Privacy

Was this helpful?

Refer to the file for full reference.

For modules, there is no such hard rule or pattern for naming the model, but it should be related to that service. ex: 1.) For user service we have two security policy models which is used when a user tries to search other user data and he/she will get the PII data in masked, plain or encrypted form depending on the visibility sets for an attribute in the MDMS. And another model is which is used when a user tries to search their own data, they get the data as per the configuration set there. For report and searcher config the model name should be similar to the value that we are setting in the field decryptionPathId. ex:- .

For an attribute where its firstLevelVisibility is set as "Masked" and whenever the respective search API is called without the plain Access Request then in the API response for that attribute we will get the masked value for ex:- if for mobile number attribute’s firstLevelVisibility is masked and its plain value is 9089243280 then in response, we will get value as ******3280 and the masking pattern is defined in the MDMS file and the pattern is picked up based on patternId. Similarly, if firstLevelVisibility is set as "ENCRYPTED" we will get the encrypted value of that plain data (which is present in DB) in the response.

For further info about adding models refer

You may find the file in the repo.

You may find the file in the repo.

In PropertyEncryptionService.java This service is solely for old data encryption and can be referred from here:

A new persister file needs to be added for keeping track of the progress of oldDataEncryption. Refer to this for the same.

Here is the Postman collection for all property, water and sewerage services for old Data encryption :

Reference:

2. An index for Old data encryption: Copy of index config under existing update topic Reference:

The variable can be found in the file .

For detailed steps to configure the above changes refer to the document: .

SecurityPolicy.json
User
UserSelf
Employee Report
Employee Report Security Model
MaskingPattern
here
here
here
PropertyEncryptionService.java
pt-enc-audit-persister.yml
https://www.getpostman.com/collections/b3858ec2020462a6407d
here
Detailed Steps to configure privacy in Property module
[UM-5579]- Added property fuzzy search topic and index in property-se… Ā· egovernments/configs@5399adb
Enc-Property indexer and persister changes by hinamakhija-eGov Ā· Pull Request #2516 Ā· egovernments/configs