merge feature/update_code and feature/Backend-MFA-Product branch code
This commit is contained in:
@@ -664,3 +664,11 @@ fineract.openproject.api-token=${FINERACT_OPENPROJECT_API_TOKEN:57dd9f933f113c72
|
||||
|
||||
# ── DIP / MNRL Mobile Number Lookup ──────────────────────────────────────────
|
||||
fineract.mobile-lookup.base-url=${FINERACT_MOBILE_LOOKUP_BASE_URL:http://localhost:8080}
|
||||
# ── Email Configuration ──────────────────────────────────────────────────────
|
||||
spring.mail.host=${FINERACT_EMAIL_SMTP_HOST:smtp.gmail.com}
|
||||
spring.mail.port=${FINERACT_EMAIL_SMTP_PORT:587}
|
||||
spring.mail.username=${FINERACT_EMAIL_SMTP_USERNAME:}
|
||||
spring.mail.password=${FINERACT_EMAIL_SMTP_PASSWORD:}
|
||||
spring.mail.properties.mail.smtp.auth=true
|
||||
spring.mail.properties.mail.smtp.starttls.enable=true
|
||||
spring.mail.properties.mail.debug=false
|
||||
|
||||
@@ -294,4 +294,18 @@
|
||||
<include file="parts/0280_add_fixed_deposit_product_codes.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0284_remove_product_code_unique_constraints.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0281_update_fd_base_interest_rate_seed_data.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0278_add_soft_delete_to_family_members.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0279_add_soft_delete_columns_client_tables.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0280_add_deletion_audit_and_version_columns.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0281_normalize_audit_columns.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0282_create_m_otp_log.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0283_add_mobile_to_m_appuser.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0284_otp_log_support_email.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0285_create_m_user_mfa_factor.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0286_drop_obsolete_mobile_number_from_m_appuser.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0287_mfa_factor_enforcement_config.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0288_add_disabled_by_to_m_user_mfa_factor.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0289_seed_read_otp_log_permission.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0290_create_otp_log_auditor_role.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0291_grant_read_otp_log_to_bankadmin_roles.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!-- Soft-delete flags for family members. is_active=true / is_deleted=false by default. -->
|
||||
<changeSet id="0278_add_is_active_is_deleted_to_family_members" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_family_members" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_family_members">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0278_index_family_members_active" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><indexExists tableName="m_family_members" indexName="idx_m_family_members_client_active"/></not>
|
||||
</preConditions>
|
||||
<createIndex tableName="m_family_members" indexName="idx_m_family_members_client_active">
|
||||
<column name="client_id"/>
|
||||
<column name="is_deleted"/>
|
||||
</createIndex>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Standardise soft-delete flags across all user-editable client detail tables.
|
||||
Default state for a row: is_active=TRUE, is_deleted=FALSE.
|
||||
On removal/unlink: is_active=FALSE, is_deleted=TRUE.
|
||||
Read services must filter `WHERE is_deleted = false`.
|
||||
|
||||
Tables that already have `is_active` only get `is_deleted`.
|
||||
Tables that have neither get both.
|
||||
|
||||
Skipped intentionally:
|
||||
- m_client (uses status_enum / sub_status state machine)
|
||||
- m_client_transaction (financial; reverse, don't delete)
|
||||
- m_client_kyc_verification_log, m_client_transfer_details, m_client_attendance (immutable audit logs)
|
||||
- m_ckyc_batch (uses its own `status` field)
|
||||
-->
|
||||
|
||||
<!-- 1. Tables that already have is_active — add is_deleted only -->
|
||||
<changeSet id="0279a_is_deleted_client_address" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_address" columnName="is_deleted"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_address">
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279b_is_deleted_client_nominee" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_nominee" columnName="is_deleted"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_nominee">
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279c_is_deleted_client_charge" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_charge" columnName="is_deleted"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_charge">
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- 2. Tables that have neither — add both -->
|
||||
<changeSet id="0279d_flags_client_non_person" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_non_person" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_non_person">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279e_flags_client_identifier" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_identifier" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_identifier">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279f_flags_client_kyc" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_kyc" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_kyc">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279g_flags_address" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_address" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_address">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279h_flags_client_priority_sector" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_priority_sector" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_priority_sector">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279i_flags_client_non_priority_sector" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_non_priority_sector" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_non_priority_sector">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279j_flags_client_msme" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_msme" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_msme">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279k_flags_client_mudra_borrower" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_mudra_borrower" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_mudra_borrower">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279l_flags_client_startup_india" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_startup_india" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_startup_india">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279m_flags_client_eou" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_eou" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_eou">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279n_flags_client_charge_paid_by" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_charge_paid_by" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_charge_paid_by">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0279o_flags_client_collateral_management" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_client_collateral_management" columnName="is_active"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_client_collateral_management">
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Adds deletion-audit columns and an optimistic-locking version column to the
|
||||
16 client-related tables already covered by 0278/0279 soft-delete columns.
|
||||
|
||||
- deleted_by BIGINT — FK-style m_appuser.id (matching existing created_by/last_modified_by style)
|
||||
- deleted_at TIMESTAMP — when the soft-delete happened
|
||||
- version BIGINT NOT NULL DEFAULT 0 — used by JPA @Version for optimistic locking
|
||||
|
||||
Maker-checker is intentionally NOT modeled per-row. Use the existing
|
||||
m_portfolio_command_source framework + m_permission.can_maker_checker.
|
||||
-->
|
||||
|
||||
<changeSet id="0280a_deletion_audit_family_members" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_family_members" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_family_members">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280b_deletion_audit_client_address" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_address" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_address">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280c_deletion_audit_client_nominee" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_nominee" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_nominee">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280d_deletion_audit_client_charge" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_charge" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_charge">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280e_deletion_audit_client_non_person" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_non_person" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_non_person">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280f_deletion_audit_client_identifier" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_identifier" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_identifier">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280g_deletion_audit_client_kyc" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_kyc" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_kyc">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280h_deletion_audit_address" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_address" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_address">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280i_deletion_audit_client_priority_sector" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_priority_sector" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_priority_sector">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280j_deletion_audit_client_non_priority_sector" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_non_priority_sector" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_non_priority_sector">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280k_deletion_audit_client_msme" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_msme" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_msme">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280l_deletion_audit_client_mudra_borrower" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_mudra_borrower" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_mudra_borrower">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280m_deletion_audit_client_startup_india" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_startup_india" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_startup_india">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280n_deletion_audit_client_eou" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_eou" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_eou">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280o_deletion_audit_client_charge_paid_by" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_charge_paid_by" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_charge_paid_by">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0280p_deletion_audit_client_collateral_management" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_collateral_management" columnName="deleted_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_collateral_management">
|
||||
<column name="deleted_by" type="bigint"/>
|
||||
<column name="deleted_at" type="datetime"/>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0"><constraints nullable="false"/></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Normalises audit column names across the 16 client-related tables to:
|
||||
created_by BIGINT (FK-style → m_appuser.id; matches existing platform pattern)
|
||||
created_at TIMESTAMP
|
||||
modified_by BIGINT (FK-style)
|
||||
modified_on TIMESTAMP
|
||||
|
||||
Group A — already had columns under different names (renamed):
|
||||
last_modified_by → modified_by
|
||||
created_on_utc → created_at
|
||||
last_modified_on_utc → modified_on
|
||||
created_by → unchanged (already correctly named)
|
||||
|
||||
Group B — entities extend AbstractPersistableCustom and had no audit columns;
|
||||
these are added fresh and populated via Spring Data JPA auditing.
|
||||
|
||||
Note: types are BIGINT (user IDs) to stay consistent with the rest of the
|
||||
platform's existing audit. JOIN m_appuser to fetch usernames in reports.
|
||||
-->
|
||||
|
||||
<!-- =========================== Group A: rename =========================== -->
|
||||
|
||||
<changeSet id="0281a_rename_audit_client_nominee" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><columnExists tableName="m_client_nominee" columnName="last_modified_by"/></preConditions>
|
||||
<renameColumn tableName="m_client_nominee" oldColumnName="last_modified_by" newColumnName="modified_by" columnDataType="bigint"/>
|
||||
<renameColumn tableName="m_client_nominee" oldColumnName="created_on_utc" newColumnName="created_at" columnDataType="datetime"/>
|
||||
<renameColumn tableName="m_client_nominee" oldColumnName="last_modified_on_utc" newColumnName="modified_on" columnDataType="datetime"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281b_rename_audit_client_identifier" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><columnExists tableName="m_client_identifier" columnName="last_modified_by"/></preConditions>
|
||||
<renameColumn tableName="m_client_identifier" oldColumnName="last_modified_by" newColumnName="modified_by" columnDataType="bigint"/>
|
||||
<renameColumn tableName="m_client_identifier" oldColumnName="created_on_utc" newColumnName="created_at" columnDataType="datetime"/>
|
||||
<renameColumn tableName="m_client_identifier" oldColumnName="last_modified_on_utc" newColumnName="modified_on" columnDataType="datetime"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281c_rename_audit_client_kyc" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><columnExists tableName="m_client_kyc" columnName="last_modified_by"/></preConditions>
|
||||
<renameColumn tableName="m_client_kyc" oldColumnName="last_modified_by" newColumnName="modified_by" columnDataType="bigint"/>
|
||||
<renameColumn tableName="m_client_kyc" oldColumnName="created_on_utc" newColumnName="created_at" columnDataType="datetime"/>
|
||||
<renameColumn tableName="m_client_kyc" oldColumnName="last_modified_on_utc" newColumnName="modified_on" columnDataType="datetime"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281d_rename_audit_client_priority_sector" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><columnExists tableName="m_client_priority_sector" columnName="last_modified_by"/></preConditions>
|
||||
<renameColumn tableName="m_client_priority_sector" oldColumnName="last_modified_by" newColumnName="modified_by" columnDataType="bigint"/>
|
||||
<renameColumn tableName="m_client_priority_sector" oldColumnName="created_on_utc" newColumnName="created_at" columnDataType="datetime"/>
|
||||
<renameColumn tableName="m_client_priority_sector" oldColumnName="last_modified_on_utc" newColumnName="modified_on" columnDataType="datetime"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281e_rename_audit_client_non_priority_sector" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><columnExists tableName="m_client_non_priority_sector" columnName="last_modified_by"/></preConditions>
|
||||
<renameColumn tableName="m_client_non_priority_sector" oldColumnName="last_modified_by" newColumnName="modified_by" columnDataType="bigint"/>
|
||||
<renameColumn tableName="m_client_non_priority_sector" oldColumnName="created_on_utc" newColumnName="created_at" columnDataType="datetime"/>
|
||||
<renameColumn tableName="m_client_non_priority_sector" oldColumnName="last_modified_on_utc" newColumnName="modified_on" columnDataType="datetime"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281f_rename_audit_client_msme" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><columnExists tableName="m_client_msme" columnName="last_modified_by"/></preConditions>
|
||||
<renameColumn tableName="m_client_msme" oldColumnName="last_modified_by" newColumnName="modified_by" columnDataType="bigint"/>
|
||||
<renameColumn tableName="m_client_msme" oldColumnName="created_on_utc" newColumnName="created_at" columnDataType="datetime"/>
|
||||
<renameColumn tableName="m_client_msme" oldColumnName="last_modified_on_utc" newColumnName="modified_on" columnDataType="datetime"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281g_rename_audit_client_mudra_borrower" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><columnExists tableName="m_client_mudra_borrower" columnName="last_modified_by"/></preConditions>
|
||||
<renameColumn tableName="m_client_mudra_borrower" oldColumnName="last_modified_by" newColumnName="modified_by" columnDataType="bigint"/>
|
||||
<renameColumn tableName="m_client_mudra_borrower" oldColumnName="created_on_utc" newColumnName="created_at" columnDataType="datetime"/>
|
||||
<renameColumn tableName="m_client_mudra_borrower" oldColumnName="last_modified_on_utc" newColumnName="modified_on" columnDataType="datetime"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281h_rename_audit_client_startup_india" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><columnExists tableName="m_client_startup_india" columnName="last_modified_by"/></preConditions>
|
||||
<renameColumn tableName="m_client_startup_india" oldColumnName="last_modified_by" newColumnName="modified_by" columnDataType="bigint"/>
|
||||
<renameColumn tableName="m_client_startup_india" oldColumnName="created_on_utc" newColumnName="created_at" columnDataType="datetime"/>
|
||||
<renameColumn tableName="m_client_startup_india" oldColumnName="last_modified_on_utc" newColumnName="modified_on" columnDataType="datetime"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281i_rename_audit_client_eou" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><columnExists tableName="m_client_eou" columnName="last_modified_by"/></preConditions>
|
||||
<renameColumn tableName="m_client_eou" oldColumnName="last_modified_by" newColumnName="modified_by" columnDataType="bigint"/>
|
||||
<renameColumn tableName="m_client_eou" oldColumnName="created_on_utc" newColumnName="created_at" columnDataType="datetime"/>
|
||||
<renameColumn tableName="m_client_eou" oldColumnName="last_modified_on_utc" newColumnName="modified_on" columnDataType="datetime"/>
|
||||
</changeSet>
|
||||
|
||||
<!-- =========================== Group B: add ============================ -->
|
||||
|
||||
<changeSet id="0281j_add_audit_family_members" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_family_members" columnName="created_at"/></not></preConditions>
|
||||
<addColumn tableName="m_family_members">
|
||||
<column name="created_by" type="bigint"/>
|
||||
<column name="created_at" type="datetime"/>
|
||||
<column name="modified_by" type="bigint"/>
|
||||
<column name="modified_on" type="datetime"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281k_add_audit_client_address" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_address" columnName="created_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_address">
|
||||
<column name="created_by" type="bigint"/>
|
||||
<column name="created_at" type="datetime"/>
|
||||
<column name="modified_by" type="bigint"/>
|
||||
<column name="modified_on" type="datetime"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- m_address intentionally skipped: it already has manual audit columns (created_by VARCHAR,
|
||||
created_on DATE, updated_by VARCHAR, updated_on DATE) populated by service code. -->
|
||||
|
||||
<changeSet id="0281m_add_audit_client_charge" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_charge" columnName="created_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_charge">
|
||||
<column name="created_by" type="bigint"/>
|
||||
<column name="created_at" type="datetime"/>
|
||||
<column name="modified_by" type="bigint"/>
|
||||
<column name="modified_on" type="datetime"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281n_add_audit_client_non_person" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_non_person" columnName="created_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_non_person">
|
||||
<column name="created_by" type="bigint"/>
|
||||
<column name="created_at" type="datetime"/>
|
||||
<column name="modified_by" type="bigint"/>
|
||||
<column name="modified_on" type="datetime"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281o_add_audit_client_charge_paid_by" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_charge_paid_by" columnName="created_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_charge_paid_by">
|
||||
<column name="created_by" type="bigint"/>
|
||||
<column name="created_at" type="datetime"/>
|
||||
<column name="modified_by" type="bigint"/>
|
||||
<column name="modified_on" type="datetime"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0281p_add_audit_client_collateral_management" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><columnExists tableName="m_client_collateral_management" columnName="created_at"/></not></preConditions>
|
||||
<addColumn tableName="m_client_collateral_management">
|
||||
<column name="created_by" type="bigint"/>
|
||||
<column name="created_at" type="datetime"/>
|
||||
<column name="modified_by" type="bigint"/>
|
||||
<column name="modified_on" type="datetime"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Audit log for OTP generation/verification. One row per OTP issued.
|
||||
Used by login 2FA (LincPay provider) and extensible to other purposes.
|
||||
-->
|
||||
<changeSet id="0282_create_m_otp_log" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><tableExists tableName="m_otp_log"/></not></preConditions>
|
||||
<createTable tableName="m_otp_log">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
|
||||
<column name="purpose" type="VARCHAR(30)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="provider" type="VARCHAR(30)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
|
||||
<column name="user_id" type="BIGINT"/>
|
||||
<column name="username" type="VARCHAR(100)"/>
|
||||
<column name="mobile_number" type="VARCHAR(20)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
|
||||
<column name="otp_reference" type="VARCHAR(100)"/>
|
||||
<column name="otp_hash" type="VARCHAR(255)"/>
|
||||
|
||||
<column name="status" type="VARCHAR(20)" defaultValue="PENDING">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="attempts" type="INT" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
|
||||
<column name="ip_address" type="VARCHAR(45)"/>
|
||||
<column name="user_agent" type="VARCHAR(500)"/>
|
||||
|
||||
<column name="request_payload" type="LONGTEXT"/>
|
||||
<column name="response_payload" type="LONGTEXT"/>
|
||||
<column name="error_message" type="VARCHAR(1000)"/>
|
||||
|
||||
<column name="expires_at" type="datetime"/>
|
||||
<column name="verified_at" type="datetime"/>
|
||||
|
||||
<column name="is_active" type="boolean" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_deleted" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="version" type="bigint" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
|
||||
<column name="created_by" type="BIGINT"/>
|
||||
<column name="created_at" type="datetime"/>
|
||||
<column name="modified_by" type="BIGINT"/>
|
||||
<column name="modified_on" type="datetime"/>
|
||||
</createTable>
|
||||
|
||||
<createIndex tableName="m_otp_log" indexName="idx_m_otp_log_user_status">
|
||||
<column name="user_id"/>
|
||||
<column name="status"/>
|
||||
</createIndex>
|
||||
|
||||
<createIndex tableName="m_otp_log" indexName="idx_m_otp_log_otp_reference">
|
||||
<column name="otp_reference"/>
|
||||
</createIndex>
|
||||
|
||||
<createIndex tableName="m_otp_log" indexName="idx_m_otp_log_mobile_purpose">
|
||||
<column name="mobile_number"/>
|
||||
<column name="purpose"/>
|
||||
</createIndex>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!-- Mobile number on m_appuser — used by login OTP (2FA) lookup. Nullable; populated at user create time. -->
|
||||
<changeSet id="0283_add_mobile_no_to_m_appuser" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_appuser" columnName="mobile_no"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_appuser">
|
||||
<column name="mobile_no" type="VARCHAR(16)"/>
|
||||
</addColumn>
|
||||
<createIndex tableName="m_appuser" indexName="idx_m_appuser_mobile_no">
|
||||
<column name="mobile_no"/>
|
||||
</createIndex>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!-- Make m_otp_log work for both SMS-OTP and email-OTP. -->
|
||||
|
||||
<changeSet id="0284_otp_log_mobile_number_nullable" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<columnExists tableName="m_otp_log" columnName="mobile_number"/>
|
||||
</preConditions>
|
||||
<dropNotNullConstraint tableName="m_otp_log" columnName="mobile_number" columnDataType="VARCHAR(20)"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0284_otp_log_add_email_address" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_otp_log" columnName="email_address"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_otp_log">
|
||||
<column name="email_address" type="VARCHAR(255)"/>
|
||||
</addColumn>
|
||||
<createIndex tableName="m_otp_log" indexName="idx_m_otp_log_email_purpose">
|
||||
<column name="email_address"/>
|
||||
<column name="purpose"/>
|
||||
</createIndex>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Persists which MFA factors a given AppUser has enrolled and verified.
|
||||
One row per (appuser_id, factor_type). Soft-disable via disabled_on.
|
||||
-->
|
||||
<changeSet id="0285_create_m_user_mfa_factor" author="fineract">
|
||||
<preConditions onFail="MARK_RAN"><not><tableExists tableName="m_user_mfa_factor"/></not></preConditions>
|
||||
<createTable tableName="m_user_mfa_factor">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="appuser_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="factor_type" type="VARCHAR(20)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="destination" type="VARCHAR(255)"/>
|
||||
<column name="secret" type="VARCHAR(64)"/>
|
||||
<column name="serial" type="VARCHAR(64)"/>
|
||||
<column name="verified" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="verified_on" type="datetime"/>
|
||||
<column name="otp_log_id" type="BIGINT"/>
|
||||
<column name="created_on" type="datetime" defaultValueComputed="CURRENT_TIMESTAMP">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="disabled_on" type="datetime"/>
|
||||
</createTable>
|
||||
|
||||
<addUniqueConstraint tableName="m_user_mfa_factor" columnNames="appuser_id, factor_type"
|
||||
constraintName="uq_user_factor"/>
|
||||
|
||||
<addForeignKeyConstraint baseTableName="m_user_mfa_factor" baseColumnNames="appuser_id"
|
||||
constraintName="fk_mfa_factor_user"
|
||||
referencedTableName="m_appuser" referencedColumnNames="id"/>
|
||||
|
||||
<addForeignKeyConstraint baseTableName="m_user_mfa_factor" baseColumnNames="otp_log_id"
|
||||
constraintName="fk_mfa_factor_otp"
|
||||
referencedTableName="m_otp_log" referencedColumnNames="id"/>
|
||||
|
||||
<createIndex tableName="m_user_mfa_factor" indexName="idx_mfa_factor_user_active">
|
||||
<column name="appuser_id"/>
|
||||
<column name="disabled_on"/>
|
||||
</createIndex>
|
||||
</changeSet>
|
||||
|
||||
<!-- Permissions: list, register, disable factor (Self Service flow) -->
|
||||
<changeSet id="0285_seed_user_mfa_permissions" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'READ_USER_MFA_FACTORS'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="special"/>
|
||||
<column name="code" value="READ_USER_MFA_FACTORS"/>
|
||||
<column name="entity_name" value="USER_MFA_FACTOR"/>
|
||||
<column name="action_name" value="READ"/>
|
||||
<column name="can_maker_checker" valueBoolean="false"/>
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="special"/>
|
||||
<column name="code" value="CREATE_USER_MFA_FACTOR"/>
|
||||
<column name="entity_name" value="USER_MFA_FACTOR"/>
|
||||
<column name="action_name" value="CREATE"/>
|
||||
<column name="can_maker_checker" valueBoolean="false"/>
|
||||
</insert>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="special"/>
|
||||
<column name="code" value="DELETE_USER_MFA_FACTOR"/>
|
||||
<column name="entity_name" value="USER_MFA_FACTOR"/>
|
||||
<column name="action_name" value="DELETE"/>
|
||||
<column name="can_maker_checker" valueBoolean="false"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<!-- Grant the new permissions to the Self Service User role (id resolved by name to keep portable). -->
|
||||
<changeSet id="0285_grant_mfa_permissions_to_self_service_role" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="1">SELECT COUNT(*) FROM m_role WHERE name = 'Self Service User'</sqlCheck>
|
||||
</preConditions>
|
||||
<sql>
|
||||
INSERT INTO m_role_permission (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM m_role r, m_permission p
|
||||
WHERE r.name = 'Self Service User'
|
||||
AND p.code IN ('READ_USER_MFA_FACTORS', 'CREATE_USER_MFA_FACTOR', 'DELETE_USER_MFA_FACTOR')
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM m_role_permission rp
|
||||
WHERE rp.role_id = r.id AND rp.permission_id = p.id
|
||||
)
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
m_appuser ended up with both `mobile_number` (legacy from an earlier version of 0283) and
|
||||
`mobile_no` (current). The Java code uses `mobile_no` exclusively. This migration:
|
||||
1. Backfills `mobile_no` from `mobile_number` for any row where `mobile_no` is NULL
|
||||
but `mobile_number` has a value, so we don't lose data.
|
||||
2. Drops the now-unused `idx_m_appuser_mobile_number` index.
|
||||
3. Drops the `mobile_number` column.
|
||||
-->
|
||||
|
||||
<changeSet id="0286_backfill_mobile_no_from_mobile_number" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<columnExists tableName="m_appuser" columnName="mobile_number"/>
|
||||
<columnExists tableName="m_appuser" columnName="mobile_no"/>
|
||||
</and>
|
||||
</preConditions>
|
||||
<sql>
|
||||
UPDATE m_appuser
|
||||
SET mobile_no = mobile_number
|
||||
WHERE mobile_no IS NULL
|
||||
AND mobile_number IS NOT NULL
|
||||
AND mobile_number <> ''
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0286_drop_index_idx_m_appuser_mobile_number" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<indexExists tableName="m_appuser" indexName="idx_m_appuser_mobile_number"/>
|
||||
</preConditions>
|
||||
<dropIndex tableName="m_appuser" indexName="idx_m_appuser_mobile_number"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0286_drop_mobile_number_from_m_appuser" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<columnExists tableName="m_appuser" columnName="mobile_number"/>
|
||||
</preConditions>
|
||||
<dropColumn tableName="m_appuser" columnName="mobile_number"/>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Global kill-switch for MFA-factor-backed login enforcement.
|
||||
- DEFAULT: disabled. Existing users are unaffected on first deploy.
|
||||
- When enabled, AuthenticationApiResource will challenge any user that
|
||||
has at least one verified, non-disabled row in m_user_mfa_factor.
|
||||
- Flip enabled=true in c_configuration to roll out; flip back to false
|
||||
to roll back instantly without a redeploy.
|
||||
-->
|
||||
<changeSet id="0287_seed_mfa_factor_enforcement_config" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM c_configuration WHERE name = 'mfa-factor-enforcement'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="c_configuration">
|
||||
<column name="name" value="mfa-factor-enforcement"/>
|
||||
<column name="enabled" valueBoolean="false"/>
|
||||
<column name="is_trap_door" valueBoolean="false"/>
|
||||
<column name="description"
|
||||
value="When enabled, users with at least one verified MFA factor in m_user_mfa_factor are required to complete a 2FA challenge after password authentication."/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<!--
|
||||
Pre-flight: grant BYPASS_TWO_FACTOR to the Super user role so an admin
|
||||
can always log in even if MFA delivery is broken (LincPay outage, SMTP
|
||||
misconfig, etc.). Idempotent — only inserts if missing.
|
||||
-->
|
||||
<changeSet id="0287_grant_bypass_twofactor_to_super_user" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="1">SELECT COUNT(*) FROM m_role WHERE name = 'Super user'</sqlCheck>
|
||||
</preConditions>
|
||||
<sql>
|
||||
INSERT INTO m_role_permission (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM m_role r, m_permission p
|
||||
WHERE r.name = 'Super user'
|
||||
AND p.code = 'BYPASS_TWO_FACTOR'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM m_role_permission rp
|
||||
WHERE rp.role_id = r.id AND rp.permission_id = p.id
|
||||
)
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Audit symmetry with our other soft-delete/disable patterns: capture WHO disabled the
|
||||
factor, not just WHEN. Useful when admins disable a user's factor (future support) or
|
||||
for compliance trails — paired with the existing disabled_on column.
|
||||
-->
|
||||
<changeSet id="0288_add_disabled_by_to_m_user_mfa_factor" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><columnExists tableName="m_user_mfa_factor" columnName="disabled_by"/></not>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_user_mfa_factor">
|
||||
<column name="disabled_by" type="BIGINT"/>
|
||||
</addColumn>
|
||||
<addForeignKeyConstraint baseTableName="m_user_mfa_factor" baseColumnNames="disabled_by"
|
||||
constraintName="fk_mfa_factor_disabled_by"
|
||||
referencedTableName="m_appuser" referencedColumnNames="id"/>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!-- Admin-only read access to the m_otp_log audit trail. -->
|
||||
<changeSet id="0289_seed_read_otp_log_permission" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_permission WHERE code = 'READ_OTP_LOG'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_permission">
|
||||
<column name="grouping" value="special"/>
|
||||
<column name="code" value="READ_OTP_LOG"/>
|
||||
<column name="entity_name" value="OTP_LOG"/>
|
||||
<column name="action_name" value="READ"/>
|
||||
<column name="can_maker_checker" valueBoolean="false"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<!-- Grant to Super user so admins can immediately use the new endpoint. -->
|
||||
<changeSet id="0289_grant_read_otp_log_to_super_user" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="1">SELECT COUNT(*) FROM m_role WHERE name = 'Super user'</sqlCheck>
|
||||
</preConditions>
|
||||
<sql>
|
||||
INSERT INTO m_role_permission (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM m_role r, m_permission p
|
||||
WHERE r.name = 'Super user'
|
||||
AND p.code = 'READ_OTP_LOG'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM m_role_permission rp
|
||||
WHERE rp.role_id = r.id AND rp.permission_id = p.id
|
||||
)
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Dedicated single-purpose role that grants READ access to the m_otp_log audit trail.
|
||||
Sized small on purpose so admins can attach it to specific users (compliance auditors,
|
||||
bank admins, support staff) without giving them the full Super user privileges.
|
||||
|
||||
The bankadmin assignment is environment-specific data — it's wrapped in a precondition so
|
||||
the migration is a no-op on installs where that user doesn't exist.
|
||||
-->
|
||||
|
||||
<!-- 1) Create the role -->
|
||||
<changeSet id="0290_create_otp_log_auditor_role" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_role WHERE name = 'OTP Log Auditor'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="m_role">
|
||||
<column name="name" value="OTP Log Auditor"/>
|
||||
<column name="description" value="Read-only access to the OTP audit trail (m_otp_log). Pair with users who need to inspect OTP send/verify history without having Super user rights."/>
|
||||
<column name="is_disabled" valueBoolean="false"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
<!-- 2) Grant READ_OTP_LOG to the role -->
|
||||
<changeSet id="0290_grant_read_otp_log_to_otp_log_auditor" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<sqlCheck expectedResult="1">SELECT COUNT(*) FROM m_role WHERE name = 'OTP Log Auditor'</sqlCheck>
|
||||
<sqlCheck expectedResult="1">SELECT COUNT(*) FROM m_permission WHERE code = 'READ_OTP_LOG'</sqlCheck>
|
||||
</and>
|
||||
</preConditions>
|
||||
<sql>
|
||||
INSERT INTO m_role_permission (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM m_role r, m_permission p
|
||||
WHERE r.name = 'OTP Log Auditor'
|
||||
AND p.code = 'READ_OTP_LOG'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM m_role_permission rp
|
||||
WHERE rp.role_id = r.id AND rp.permission_id = p.id
|
||||
)
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
<!-- 3) Assign role to 'bankadmin' if that user exists in this environment.
|
||||
This block is intentionally environment-aware — fresh installs without a bankadmin
|
||||
user will skip silently (preCondition onFail=MARK_RAN). -->
|
||||
<changeSet id="0290_assign_otp_log_auditor_to_bankadmin" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<sqlCheck expectedResult="1">SELECT COUNT(*) FROM m_appuser WHERE username = 'bankadmin'</sqlCheck>
|
||||
<sqlCheck expectedResult="1">SELECT COUNT(*) FROM m_role WHERE name = 'OTP Log Auditor'</sqlCheck>
|
||||
</and>
|
||||
</preConditions>
|
||||
<sql>
|
||||
INSERT INTO m_appuser_role (appuser_id, role_id)
|
||||
SELECT u.id, r.id
|
||||
FROM m_appuser u, m_role r
|
||||
WHERE u.username = 'bankadmin'
|
||||
AND r.name = 'OTP Log Auditor'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM m_appuser_role ur
|
||||
WHERE ur.appuser_id = u.id AND ur.role_id = r.id
|
||||
)
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Direct grant: attach READ_OTP_LOG to every role the 'bankadmin' user already holds.
|
||||
|
||||
Migration 0290 created a dedicated 'OTP Log Auditor' role and linked it to bankadmin,
|
||||
which is the clean approach. This migration is a parallel, belt-and-braces grant that
|
||||
also adds the permission to bankadmin's *existing* roles (Bank Admin, etc.) so the
|
||||
OTP Audit Logs screen works without anyone toggling checkboxes in Manage Roles UI.
|
||||
|
||||
Idempotent via NOT EXISTS — safe to re-run. No-op on installs without a 'bankadmin' user.
|
||||
-->
|
||||
<changeSet id="0291_grant_read_otp_log_to_bankadmin_roles" author="fineract">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<sqlCheck expectedResult="1">SELECT COUNT(*) FROM m_appuser WHERE username = 'bankadmin'</sqlCheck>
|
||||
<sqlCheck expectedResult="1">SELECT COUNT(*) FROM m_permission WHERE code = 'READ_OTP_LOG'</sqlCheck>
|
||||
</and>
|
||||
</preConditions>
|
||||
<sql>
|
||||
INSERT INTO m_role_permission (role_id, permission_id)
|
||||
SELECT ur.role_id, p.id
|
||||
FROM m_appuser u
|
||||
JOIN m_appuser_role ur ON ur.appuser_id = u.id
|
||||
CROSS JOIN m_permission p
|
||||
WHERE u.username = 'bankadmin'
|
||||
AND p.code = 'READ_OTP_LOG'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM m_role_permission rp
|
||||
WHERE rp.role_id = ur.role_id AND rp.permission_id = p.id
|
||||
)
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
Reference in New Issue
Block a user