Compare commits

..

10 Commits

Author SHA1 Message Date
Naeem Ullah 9c7f195e98 Merge pull request 'User Permission Management' (#4) from Wasi-BS/1676 into FMFI-PRE-PRODUCTION
Reviewed-on: https://ct.mfsys.com.pk/aConnect/aConnect-BS/pulls/4
9 hours ago
Wasiullah Khan a0529f9b34 User Permission Management 1 day ago
Naeem Ullah 162678d8d9 Rename econnect module to aconnect
All files and references for the 'econnect' module have been renamed to 'aconnect', including source, test files, and module references in the parent POM. This standardizes the module naming across the project.
1 week ago
Naeem Ullah 16ef541e30 Merge branch 'FMFI-PRE-PRODUCTION' of https://ct.mfsys.com.pk/aConnect/aConnect-BS into FMFI-PRE-PRODUCTION 1 week ago
Naeem Ullah 3a475a595d Update pom.xml 1 week ago
Naeem Ullah e54acd9a61 Merge pull request 'Add ptrTrancode to DTOs and update config files' (#3) from FMFI-PRE-PRODUCTION-PROFILING into FMFI-PRE-PRODUCTION
Reviewed-on: https://ct.mfsys.com.pk/aConnect/aConnect-BS/pulls/3
1 week ago
Naeem Ullah 40cc1f1597 Add ptrTrancode to DTOs and update config files
Added the ptrTrancode field to AccountGLTransactionRequest and GLtoGLRequest DTOs. Updated Maven build to include spring-boot-maven-plugin with profile support. Cleaned up and simplified environment-specific application properties, moving most configuration to environment variables and reducing duplication.
1 week ago
Mubashar Hussain 01d3c23103 Merge pull request 'security module- login screen' (#1) from SecurityModuleChanges into FMFI-PRE-PRODUCTION
Reviewed-on: https://ct.mfsys.com.pk/aConnect/aConnect-BS/pulls/1
3 weeks ago
Wasiullah Khan 173663d935 security module- login screen 3 weeks ago
Naeem Ullah fc07a8e88f Base Architecture
Base Architecture
3 weeks ago

33
.gitignore vendored

@ -0,0 +1,33 @@
HELP.md
target/
.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf

@ -0,0 +1,33 @@
HELP.md
target/
.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

@ -0,0 +1,2 @@
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

295
aconnect/mvnw vendored

@ -0,0 +1,295 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# 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
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.3.3
#
# Optional ENV vars
# -----------------
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
# MVNW_REPOURL - repo url base for downloading maven distribution
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN* | MINGW*)
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
native_path() { cygpath --path --windows "$1"; }
;;
esac
# set JAVACMD and JAVACCMD
set_java_home() {
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
if [ -n "${JAVA_HOME-}" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACCMD="$JAVA_HOME/jre/sh/javac"
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACCMD="$JAVA_HOME/bin/javac"
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
return 1
fi
fi
else
JAVACMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v java
)" || :
JAVACCMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v javac
)" || :
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
return 1
fi
fi
}
# hash string like Java String::hashCode
hash_string() {
str="${1:-}" h=0
while [ -n "$str" ]; do
char="${str%"${str#?}"}"
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
str="${str#?}"
done
printf %x\\n $h
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
die() {
printf %s\\n "$1" >&2
exit 1
}
trim() {
# MWRAPPER-139:
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
# Needed for removing poorly interpreted newline sequences when running in more
# exotic environments such as mingw bash on Windows.
printf "%s" "${1}" | tr -d '[:space:]'
}
scriptDir="$(dirname "$0")"
scriptName="$(basename "$0")"
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
case "${key-}" in
distributionUrl) distributionUrl=$(trim "${value-}") ;;
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
esac
done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
*)
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
distributionPlatform=linux-amd64
;;
esac
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
;;
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
trap clean HUP INT TERM EXIT
else
die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
distributionUrl="${distributionUrl%.zip}.tar.gz"
distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
verbose "Found wget ... using wget"
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
verbose "Found curl ... using curl"
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
verbose "Falling back to use Java to download"
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
cat >"$javaSource" <<-END
public class Downloader extends java.net.Authenticator
{
protected java.net.PasswordAuthentication getPasswordAuthentication()
{
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
}
public static void main( String[] args ) throws Exception
{
setDefault( new Downloader() );
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
}
}
END
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
verbose " - Compiling Downloader.java ..."
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
verbose " - Running Downloader.java ..."
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
distributionSha256Result=false
if [ "$MVN_CMD" = mvnd.sh ]; then
echo "Checksum validation is not supported for maven-mvnd." >&2
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
elif command -v sha256sum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
distributionSha256Result=true
fi
elif command -v shasum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
fi
if [ $distributionSha256Result = false ]; then
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
exit 1
fi
fi
# unzip and move
if command -v unzip >/dev/null; then
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
# Find the actual extracted directory name (handles snapshots where filename != directory name)
actualDistributionDir=""
# First try the expected directory name (for regular distributions)
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
actualDistributionDir="$distributionUrlNameMain"
fi
fi
# If not found, search for any directory with the Maven executable (for snapshots)
if [ -z "$actualDistributionDir" ]; then
# enable globbing to iterate over items
set +f
for dir in "$TMP_DOWNLOAD_DIR"/*; do
if [ -d "$dir" ]; then
if [ -f "$dir/bin/$MVN_CMD" ]; then
actualDistributionDir="$(basename "$dir")"
break
fi
fi
done
set -f
fi
if [ -z "$actualDistributionDir" ]; then
verbose "Contents of $TMP_DOWNLOAD_DIR:"
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
die "Could not find Maven distribution directory in extracted archive"
fi
verbose "Found extracted Maven distribution directory: $actualDistributionDir"
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
clean || :
exec_maven "$@"

189
aconnect/mvnw.cmd vendored

@ -0,0 +1,189 @@
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.3.3
@REM
@REM Optional ENV vars
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
$MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
$MAVEN_M2_PATH = "$HOME/.m2"
if ($env:MAVEN_USER_HOME) {
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
}
if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
}
$MAVEN_WRAPPER_DISTS = $null
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
} else {
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
}
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
}
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
# Find the actual extracted directory name (handles snapshots where filename != directory name)
$actualDistributionDir = ""
# First try the expected directory name (for regular distributions)
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
$actualDistributionDir = $distributionUrlNameMain
}
# If not found, search for any directory with the Maven executable (for snapshots)
if (!$actualDistributionDir) {
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
$testPath = Join-Path $_.FullName "bin/$MVN_CMD"
if (Test-Path -Path $testPath -PathType Leaf) {
$actualDistributionDir = $_.Name
}
}
}
if (!$actualDistributionDir) {
Write-Error "Could not find Maven distribution directory in extracted archive"
}
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

@ -0,0 +1,212 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mfsys</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<groupId>com.mfsys</groupId>
<artifactId>aconnect</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<name>aconnect</name>
<description>Middleware Application</description>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<!-- Spring Boot Starters -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Database -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Tomcat (external deployment) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.6</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.6</version>
<scope>runtime</scope>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Internal common module -->
<dependency>
<groupId>com.mfsys</groupId>
<artifactId>common</artifactId>
<version>0.0.1</version>
</dependency>
<!-- Optional Spring Context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>21</source>
<target>21</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<spring.profiles.active>${spring.profiles.active}</spring.profiles.active>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
<!-- Maven Environment Profiles -->
<profiles>
<!-- Development -->
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
<build>
<finalName>aconnect-dev</finalName>
</build>
</profile>
<!-- UAT -->
<profile>
<id>uat</id>
<properties>
<spring.profiles.active>uat</spring.profiles.active>
</properties>
<build>
<finalName>aconnect-uat</finalName>
</build>
</profile>
<!-- Live / Production -->
<profile>
<id>live</id>
<properties>
<spring.profiles.active>live</spring.profiles.active>
</properties>
<build>
<finalName>aconnect</finalName>
</build>
</profile>
</profiles>
</project>

@ -0,0 +1,29 @@
package com.mfsys.aconnect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication(scanBasePackages = {"com.mfsys"})
@EntityScan(basePackages = {"com.mfsys"})
@EnableJpaRepositories({"com.mfsys"})
public class AconnectApplication {
public static void main(String[] args) {
SpringApplication.run(AconnectApplication.class, args);
}
@Value("${app.base.uri}")
private String baseUri;
@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> webServerFactoryCustomizer() {
return factory -> factory.setContextPath("/" + baseUri);
}
}

@ -0,0 +1,13 @@
package com.mfsys.aconnect;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AconnectApplication.class);
}
}

@ -0,0 +1,39 @@
package com.mfsys.aconnect.client.controller;
import com.mfsys.aconnect.client.dto.SigninRequest;
import com.mfsys.aconnect.client.service.LoginService;
import com.mfsys.common.configuration.constant.AconnectURI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class LoginController {
LoginService loginService;
@Autowired
public LoginController(LoginService loginService) {
this.loginService = loginService;
}
@PostMapping(AconnectURI.SIGNIN)
public ResponseEntity<Map<String, Object>> login(@RequestBody(required = false) SigninRequest login) {
if (login == null) {
return ResponseEntity.badRequest().body(Map.of("error", "Request body is missing"));
}
Map<String, String> payload = Map.of(
"username", login.getUsername(),
"password", login.getPassword()
);
Map<String, Object> response = loginService.authenticate(payload);
return ResponseEntity.ok(response);
}
}

@ -0,0 +1,96 @@
package com.mfsys.aconnect.client.controller;
import com.mfsys.aconnect.client.dto.*;
import com.mfsys.aconnect.client.service.TransactionService;
import com.mfsys.common.configuration.constant.AconnectURI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
@RestController
public class TransactionController {
@Autowired
private TransactionService transactionService;
@Autowired
public TransactionController(TransactionService transactionService) {
this.transactionService = transactionService;
}
@GetMapping("/account/getAccountDetails")
public ResponseEntity activeAccountDetails(
@RequestParam("porOrgacode") String porOrgacode,
@RequestParam("mbmBkmsnumber") String mbmBkmsnumber,
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate sgtGntrvaluedate,
@RequestHeader("Authorization") String token,
@RequestHeader("SUS_USERCODE") String userCode) {
return transactionService.getActiveAccountDetails(porOrgacode, mbmBkmsnumber, sgtGntrvaluedate, token, userCode);
}
@PostMapping(AconnectURI.TRANSACTION_ACCOUNT_GL_URI)
public Object accountGLTransaction(@RequestBody AccountGLTransactionRequest request,
@RequestHeader("Authorization") String token) {
return transactionService.processAccountTransaction(request, token);
}
@PostMapping(AconnectURI.TRANSACTION_GL_GL_URI)
public Object glGlTransaction(@RequestBody GLtoGLRequest request,
@RequestHeader("Authorization") String token) {
return transactionService.processGLTransaction(request, token);
}
@PostMapping(AconnectURI.DEPOSIT_AUTHORIZATION_URI)
public Object depositAuthorizationTransaction(@RequestBody DepositAuthorizationRequest authorizationRequest,
@RequestHeader("Authorization") String token) {
return transactionService.processDepositAuthTransaction(authorizationRequest, token);
}
@PostMapping(AconnectURI.GENERALLEDGER_AUTHORIZATION_URI)
public Object glAuthorizationTransaction(@RequestBody GLAuthorizationDTO glAuthorizationRequest,
@RequestHeader("Authorization") String token) {
return transactionService.processGLAuthTransaction(glAuthorizationRequest, token);
}
@PostMapping(AconnectURI.DEPOSIT_CANCELLATION_URI)
public Object depositCancellationTransaction(@RequestBody DepositCancellationDTO depositCancellationDTO,
@RequestHeader("Authorization") String token) {
return transactionService.processDepositCancellationTransaction(depositCancellationDTO, token);
}
@PostMapping(AconnectURI.GENERALLEDGER_CANCELLATION_URI)
public Object glCancellationTransaction(@RequestBody GLCancellationDTO glCancellationRequest,
@RequestHeader("Authorization") String token) {
return transactionService.processGLCancellationTransaction(glCancellationRequest, token);
}
@PostMapping(AconnectURI.DEPOSIT_TRANSACTION_REVERSAL_URI)
public Object depositReversalTransaction(@RequestBody DepositReversalDTO depositReversalDTO,
@RequestHeader("Authorization") String token) {
return transactionService.processDepositReversalTransaction(depositReversalDTO, token);
}
@PostMapping(AconnectURI.GENERALLEDGER_TRANSACTION_REVERSAL_URI)
public Object glReversalTransaction(@RequestBody GLReversalDTO glReversalRequest,
@RequestHeader("Authorization") String token) {
return transactionService.processGLReversalTransaction(glReversalRequest, token);
}
@PostMapping(AconnectURI.DEPOSIT_TRANSACTION_REJECT_URI)
public Object depositRejectionTransaction(@RequestBody DepositRejectDTO rejectRequest,
@RequestHeader("Authorization") String token) {
return transactionService.processDepositRejectionTransaction(rejectRequest, token);
}
@PostMapping(AconnectURI.GENERALLEDGER_TRANSACTION_REJECT_URI)
public Object glRejectionTransaction(@RequestBody DepositRejectDTO rejectRequest,
@RequestHeader("Authorization") String token) {
return transactionService.processGLRejectionTransaction(rejectRequest, token);
}
}

@ -0,0 +1,40 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
@Data
public class AccountGLTransactionRequest {
private AdditionalInfo additionalInfo;
private CreditGl creditGl;
private DebitAcc debitAcc;
private String plcLocacode;
private String porOrgacode;
private String ptrTrancode;
private String ppmPymdcode;
private String sgtGntrcreateusr;
private String sgtGntrnarration;
private String sgtGntrvaluedate;
@Data
public static class AdditionalInfo {
private Boolean sgtRemittancetrans;
private String sgtTrandate;
}
@Data
public static class CreditGl {
private String pcaGlaccode;
private String plcLocacode;
private Double sgtGntramtfc;
}
@Data
public static class DebitAcc {
private String mbmBkmsnumber;
private String pitInstcode;
private Double sgtGntramtfc;
private String sgtGntrinstrumentno;
}
}

@ -0,0 +1,12 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
import java.util.List;
@Data
public class DepositAuthorizationRequest {
private List<TranDetail> tranDetailList;
private String porOrgacode;
private String susUsercode;
}

@ -0,0 +1,12 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
@Data
public class DepositCancellationDTO {
private String sgtGntrtranlink;
private String nodeId;
private String sgtGntrnarration;
private String porOrgacode;
private String susUsercode;
}

@ -0,0 +1,12 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
import java.util.List;
@Data
public class DepositRejectDTO {
private List<TranDetail> tranDetailList;
private String porOrgacode;
private String susUsercode;
}

@ -0,0 +1,11 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
@Data
public class DepositReversalDTO {
private String porOrgacode;
private String susUsercode;
private String nodeId;
private String sgtGntrtranlink;
}

@ -0,0 +1,12 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
import java.util.List;
@Data
public class GLAuthorizationDTO {
private List<TranDetail> tranDetailList;
private String porOrgacode;
private String susUsercode;
}

@ -0,0 +1,12 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
@Data
public class GLCancellationDTO {
private String sgtGntrtranlink;
private String nodeId;
private String sgtGntrnarration;
private String porOrgacode;
private String susUsercode;
}

@ -0,0 +1,12 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
import java.util.List;
@Data
public class GLRejectDTO {
private List<TranDetail> tranDetailList;
private String porOrgacode;
private String susUsercode;
}

@ -0,0 +1,11 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
@Data
public class GLReversalDTO {
private String porOrgacode;
private String susUsercode;
private String nodeId;
private String sgtGntrtranlink;
}

@ -0,0 +1,38 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
@Data
public class GLtoGLRequest {
private GLtoGLRequest.AdditionalInfo additionalInfo;
private GLtoGLRequest.CreditGl creditGl;
private GLtoGLRequest.DebitGl debitGl;
private String plcLocacode;
private String ptrTrancode;
private String porOrgacode;
private String ppmPymdcode;
private String sgtGntrcreateusr;
private String sgtGntrnarration;
private String sgtGntrvaluedate;
@Data
public static class AdditionalInfo {
private Boolean sgtRemittancetrans;
private String sgtTrandate;
}
@Data
public static class CreditGl {
private String pcaGlaccode;
private String plcLocacode;
private Double sgtGntramtfc;
}
@Data
public static class DebitGl {
private String pcaGlaccode;
private String plcLocacode;
private Double sgtGntramtfc;
}
}

@ -0,0 +1,13 @@
package com.mfsys.aconnect.client.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SigninRequest {
private String username;
private String password;
}

@ -0,0 +1,9 @@
package com.mfsys.aconnect.client.dto;
import lombok.Data;
@Data
public class TranDetail {
private String sgtGntrtranlink;
private String nodeId;
}

@ -0,0 +1,60 @@
package com.mfsys.aconnect.client.service;
import org.springframework.core.env.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class EnvironmentDetectionService {
@Autowired
private Environment environment;
public String detectEnvironmentFromUsername(String username) {
// Check if user has specific environment mapping
String userEnvironment = environment.getProperty("app.user." + username + ".environment");
if (userEnvironment != null) {
return userEnvironment;
}
// Default environment if user not mapped
return environment.getProperty("app.environment.default", "dev");
}
public String getSecurityUriForEnvironment(String environmentType) {
// Get security URI for the detected environment
String securityUri = environment.getProperty("app.environment." + environmentType + ".securityUri");
if (securityUri != null) {
return securityUri;
}
// Fallback to default
return environment.getProperty("app.security.uri.default",
"http://localhost:9090/security/auth/user");
}
public String getSecurityUriForUser(String username) {
String userEnvironment = detectEnvironmentFromUsername(username);
return getSecurityUriForEnvironment(userEnvironment);
}
public boolean isUserMapped(String username) {
return environment.getProperty("app.user." + username + ".environment") != null;
}
public Map<String, String> getUserEnvironmentInfo(String username) {
String environment = detectEnvironmentFromUsername(username);
String securityUri = getSecurityUriForEnvironment(environment);
return Map.of(
"username", username,
"environment", environment,
"securityUri", securityUri,
"isMapped", String.valueOf(isUserMapped(username))
);
}
}

@ -0,0 +1,78 @@
package com.mfsys.aconnect.client.service;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
@Service
public class LoginService {
@Value("${app.organization.uri}")
private String OrgaCode;
@Value("${app.security.uri}")
private String securityURI;
@Autowired
private EnvironmentDetectionService environmentDetectionService;
private final RestTemplate restTemplate = new RestTemplate();
private final ObjectMapper objectMapper = new ObjectMapper();
public Map<String, Object> authenticate(Map<String, String> payload) {
String username = payload.get("username");
String password = payload.get("password");
// // Detect environment and get security URI based on username
// String userEnvironment = environmentDetectionService.detectEnvironmentFromUsername(username);
// String securityUri = environmentDetectionService.getSecurityUriForUser(username);
// boolean isUserMapped = environmentDetectionService.isUserMapped(username);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("mobileLogin", "false");
Map<String, String> requestPayload = new HashMap<>(payload);
requestPayload.put("clientid", OrgaCode);
HttpEntity<Map<String, String>> request = new HttpEntity<>(requestPayload, headers);
try {
// System.out.println("=== Environment-Based Routing ===");
// System.out.println("Username: " + username);
// System.out.println("Detected Environment: " + userEnvironment);
// System.out.println("Security Service: " + securityUri);
// System.out.println("User Explicitly Mapped: " + isUserMapped);
ResponseEntity<String> response = restTemplate.postForEntity(securityURI, request, String.class);
JsonNode jsonNode = objectMapper.readTree(response.getBody());
Map<String, Object> result = new HashMap<>();
result.put("authenticated", jsonNode.get("authenticated").asBoolean());
result.put("token", jsonNode.get("token").asText());
result.put("userName", jsonNode.get("userName").asText());
// result.put("securityServiceUsed", securityUri);
// result.put("userEnvironment", userEnvironment);
// result.put("userExplicitlyMapped", isUserMapped);
return result;
} catch (Exception e) {
// System.err.println("Authentication failed for user: " + username);
// System.err.println("Environment: " + userEnvironment);
// System.err.println("Security Service: " + securityUri);
// System.err.println("Error: " + e.getMessage());
return Map.of(
"authenticated", false,
"error", "Authentication failed: " + e.getMessage()
);
}
}
}

@ -0,0 +1,297 @@
package com.mfsys.aconnect.client.service;
import com.mfsys.aconnect.client.dto.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpHeaders;
import java.time.LocalDate;
import java.util.Map;
import static com.mfsys.common.configuration.constant.AconnectURI.*;
@Service
public class TransactionService {
@Value("${app.deposit.uri}")
private String depositURI;
@Value("${app.generalledger.uri}")
private String generalledgerURI;
private final RestTemplate restTemplate = new RestTemplate();
public ResponseEntity getActiveAccountDetails(String porOrgacode, String mbmBkmsnumber, LocalDate sgtGntrvaluedate, String tokenHeader, String userCode) {
String url = depositURI + DEPOSIT_CIIHIVE_ACCOUNT_MISCELLANEOUS_DETAILS_URI + "?porOrgacode=" + porOrgacode + "&mbmBkmsnumber=" + mbmBkmsnumber;
if (sgtGntrvaluedate != null) {
url += "&sgtGntrvaluedate=" + sgtGntrvaluedate;
}
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", userCode);
headers.setAccept(java.util.List.of(MediaType.APPLICATION_JSON));
HttpEntity<Void> entity = new HttpEntity<>(headers);
ResponseEntity<Map> response = restTemplate.exchange(url,HttpMethod.GET,entity,Map.class);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
public ResponseEntity processAccountTransaction(AccountGLTransactionRequest accountGLTransactionRequest, String tokenHeader) {
Double creditAmount = accountGLTransactionRequest.getCreditGl().getSgtGntramtfc();
Double debitAmount = accountGLTransactionRequest.getDebitAcc().getSgtGntramtfc();
if (!creditAmount.equals(debitAmount)) {
return ResponseEntity
.badRequest()
.body("Credit and Debit amounts must be equal");
}
String porOrgacode = accountGLTransactionRequest.getPorOrgacode();
String url = depositURI + "/deposit/" + "/organizations/" + porOrgacode + "/transactions" + ACONNECT + "/accounttogls";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", accountGLTransactionRequest.getSgtGntrcreateusr());
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(java.util.List.of(MediaType.APPLICATION_JSON));
HttpEntity<AccountGLTransactionRequest> entity = new HttpEntity<>(accountGLTransactionRequest, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Map.class
);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
public Object processGLTransaction(GLtoGLRequest gLtoGLRequest, String tokenHeader) {
Double creditAmount = gLtoGLRequest.getCreditGl().getSgtGntramtfc();
Double debitAmount = gLtoGLRequest.getDebitGl().getSgtGntramtfc();
if (!creditAmount.equals(debitAmount)) {
return ResponseEntity
.badRequest()
.body("Credit and Debit amounts must be equal");
}
String porOrgacode = gLtoGLRequest.getPorOrgacode();
String url = generalledgerURI + "/generalledger/" + "/organizations/" + porOrgacode + "/transactions" + ACONNECT +"/gltogls";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", gLtoGLRequest.getSgtGntrcreateusr());
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(java.util.List.of(MediaType.APPLICATION_JSON));
HttpEntity<GLtoGLRequest> entity = new HttpEntity<>(gLtoGLRequest, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Map.class
);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
public Object processDepositAuthTransaction(DepositAuthorizationRequest authorizationRequest, String tokenHeader) {
String porOrgacode = authorizationRequest.getPorOrgacode();
String url = depositURI + "/deposit/" + "/organizations/" + porOrgacode + "/transactions" + ACONNECT + "/authorizations";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", authorizationRequest.getSusUsercode());
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(java.util.List.of(MediaType.APPLICATION_JSON));
HttpEntity<DepositAuthorizationRequest> entity = new HttpEntity<>(authorizationRequest, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Map.class
);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
public Object processGLAuthTransaction(GLAuthorizationDTO authorizationRequest, String tokenHeader) {
String porOrgacode = authorizationRequest.getPorOrgacode();
String url = generalledgerURI + "/generalledger/" + "/organizations/" + porOrgacode + "/transactions/authorizations";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", authorizationRequest.getSusUsercode());
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<GLAuthorizationDTO> entity = new HttpEntity<>(authorizationRequest, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Map.class
);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
public Object processDepositReversalTransaction(DepositReversalDTO reversalRequest, String tokenHeader) {
String porOrgacode = reversalRequest.getPorOrgacode();
String nodeID = reversalRequest.getNodeId();
String sgtGntrtranlink = reversalRequest.getSgtGntrtranlink();
String url = depositURI + "/deposit/" + "/organizations/" + porOrgacode + "/transactions" + ACONNECT + "/reversals/nodes/" + nodeID + "/trannums/" + sgtGntrtranlink;
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", reversalRequest.getSusUsercode());
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<DepositReversalDTO> entity = new HttpEntity<>(reversalRequest, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Map.class
);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
public Object processGLReversalTransaction(GLReversalDTO reversalRequest, String tokenHeader) {
String porOrgacode = reversalRequest.getPorOrgacode();
String nodeID = reversalRequest.getNodeId();
String sgtGntrtranlink = reversalRequest.getSgtGntrtranlink();
String url = generalledgerURI + "/generalledger/" + "/organizations/" + porOrgacode + "/transactions"+ ACONNECT +"/reversals/nodes/" + nodeID + "/trannums/" + sgtGntrtranlink;
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", reversalRequest.getSusUsercode());
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<GLReversalDTO> entity = new HttpEntity<>(reversalRequest, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Map.class
);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
public Object processDepositRejectionTransaction(DepositRejectDTO rejectRequest, String tokenHeader) {
String porOrgacode = rejectRequest.getPorOrgacode();
String url = depositURI + "/deposit/" + "/organizations/" + porOrgacode + "/transactions" + ACONNECT +"/rejection";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", rejectRequest.getSusUsercode());
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<DepositRejectDTO> entity = new HttpEntity<>(rejectRequest, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Map.class
);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
public Object processGLRejectionTransaction(DepositRejectDTO rejectRequest, String tokenHeader) {
String porOrgacode = rejectRequest.getPorOrgacode();
String url = generalledgerURI + "/generalledger/" + "/organizations/" + porOrgacode + "/transactions" + ACONNECT +"/rejection";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", rejectRequest.getSusUsercode());
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<DepositRejectDTO> entity = new HttpEntity<>(rejectRequest, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Map.class
);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
public Object processDepositCancellationTransaction(DepositCancellationDTO depositCancellationDTO, String tokenHeader) {
String porOrgacode = depositCancellationDTO.getPorOrgacode();
String url = depositURI + "/deposit" + "/organizations/" + depositCancellationDTO.getPorOrgacode() +
"/transactions" + ACONNECT + "/cancel/nodes/" + depositCancellationDTO.getNodeId() +
"/trannums/" + depositCancellationDTO.getSgtGntrtranlink();
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", depositCancellationDTO.getSusUsercode());
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<DepositCancellationDTO> entity = new HttpEntity<>(depositCancellationDTO, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Map.class
);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
public Object processGLCancellationTransaction(GLCancellationDTO glCancellationDTO, String tokenHeader) {
String porOrgacode = glCancellationDTO.getPorOrgacode();
String url = generalledgerURI + GENERALLEDGER + "/organizations/" + glCancellationDTO.getPorOrgacode() +
"/transactions" + ACONNECT + "/cancel/nodes/" + glCancellationDTO.getNodeId() +
"/trannums/" + glCancellationDTO.getSgtGntrtranlink();
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", tokenHeader);
headers.set("POR_ORGACODE", porOrgacode);
headers.set("SUS_USERCODE", glCancellationDTO.getSusUsercode());
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<GLCancellationDTO> entity = new HttpEntity<>(glCancellationDTO, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
Map.class
);
return ResponseEntity.status(response.getStatusCode()).body(response.getBody());
}
}

@ -0,0 +1,25 @@
package com.mfsys.aconnect.configuration.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
System.out.println("✅ Custom SecurityFilterChain loaded");
http
.csrf(csrf -> csrf.disable()) // Disable CSRF for API use
.authorizeHttpRequests(auth -> auth
.anyRequest().permitAll() // Allow all requests
)
.httpBasic(Customizer.withDefaults()); // Optional — won't do anything since all requests are permitted
return http.build();
}
}

@ -0,0 +1,23 @@
package com.mfsys.aconnect.configuration.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class WebClientConfig {
private final String baseUrl = "http://localhost:8080/digitalkisaan";
@Bean
public WebClient webClient(WebClient.Builder builder) {
return builder
.baseUrl(baseUrl) // Set the base URL for all requests
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // Set a default content type
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) // Set a default accept header
.build();
}
}

@ -0,0 +1,65 @@
package com.mfsys.aconnect.configuration.service;
import org.springframework.stereotype.Service;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@Service
public class RequestRateLimiterService {
private final ConcurrentHashMap<String, RateLimitData> requestCounts = new ConcurrentHashMap<>();
public boolean isRequestAllowed(String userId, String requestURI, int maxRequestsPerMinute) {
String key = userId + ":" + requestURI;
long currentTimeMillis = System.currentTimeMillis();
requestCounts.putIfAbsent(key, new RateLimitData(currentTimeMillis, 0));
RateLimitData data = requestCounts.get(key);
// Check if a minute has passed since the last reset
if (TimeUnit.MILLISECONDS.toMinutes(currentTimeMillis - data.getTimestamp()) >= 1) {
// Reset the counter if a minute has passed
data.setCount(1);
data.setTimestamp(currentTimeMillis);
return true;
} else {
// Increment and check the count
data.incrementCount();
if (data.getCount() > maxRequestsPerMinute) {
return false; // Request denied
}
return true; // Request allowed
}
}
}
class RateLimitData {
private long timestamp;
private int count;
public RateLimitData(long timestamp, int count) {
this.timestamp = timestamp;
this.count = count;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public void incrementCount() {
this.count++;
}
}

@ -0,0 +1,6 @@
package com.mfsys.aconnect.security.constant;
public interface SecurityURI {
String AUTHENTICATION = "/authentication";
String LOGIN = "/login";
}

@ -0,0 +1,35 @@
package com.mfsys.aconnect.security.controller;
import com.mfsys.aconnect.security.constant.SecurityURI;
import com.mfsys.aconnect.security.dto.LoginRequest;
import com.mfsys.aconnect.security.dto.LoginResponse;
import com.mfsys.aconnect.security.service.AuthenticationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(SecurityURI.AUTHENTICATION)
public class AuthenticationController {
private final AuthenticationService authenticationService;
@Autowired
public AuthenticationController(AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}
@PostMapping(SecurityURI.LOGIN)
public ResponseEntity<LoginResponse> login(@RequestBody LoginRequest loginRequest) {
try {
LoginResponse response = authenticationService.login(loginRequest);
return ResponseEntity.ok(response);
} catch (RuntimeException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
}
}

@ -0,0 +1,13 @@
package com.mfsys.aconnect.security.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginRequest {
private String userId;
private String password;
}

@ -0,0 +1,16 @@
package com.mfsys.aconnect.security.dto;
import com.mfsys.aconnect.usermanagement.model.User;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginResponse {
private User user;
private boolean requiresOtp;
private boolean requiresPasswordChange;
private String token;
}

@ -0,0 +1,48 @@
package com.mfsys.aconnect.security.model;
import com.mfsys.aconnect.usermanagement.model.User;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import java.time.LocalDateTime;
@Entity(name = "OTP_TOKENS")
@Table(name = "OTP_TOKENS")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OtpToken {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Column(nullable = false, length = 10)
private String token;
@Enumerated(EnumType.STRING)
@Column(name = "token_type", nullable = false)
private TokenType tokenType;
@Column(name = "is_used")
private Boolean isUsed = false;
@Column(name = "expires_at", nullable = false)
private LocalDateTime expiresAt;
@CreatedDate
@Column(name = "created_at")
private LocalDateTime createdAt;
public enum TokenType {
LOGIN,
PASSWORD_RESET,
EMAIL_VERIFICATION
}
}

@ -0,0 +1,42 @@
package com.mfsys.aconnect.security.service;
import com.mfsys.common.configuration.service.JwtService;
import com.mfsys.common.configuration.service.PasswordEncryptionService;
import com.mfsys.aconnect.security.dto.LoginRequest;
import com.mfsys.aconnect.security.dto.LoginResponse;
import com.mfsys.aconnect.usermanagement.model.User;
import com.mfsys.aconnect.usermanagement.repository.UserRepository;
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AuthenticationService {
private final UserRepository userRepository;
private final JwtService jwtService;
@Autowired
public AuthenticationService (UserRepository userRepository, PasswordEncryptionService passwordEncryptionService,
JwtService jwtService) {
this.userRepository = userRepository;
this.jwtService = jwtService;
}
@Transactional
public LoginResponse login(LoginRequest loginRequest) {
// Find user by email
User user = userRepository.findByUserIdAndIsActiveTrue(loginRequest.getUserId())
.orElseThrow(() -> new RuntimeException("Invalid credentials"));
// Verify password
if (!PasswordEncryptionService.verifyPassword(loginRequest.getPassword(), user.getPassword())) {
throw new RuntimeException("Invalid credentials");
}
String token = jwtService.generateToken(loginRequest.getUserId());
return new LoginResponse(user, false, user.getIsFirstLogin(), token);
}
}

@ -0,0 +1,7 @@
package com.mfsys.aconnect.security.service;
import org.springframework.stereotype.Service;
@Service
public class OtpService {
}

@ -0,0 +1,21 @@
package com.mfsys.aconnect.usermanagement.constant;
public interface UserManagementURI {
String USER = "/user";
String GET_USER = "/getUser";
String CREATE_USER = "/createUser";
String UPDATE_USER = "/updateUser";
String DELETE_USER = "/deleteUser";
String GET_ALL_USERS = "/getAllUsers";
String GET_USER_PERMISSIONS = "/getPermissions";
String SAVE_USER_PERMISSIONS = "/savePermissions";
String UPDATE_USER_PERMISSIONS = "/updatePermissions";
String USER_SUBSCRIPTION = "/userSubscription";
String GET_USER_SUBSCRIPTION = "/getUserSubscription";
String CREATE_USER_SUBSCRIPTION = "/createUserSubscription";
String UPDATE_USER_SUBSCRIPTION = "/updateUserSubscription";
String DELETE_USER_SUBSCRIPTION = "/deleteUserSubscription";
String GET_ALL_USER_SUBSCRIPTIONS = "/getAllUserSubscriptions";
}

@ -0,0 +1,88 @@
package com.mfsys.aconnect.usermanagement.controller;
import com.mfsys.aconnect.usermanagement.constant.UserManagementURI;
import com.mfsys.aconnect.usermanagement.dto.PermissionDTO;
import com.mfsys.aconnect.usermanagement.dto.UserDTOs;
import com.mfsys.aconnect.usermanagement.service.UserService;
import jakarta.persistence.EntityNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping(UserManagementURI.USER)
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping(UserManagementURI.CREATE_USER)
public ResponseEntity<UserDTOs.UserResponse> createUser(@RequestBody UserDTOs.UserRequest request) {
UserDTOs.UserResponse response = userService.createUser(request);
return new ResponseEntity<>(response, HttpStatus.CREATED);
}
@GetMapping(UserManagementURI.GET_ALL_USERS)
public ResponseEntity<List<UserDTOs.UserResponse>> getAllUsers() {
List<UserDTOs.UserResponse> users = userService.getAllUsers();
return new ResponseEntity<>(users, HttpStatus.OK);
}
@GetMapping(UserManagementURI.GET_USER)
public ResponseEntity<UserDTOs.UserResponse> getUserById(@RequestParam String userId) {
try {
UserDTOs.UserResponse user = userService.getUserById(userId);
return new ResponseEntity<>(user, HttpStatus.OK);
} catch (EntityNotFoundException ex) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@PutMapping(UserManagementURI.UPDATE_USER)
public ResponseEntity<UserDTOs.UserResponse> updateUser(@RequestParam String userId, @RequestBody UserDTOs.UserRequest request) {
try {
UserDTOs.UserResponse response = userService.updateUser(userId, request);
return new ResponseEntity<>(response, HttpStatus.OK);
} catch (EntityNotFoundException ex) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@DeleteMapping(UserManagementURI.DELETE_USER)
public ResponseEntity<Void> deleteUser(@RequestParam String userId) {
try {
userService.deleteUser(userId);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (EntityNotFoundException ex) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@PostMapping(UserManagementURI.SAVE_USER_PERMISSIONS)
public ResponseEntity<UserDTOs.UserResponse> saveUserPermissions(
@RequestBody PermissionDTO permissionDTO) {
UserDTOs.UserResponse response = userService.saveUserPermissions(permissionDTO);
return new ResponseEntity<>(response, HttpStatus.OK);
}
@GetMapping(UserManagementURI.GET_USER_PERMISSIONS)
public ResponseEntity<PermissionDTO> getUserPermissions(@RequestParam String userId) {
PermissionDTO dto = userService.getUserPermissions(userId);
return new ResponseEntity<>(dto, HttpStatus.OK);
}
@PutMapping(UserManagementURI.UPDATE_USER_PERMISSIONS)
public ResponseEntity<UserDTOs.UserResponse> updateUserPermissions(
@RequestBody PermissionDTO permissionDTO) {
UserDTOs.UserResponse response = userService.updateUserPermissions(permissionDTO);
return new ResponseEntity<>(response, HttpStatus.OK);
}
}

@ -0,0 +1,62 @@
package com.mfsys.aconnect.usermanagement.controller;
import com.mfsys.aconnect.usermanagement.constant.UserManagementURI;
import com.mfsys.aconnect.usermanagement.dto.UserSubscriptionDTOs.UserSubscriptionRequest;
import com.mfsys.aconnect.usermanagement.dto.UserSubscriptionDTOs.UserSubscriptionResponse;
import com.mfsys.aconnect.usermanagement.service.UserSubscriptionService;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping(UserManagementURI.USER_SUBSCRIPTION)
public class UserSubscriptionController {
private final UserSubscriptionService userSubscriptionService;
@Autowired
public UserSubscriptionController(UserSubscriptionService userSubscriptionService) {
this.userSubscriptionService = userSubscriptionService;
}
@PostMapping(UserManagementURI.CREATE_USER_SUBSCRIPTION)
public ResponseEntity<UserSubscriptionResponse> createSubscription(
@RequestParam String userId,
@Valid @RequestBody UserSubscriptionRequest request) {
UserSubscriptionResponse createdSubscription = userSubscriptionService.createSubscription(userId, request);
return new ResponseEntity<>(createdSubscription, HttpStatus.CREATED);
}
@GetMapping(UserManagementURI.GET_ALL_USER_SUBSCRIPTIONS)
public ResponseEntity<List<UserSubscriptionResponse>> getSubscriptionsByUserId(@RequestParam String userId) {
List<UserSubscriptionResponse> subscriptions = userSubscriptionService.getSubscriptionsByUserId(userId);
return ResponseEntity.ok(subscriptions);
}
@GetMapping(UserManagementURI.GET_USER_SUBSCRIPTION)
public ResponseEntity<UserSubscriptionResponse> getSubscriptionById(
@RequestParam Long subscriptionId) {
return userSubscriptionService.getSubscriptionById(subscriptionId)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PutMapping(UserManagementURI.UPDATE_USER_SUBSCRIPTION)
public ResponseEntity<UserSubscriptionResponse> updateSubscription(
@RequestParam Long subscriptionId,
@Valid @RequestBody UserSubscriptionRequest request) {
UserSubscriptionResponse updatedSubscription = userSubscriptionService.updateSubscription(subscriptionId, request);
return ResponseEntity.ok(updatedSubscription);
}
@DeleteMapping(UserManagementURI.DELETE_USER_SUBSCRIPTION)
public ResponseEntity<Void> deleteSubscription(
@RequestParam Long subscriptionId) {
userSubscriptionService.deleteSubscription(subscriptionId);
return ResponseEntity.noContent().build();
}
}

@ -0,0 +1,10 @@
package com.mfsys.aconnect.usermanagement.dto;
import lombok.Data;
import java.util.List;
@Data
public class PermissionDTO {
private List<String> permissions;
private String userId;
}

@ -0,0 +1,37 @@
package com.mfsys.aconnect.usermanagement.dto;
import com.mfsys.aconnect.usermanagement.model.Role;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* DTOs (Data Transfer Objects) for User.
* This separates the API contract from the internal entity model for security and flexibility.
*/
public class UserDTOs {
@Data
@NoArgsConstructor
public static class UserRequest {
private String userId;
private String userFullname;
private String password;
private String email;
private Role role;
}
@Data
@NoArgsConstructor
public static class UserResponse {
private String userId;
private String userFullname;
private String email;
private Role role;
private Boolean isFirstLogin;
private Boolean isActive;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
}

@ -0,0 +1,51 @@
package com.mfsys.aconnect.usermanagement.dto;
import com.mfsys.aconnect.usermanagement.model.UserSubscription;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
public class UserSubscriptionDTOs {
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class UserSubscriptionRequest {
@NotBlank(message = "Endpoint path is required")
private String endpointPath;
private String description;
@NotNull(message = "isActive status is required")
private Boolean isActive;
@NotNull(message = "Max requests per minute is required")
private Integer maxRequestsPerMinute;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class UserSubscriptionResponse {
private Long id;
private String userId;
private String endpointPath;
private String description;
private Boolean isActive;
private Integer maxRequestsPerMinute;
private LocalDateTime createdAt;
public static UserSubscriptionResponse fromEntity(UserSubscription userSubscription) {
return new UserSubscriptionResponse(
userSubscription.getId(),
userSubscription.getUserId(),
userSubscription.getEndpointPath(),
userSubscription.getDescription(),
userSubscription.getIsActive(),
userSubscription.getMaxRequestsPerMinute(),
userSubscription.getCreatedAt()
);
}
}
}

@ -0,0 +1,68 @@
package com.mfsys.aconnect.usermanagement.filter;
import com.mfsys.common.configuration.constant.FilterPriority;
import com.mfsys.common.configuration.constant.TokenBypassURI;
import com.mfsys.aconnect.configuration.service.RequestRateLimiterService;
import com.mfsys.aconnect.usermanagement.model.Role;
import com.mfsys.aconnect.usermanagement.model.User;
import com.mfsys.aconnect.usermanagement.model.UserSubscription;
import com.mfsys.aconnect.usermanagement.service.UserService;
import com.mfsys.aconnect.usermanagement.service.UserSubscriptionService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@Component
@Order(FilterPriority.SUBSCRIPTION)
public class SubscriptionFilter extends OncePerRequestFilter {
private final UserService userService;
private final UserSubscriptionService userSubscriptionService;
private final RequestRateLimiterService requestRateLimiterService;
@Autowired
public SubscriptionFilter(UserService userService, UserSubscriptionService userSubscriptionService,
RequestRateLimiterService requestRateLimiterService) {
this.userService = userService;
this.userSubscriptionService = userSubscriptionService;
this.requestRateLimiterService = requestRateLimiterService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// TODO: For porOrga-change we Will removed it later
if (!(request.getMethod().equals("OPTIONS"))) {
System.out.println(">> " + request.getRequestURI() + " <<");
// TODO:
// important add all mconnect url in tokenbypass uri and remove this if
// condition or implement jwt in mconnect module
System.out.println(request.getHeaderNames());
if (!(TokenBypassURI.URIs.contains(request.getRequestURI()) || request.getRequestURI().startsWith("/MCONNECT/actuator"))) {
String userId = request.getHeader("userId");
User user = userService.findActiveUserById(userId)
.orElseThrow(() -> new RuntimeException("Invalid credentials"));
if(user.getRole().equals(Role.USER)){
UserSubscription userSubscription = userSubscriptionService.findByUserIdAndEndpointPath(userId, request.getRequestURI())
.orElseThrow(() -> new RuntimeException("No Active Subscription"));
int maxRequests = userSubscription.getMaxRequestsPerMinute();
if (!requestRateLimiterService.isRequestAllowed(userId, request.getRequestURI(), maxRequests)) {
throw new RuntimeException("Too many requests");
}
}
}
filterChain.doFilter(request, response);
}
}
}

@ -0,0 +1,5 @@
package com.mfsys.aconnect.usermanagement.model;
public enum Role {
USER, ADMIN
}

@ -0,0 +1,57 @@
package com.mfsys.aconnect.usermanagement.model;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@Column(name = "user_id", unique = true, nullable = false)
private String userId;
@Column(name = "user_fullname", nullable = false)
private String userFullname;
@Column(name = "password", nullable = false)
private String password;
@Column(name = "email", nullable = false, unique = true)
private String email;
@Enumerated(EnumType.STRING)
@Column(name = "role", nullable = false)
private Role role = Role.USER;
@Column(name = "permissions", columnDefinition = "TEXT")
private String permissions;
@Column(name = "is_first_login")
private Boolean isFirstLogin = true;
@Column(name = "is_active")
private Boolean isActive = true;
@CreationTimestamp
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserSubscription> userSubscriptions = new HashSet<>();
}

@ -0,0 +1,46 @@
package com.mfsys.aconnect.usermanagement.model;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Entity(name = "user_subscriptions")
@Table(name = "user_subscriptions")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserSubscription {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "endpoint_path", nullable = false, unique = true)
private String endpointPath;
@Column(columnDefinition = "TEXT")
private String description;
@Column(name = "is_active")
private Boolean isActive = true;
@Column(name = "max_requests_per_minute")
private Integer maxRequestsPerMinute = 60;
@Column(name = "created_at")
private LocalDateTime createdAt;
@Column(name = "user_id", nullable = false, updatable = false)
private String userId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
private User user;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
}
}

@ -0,0 +1,13 @@
package com.mfsys.aconnect.usermanagement.repository;
import com.mfsys.aconnect.usermanagement.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, String> {
Optional<User> findByUserIdAndIsActiveTrue(String userId);
Optional<User> findByEmail(String email);
}

@ -0,0 +1,14 @@
package com.mfsys.aconnect.usermanagement.repository;
import com.mfsys.aconnect.usermanagement.model.UserSubscription;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface UserSubscriptionRepository extends JpaRepository<UserSubscription, Long> {
Optional<UserSubscription> findByUserIdAndEndpointPathAndIsActiveTrue(String userId, String endpointPath);
List<UserSubscription> findByUserId(String userId);
}

@ -0,0 +1,132 @@
package com.mfsys.aconnect.usermanagement.service;
import com.mfsys.common.configuration.service.PasswordEncryptionService;
import com.mfsys.aconnect.usermanagement.dto.UserDTOs;
import com.mfsys.aconnect.usermanagement.dto.PermissionDTO;
import com.mfsys.aconnect.usermanagement.model.User;
import com.mfsys.aconnect.usermanagement.repository.UserRepository;
import jakarta.persistence.EntityNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Service class for handling User-related business logic.
* It uses the UserRepository to interact with the database.
*/
@Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncryptionService passwordEncryptionService;
public UserService(UserRepository userRepository, PasswordEncryptionService passwordEncryptionService) {
this.userRepository = userRepository;
this.passwordEncryptionService = passwordEncryptionService;
}
@Transactional
public UserDTOs.UserResponse createUser(UserDTOs.UserRequest request) {
User user = new User();
user.setUserId(request.getUserId());
user.setUserFullname(request.getUserFullname());
user.setEmail(request.getEmail());
user.setRole(request.getRole());
user.setPassword(passwordEncryptionService.hashPassword(request.getPassword()));
User savedUser = userRepository.save(user);
return mapToResponseDTO(savedUser);
}
public List<UserDTOs.UserResponse> getAllUsers() {
return userRepository.findAll().stream()
.map(this::mapToResponseDTO)
.collect(Collectors.toList());
}
public UserDTOs.UserResponse getUserById(String userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new EntityNotFoundException("User not found with ID: " + userId));
return mapToResponseDTO(user);
}
@Transactional
public UserDTOs.UserResponse updateUser(String userId, UserDTOs.UserRequest request) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new EntityNotFoundException("User not found with ID: " + userId));
user.setUserFullname(request.getUserFullname());
user.setEmail(request.getEmail());
user.setRole(request.getRole());
user.setPassword(passwordEncryptionService.hashPassword(request.getPassword()));
User updatedUser = userRepository.save(user);
return mapToResponseDTO(updatedUser);
}
@Transactional
public void deleteUser(String userId) {
if (!userRepository.existsById(userId)) {
throw new EntityNotFoundException("User not found with ID: " + userId);
}
userRepository.deleteById(userId);
}
public Optional<User> findActiveUserById(String userId) {
return userRepository.findByUserIdAndIsActiveTrue(userId);
}
private UserDTOs.UserResponse mapToResponseDTO(User user) {
UserDTOs.UserResponse response = new UserDTOs.UserResponse();
response.setUserId(user.getUserId());
response.setUserFullname(user.getUserFullname());
response.setEmail(user.getEmail());
response.setRole(user.getRole());
response.setIsFirstLogin(user.getIsFirstLogin());
response.setIsActive(user.getIsActive());
response.setCreatedAt(user.getCreatedAt());
response.setUpdatedAt(user.getUpdatedAt());
return response;
}
@Transactional
public UserDTOs.UserResponse saveUserPermissions(PermissionDTO permissionDTO) {
User user = userRepository.findById(permissionDTO.getUserId())
.orElseThrow(() -> new EntityNotFoundException("User not found with ID: " + permissionDTO.getUserId()));
// Convert list of permissions to comma-separated string
String permissions = String.join(",", permissionDTO.getPermissions());
user.setPermissions(permissions);
User updatedUser = userRepository.save(user);
return mapToResponseDTO(updatedUser);
}
public PermissionDTO getUserPermissions(String userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new EntityNotFoundException("User not found with ID: " + userId));
PermissionDTO dto = new PermissionDTO();
dto.setUserId(userId);
if (user.getPermissions() != null && !user.getPermissions().isEmpty()) {
dto.setPermissions(java.util.Arrays.asList(user.getPermissions().split(",")));
}
return dto;
}
@Transactional
public UserDTOs.UserResponse updateUserPermissions(PermissionDTO permissionDTO) {
User user = userRepository.findById(permissionDTO.getUserId())
.orElseThrow(() ->
new EntityNotFoundException("User not found with ID: " + permissionDTO.getUserId())
);
String permissions = String.join(",", permissionDTO.getPermissions());
user.setPermissions(permissions);
User updatedUser = userRepository.save(user);
return mapToResponseDTO(updatedUser);
}
}

@ -0,0 +1,84 @@
package com.mfsys.aconnect.usermanagement.service;
import com.mfsys.aconnect.usermanagement.dto.UserSubscriptionDTOs.UserSubscriptionRequest;
import com.mfsys.aconnect.usermanagement.model.User;
import com.mfsys.aconnect.usermanagement.model.UserSubscription;
import com.mfsys.aconnect.usermanagement.repository.UserRepository;
import com.mfsys.aconnect.usermanagement.repository.UserSubscriptionRepository;
import jakarta.persistence.EntityNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import com.mfsys.aconnect.usermanagement.dto.UserSubscriptionDTOs.UserSubscriptionResponse;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserSubscriptionService {
private final UserSubscriptionRepository userSubscriptionRepository;
private final UserRepository userRepository;
@Autowired
public UserSubscriptionService(UserSubscriptionRepository userSubscriptionRepository, UserRepository userRepository) {
this.userSubscriptionRepository = userSubscriptionRepository;
this.userRepository = userRepository;
}
@Transactional
public UserSubscriptionResponse createSubscription(String userId, UserSubscriptionRequest request) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new EntityNotFoundException("User not found with id: " + userId));
UserSubscription userSubscription = new UserSubscription();
userSubscription.setUserId(userId);
userSubscription.setEndpointPath(request.getEndpointPath());
userSubscription.setDescription(request.getDescription());
userSubscription.setIsActive(request.getIsActive());
userSubscription.setMaxRequestsPerMinute(request.getMaxRequestsPerMinute());
userSubscription.setUser(user);
UserSubscription savedSubscription = userSubscriptionRepository.save(userSubscription);
return UserSubscriptionResponse.fromEntity(savedSubscription);
}
public List<UserSubscriptionResponse> getSubscriptionsByUserId(String userId) {
return userSubscriptionRepository.findByUserId(userId)
.stream()
.map(UserSubscriptionResponse::fromEntity)
.collect(Collectors.toList());
}
public Optional<UserSubscriptionResponse> getSubscriptionById(Long subscriptionId) {
return userSubscriptionRepository.findById(subscriptionId)
.map(UserSubscriptionResponse::fromEntity);
}
@Transactional
public UserSubscriptionResponse updateSubscription(Long subscriptionId, UserSubscriptionRequest request) {
UserSubscription existingSubscription = userSubscriptionRepository.findById(subscriptionId)
.orElseThrow(() -> new EntityNotFoundException("User subscription not found with id: " + subscriptionId));
existingSubscription.setEndpointPath(request.getEndpointPath());
existingSubscription.setDescription(request.getDescription());
existingSubscription.setIsActive(request.getIsActive());
existingSubscription.setMaxRequestsPerMinute(request.getMaxRequestsPerMinute());
UserSubscription updatedSubscription = userSubscriptionRepository.save(existingSubscription);
return UserSubscriptionResponse.fromEntity(updatedSubscription);
}
@Transactional
public void deleteSubscription(Long subscriptionId) {
if (!userSubscriptionRepository.existsById(subscriptionId)) {
throw new EntityNotFoundException("User subscription not found with id: " + subscriptionId);
}
userSubscriptionRepository.deleteById(subscriptionId);
}
public Optional<UserSubscription> findByUserIdAndEndpointPath(String userId, String endpointPath) {
return userSubscriptionRepository.findByUserIdAndEndpointPathAndIsActiveTrue(userId, endpointPath);
}
}

@ -0,0 +1,5 @@
app.security.uri=http://localhost:9090/security/auth/user
app.deposit.uri=http://localhost:9095
app.generalledger.uri=http://localhost:9093
app.organization.uri=0005

@ -0,0 +1,4 @@
app.deposit.uri=${CMB_DEPOSIT_SERVER_URL}
app.generalledger.uri=${CMB_GL_SERVER_URL}
app.organization.uri=${CMB_ORGA_CODE}
app.security.uri=${CMB_SECURITY_SERVER_URL}/security/auth/user

@ -0,0 +1,4 @@
app.deposit.uri=${CMB_DEPOSIT_SERVER_URL}
app.generalledger.uri=${CMB_GL_SERVER_URL}
app.organization.uri=${CMB_ORGA_CODE}
app.security.uri=${CMB_SECURITY_SERVER_URL}/security/auth/user

@ -0,0 +1,4 @@
app.deposit.uri=${CMB_DEPOSIT_SERVER_URL}
app.generalledger.uri=${CMB_GL_SERVER_URL}
app.organization.uri=${CMB_ORGA_CODE}
app.security.uri=${CMB_SECURITY_SERVER_URL}/security/auth/user

@ -0,0 +1,23 @@
spring.application.name = aconnect
app.base.uri=aconnect
app.db.dbname = aconnect
app.db.dbuser=${CMB_SQL_DB_USER}
app.db.dbpassword=${CMB_SQL_DB_PASSWORD}
app.db.url=${CMB_SQL_DB_MACHINE_IP}
app.server.timezone=${APP_SERVER_TIMEZONE}
spring.datasource.username = ${app.db.dbuser}
spring.datasource.password = ${app.db.dbpassword}
spring.datasource.url = jdbc:mysql://${app.db.url}/${app.db.dbname}?createDatabaseIfNotExist=true&serverTimezone=${app.server.timezone}&useLegacyDatetimeCode=false&useUnicode=yes&characterEncoding=UTF-8&characterSetResults=UTF-8
spring.jpa.properties.hibernate.connection.characterEncoding=utf-8
spring.jpa.properties.hibernate.connection.CharSet=utf-8
spring.jpa.properties.hibernate.connection.useUnicode=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.profiles.active=@spring.profiles.active@
jwt.secret = D1kD4fP8wQ2zL6hM9sR3vX7yU0tJ5nB2cV8pG4qW6eY1iK3oA9uH7jN2mZ5xT9bS4rF0lP3dQ8wE1
jwt.expiration = 86400000
jwt.refresh-expiration= 604800000

@ -0,0 +1,13 @@
package com.mfsys.aconnect;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class AconnectApplicationTests {
@Test
void contextLoads() {
}
}

@ -0,0 +1,19 @@
# 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
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip

259
common/mvnw vendored

@ -0,0 +1,259 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# 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
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.3.2
#
# Optional ENV vars
# -----------------
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
# MVNW_REPOURL - repo url base for downloading maven distribution
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN* | MINGW*)
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
native_path() { cygpath --path --windows "$1"; }
;;
esac
# set JAVACMD and JAVACCMD
set_java_home() {
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
if [ -n "${JAVA_HOME-}" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACCMD="$JAVA_HOME/jre/sh/javac"
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACCMD="$JAVA_HOME/bin/javac"
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
return 1
fi
fi
else
JAVACMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v java
)" || :
JAVACCMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v javac
)" || :
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
return 1
fi
fi
}
# hash string like Java String::hashCode
hash_string() {
str="${1:-}" h=0
while [ -n "$str" ]; do
char="${str%"${str#?}"}"
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
str="${str#?}"
done
printf %x\\n $h
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
die() {
printf %s\\n "$1" >&2
exit 1
}
trim() {
# MWRAPPER-139:
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
# Needed for removing poorly interpreted newline sequences when running in more
# exotic environments such as mingw bash on Windows.
printf "%s" "${1}" | tr -d '[:space:]'
}
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
case "${key-}" in
distributionUrl) distributionUrl=$(trim "${value-}") ;;
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
esac
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
*)
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
distributionPlatform=linux-amd64
;;
esac
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
;;
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
trap clean HUP INT TERM EXIT
else
die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
distributionUrl="${distributionUrl%.zip}.tar.gz"
distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
verbose "Found wget ... using wget"
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
verbose "Found curl ... using curl"
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
verbose "Falling back to use Java to download"
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
cat >"$javaSource" <<-END
public class Downloader extends java.net.Authenticator
{
protected java.net.PasswordAuthentication getPasswordAuthentication()
{
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
}
public static void main( String[] args ) throws Exception
{
setDefault( new Downloader() );
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
}
}
END
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
verbose " - Compiling Downloader.java ..."
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
verbose " - Running Downloader.java ..."
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
distributionSha256Result=false
if [ "$MVN_CMD" = mvnd.sh ]; then
echo "Checksum validation is not supported for maven-mvnd." >&2
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
elif command -v sha256sum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
elif command -v shasum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
fi
if [ $distributionSha256Result = false ]; then
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
exit 1
fi
fi
# unzip and move
if command -v unzip >/dev/null; then
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
clean || :
exec_maven "$@"

149
common/mvnw.cmd vendored

@ -0,0 +1,149 @@
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.3.2
@REM
@REM Optional ENV vars
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
if ($env:MAVEN_USER_HOME) {
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
}
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
}
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mfsys</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<groupId>com.mfsys</groupId>
<artifactId>common</artifactId>
<version>0.0.1</version>
<name>common</name>
<description>aConnect</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.3</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>21</source>
<target>21</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,35 @@
package com.mfsys.common.configuration.constant;
public interface AconnectURI {
String ACONNECT = "/aconnect";
String REFRESH_TOKEN = "/refreshtoken";
String DEPOSIT = "/deposit";
String GENERALLEDGER = "/generalledger";
String SIGNIN = "/signin";
String TRANSACTION_URI = "/transactions";
String CANCEL_URI = "/cancel";
String REJECT_URI = "/rejection";
String REVERSE_URI = "/reversal";
String AUTHORIZATION_URI = "/authorizations";
String DEPOSIT_AUTHORIZATION_URI = DEPOSIT + AUTHORIZATION_URI;
String GENERALLEDGER_AUTHORIZATION_URI = GENERALLEDGER + AUTHORIZATION_URI;
// Cancellation
String DEPOSIT_CANCELLATION_URI = DEPOSIT + TRANSACTION_URI + CANCEL_URI;
String GENERALLEDGER_CANCELLATION_URI = GENERALLEDGER + TRANSACTION_URI + CANCEL_URI;
String TRANSACTION_ACCOUNT_GL_URI = TRANSACTION_URI + "/accounttogl";
String TRANSACTION_GL_GL_URI = TRANSACTION_URI + "/gltogls";
String TRANSACTION_CANCEL_URI = TRANSACTION_URI + CANCEL_URI + "/nodes/{nodeId}/trannums/{sgtGntrtranlink}";
String DEPOSIT_TRANSACTION_REJECT_URI = DEPOSIT + TRANSACTION_URI + REJECT_URI;
String GENERALLEDGER_TRANSACTION_REJECT_URI = GENERALLEDGER + TRANSACTION_URI + REJECT_URI;
String DEPOSIT_TRANSACTION_REVERSAL_URI = DEPOSIT + TRANSACTION_URI + REVERSE_URI;
String GENERALLEDGER_TRANSACTION_REVERSAL_URI = GENERALLEDGER + TRANSACTION_URI + REVERSE_URI;
String TRANSACTION_CIIHIVE_AUTHORIZATION_URI = TRANSACTION_URI + AUTHORIZATION_URI;
String TRANSACTION_CIIHIVE_REVERSAL_URI = TRANSACTION_URI + REVERSE_URI + "/nodes/{nodeId}/trannums/{sgtGntrtranlink}";
String DEPOSIT_CIIHIVE_ACCOUNT_MISCELLANEOUS_DETAILS_URI = "/deposit/account/miscDetails";
String DEPOSIT_ACONNECT_ACCOUNT_DETAILS_URI = "/aconnect/account/getAccountDetails";
}

@ -0,0 +1,23 @@
package com.mfsys.common.configuration.constant;
import com.mfsys.common.configuration.exception.ErrorMessage;
public enum ERRCode implements ErrorMessage {;
private String code;
private String description;
private ERRCode(String code, String description) {
this.code = code;
this.description = description;
}
@Override
public String getCode() {
return this.code;
}
@Override
public String getDescription() {
return this.description;
}
}

@ -0,0 +1,57 @@
package com.mfsys.common.configuration.constant;
public interface FieldNameLength {
// VARCHAR Lengths
String CODE_1 = "VARCHAR(1)";
String CODE_2 = "VARCHAR(2)";
String CODE_3 = "VARCHAR(3)";
String CODE_4 = "VARCHAR(4)";
String CODE_5 = "VARCHAR(5)";
String CODE_6 = "VARCHAR(60)";
String CODE_7 = "VARCHAR(7)";
String CODE_10 = "VARCHAR(10)";
String CODE_12 = "VARCHAR(12)";
String CODE_20 = "VARCHAR(20)";
String CODE_50 = "VARCHAR(50)";
String CODE_60 = "VARCHAR(60)";
String CODE_100 = "VARCHAR(100)";
String CODE_150 = "VARCHAR(150)";
String CODE_200 = "VARCHAR(200)";
String CODE_500 = "VARCHAR(500)";
String CODE_1000 = "VARCHAR(1000)";
// Descriptions
String DESCRIPTION_LONG = "VARCHAR(40)";
String DESCRIPTION_SHORT = "VARCHAR(20)";
// Numeric & Boolean Types
String BOOLEAN_BIT = "TINYINT(1)";
String AMOUNT_REAL = "DECIMAL(20,6)";
String AMOUNT_INT = "DECIMAL(20,0)";
String DECIMAL = "DECIMAL(20,6)";
String DECIMAL_30 = "DECIMAL(30,6)";
String RATE_REAL = "DECIMAL(20,10)";
// Date/Time Types
String DATE = "DATE";
String DATETIME = "DATETIME";
String TIMESTAMP = "TIMESTAMP";
String TIMESTAMP_NULLABLE = "TIMESTAMP NULL";
String YEAR = "YEAR";
// Other Data Types
String PASSWORD = "VARCHAR(50)";
String BIGINT = "BIGINT";
String INT = "INT";
String INT_50 = "INT(50)";
String TINYINT = "TINYINT";
String XML = "TEXT";
String TEXT = "TEXT";
String JSON = "JSON";
// Aliases
String DAYS = INT;
}

@ -0,0 +1,10 @@
package com.mfsys.common.configuration.constant;
public interface FilterPriority {
int CORS = 1;
int LOGGING = 2;
int AUTHENTICATION = 3;
int SUBSCRIPTION = 4;
}

@ -0,0 +1,5 @@
package com.mfsys.common.configuration.constant;
public interface LoggerURI {
String GET_LOGS_BY_DATES = "/logs/getByDate";
}

@ -0,0 +1,5 @@
package com.mfsys.common.configuration.constant;
public interface PropertyConstant {
}

@ -0,0 +1,30 @@
package com.mfsys.common.configuration.constant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public interface TokenBypassURI {
List<String> URIs = new ArrayList<String>(Arrays.asList(
"/aconnect/authentication/login",
"/aconnect/signin",
"/aconnect/transactions/accounttogl",
"/aconnect/account/miscDetails",
"/deposit/account/miscDetails",
"/aconnect/account/getAccountDetails",
"/aconnect/transactions/gltogls",
"/aconnect/deposit/authorizations",
"/aconnect/generalledger/authorizations",
"/aconnect/deposit/authorizations",
"/aconnect/deposit/transactions/cancel",
"/aconnect/generalledger/transactions/cancel",
"/aconnect/deposit/transactions/reversal",
"/aconnect/generalledger/transactions/reversal",
"/aconnect/deposit/transactions/rejection",
"/aconnect/generalledger/transactions/rejection"
));
}

@ -0,0 +1,28 @@
package com.mfsys.common.configuration.controller;
import com.mfsys.common.configuration.constant.LoggerURI;
import com.mfsys.common.configuration.model.Logger;
import com.mfsys.common.configuration.service.LoggerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
import java.util.List;
@RestController
public class LoggerController {
LoggerService loggerService;
@Autowired
LoggerController(LoggerService loggerService) {
this.loggerService = loggerService;
}
@GetMapping(LoggerURI.GET_LOGS_BY_DATES)
public List<Logger> findLogsBetweenDates(@RequestParam LocalDate fromDate, @RequestParam LocalDate toDate) {
return loggerService.findLogsBetweenDates(fromDate, toDate);
}
}

@ -0,0 +1,53 @@
package com.mfsys.common.configuration.exception;
import java.text.MessageFormat;
public class ApplicationException extends RuntimeException{
private static final long serialVersionUID = 1L;
protected final String porOrgacode;
protected final String errorCode;
protected final Object[] arguments;
protected final Object[] IMMUTABLE_ZERO_LEN_ARRAY = new Object[0];
protected String errorDescription;
public ApplicationException(String porOrgacode, ErrorMessage errorCode, Object... arguments) {
this(porOrgacode, errorCode.getCode(), arguments);
this.errorDescription = errorCode.getDescription();
}
public ApplicationException(String porOrgacode, String errorCode, Object... arguments) {
this.porOrgacode = porOrgacode;
this.errorCode = errorCode;
this.arguments = arguments;
}
public ApplicationException(String porOrgacode, String errorCode, Throwable e) {
super(errorCode, e);
this.porOrgacode = porOrgacode;
this.errorCode = errorCode;
arguments = IMMUTABLE_ZERO_LEN_ARRAY;
}
public String getErrorCode() {
return errorCode;
}
public String getErrorDescription() {
if (errorDescription != null) {
return replacePlaceholders(errorDescription, arguments);
}
return null;
}
public Object[] getArguments() {
return arguments;
}
public String getPorOrgacode() {
return this.porOrgacode;
}
private String replacePlaceholders(String message, Object[] arguments) {
return MessageFormat.format(message, arguments);
}
}

@ -0,0 +1,155 @@
package com.mfsys.common.configuration.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import java.io.Serializable;
import java.sql.Timestamp;
@ControllerAdvice
public class ApplicationExceptionMapper {
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationExceptionMapper.class);
// Handle generic exceptions
@ExceptionHandler(value = {Throwable.class})
protected ResponseEntity<GeneralError> handleConflict(Exception ex, WebRequest request) {
logExceptionStackTrace(ex);
return new ResponseEntity<GeneralError>(new GeneralError(ex.getMessage(), MDC.get("request_id")),
HttpStatus.INTERNAL_SERVER_ERROR);
}
// Handle Application-specific exceptions
@ExceptionHandler(value = {ApplicationException.class})
protected ResponseEntity<APIError> handleConflict(ApplicationException ex, WebRequest request) {
logExceptionStackTrace(ex);
return new ResponseEntity<APIError>(new APIError(ex.getErrorCode(), ex.getArguments(), ex.getLocalizedMessage(),
MDC.get("request_id")), HttpStatus.BAD_REQUEST);
}
// Handle DataIntegrityViolationException (duplicate entries, etc.)
@ExceptionHandler(value = {DataIntegrityViolationException.class})
protected ResponseEntity<APIError> handleDataIntegrityViolation(DataIntegrityViolationException ex, WebRequest request) {
logExceptionStackTrace(ex);
// Extract the root cause of the exception
String rootCauseMessage = ex.getRootCause() != null ? ex.getRootCause().getMessage() : ex.getMessage();
String errorCode;
HttpStatus status;
String message;
// Determine the type of Data Integrity Violation based on the root cause message
if (rootCauseMessage.contains("Duplicate entry")) {
// Handle duplicate entry constraint violations
errorCode = "DUPLICATE_ENTRY";
message = "Duplicate entry error: " + rootCauseMessage;
status = HttpStatus.CONFLICT; // 409 Conflict
} else if (rootCauseMessage.contains("not-null property")) {
// Handle not-null constraint violations
errorCode = "NOT_NULL_CONSTRAINT";
message = "Null value not allowed for the field: " + extractFieldName(rootCauseMessage);
status = HttpStatus.BAD_REQUEST; // 400 Bad Request
} else {
// Generic Data Integrity Violation
errorCode = "DATA_INTEGRITY_VIOLATION";
message = "Data integrity violation: " + rootCauseMessage;
status = HttpStatus.BAD_REQUEST; // 400 Bad Request
}
return new ResponseEntity<>(
new APIError(errorCode, new Object[] {}, message, MDC.get("request_id")),
status
);
}
// Handle RuntimeExceptions
@ExceptionHandler(value = {RuntimeException.class})
protected ResponseEntity<APIError> handleRuntimeException(RuntimeException ex, WebRequest request) {
logExceptionStackTrace(ex);
String message = "Runtime exception occurred: " + ex.getMessage();
return new ResponseEntity<>(new APIError(message, new Object[]{}, message, MDC.get("request_id")),
HttpStatus.INTERNAL_SERVER_ERROR);
}
// Utility method to extract field name from the root cause message
private String extractFieldName(String rootCauseMessage) {
// Example root cause message: "not-null property references a null or transient value: com.mfsys.cargoguard.auth.model.User.countryCode"
if (rootCauseMessage.contains(":")) {
return rootCauseMessage.substring(rootCauseMessage.lastIndexOf(":") + 1).trim();
}
return "Unknown field";
}
private void logExceptionStackTrace(Exception ex) {
ExceptionDAO exceptionDAO = ExceptionUtil.toExceptionDAO(ex);
LOGGER.error(exceptionDAO.getRequestId(), exceptionDAO.getExceptionArgs());
}
private static class GeneralError implements Serializable {
private static final long serialVersionUID = 1L;
private Timestamp timestamp = new Timestamp(System.currentTimeMillis());
private String debugMessage;
private String trackingId;
public GeneralError(String debugMessage, String trackingId) {
this.debugMessage = debugMessage;
this.trackingId = trackingId;
}
public GeneralError() {}
public Timestamp getTimestamp() {
return timestamp;
}
public String getDebugMessage() {
return debugMessage;
}
public String getTrackingId() {
return trackingId;
}
}
public static class APIError extends GeneralError implements Serializable {
private static final long serialVersionUID = 1L;
private String errorCode;
private Object[] arguments;
public APIError(String errorCode, Object[] arguments, String debugMessage, String trackingId) {
super(debugMessage, trackingId);
this.errorCode = errorCode;
this.arguments = arguments;
}
public APIError(String errorCode, Object[] arguments) {
super();
this.errorCode = errorCode;
this.arguments = arguments;
}
public APIError() {}
public String getErrorCode() {
return errorCode;
}
public Object[] getArguments() {
return arguments;
}
}
}

@ -0,0 +1,7 @@
package com.mfsys.common.configuration.exception;
public class DuplicateException extends ApplicationException {
public DuplicateException(ErrorMessage errCode){
super(null, errCode,null);
}
}

@ -0,0 +1,7 @@
package com.mfsys.common.configuration.exception;
public interface ErrorMessage {
public String getCode();
public String getDescription();
}

@ -0,0 +1,25 @@
package com.mfsys.common.configuration.exception;
public class ExceptionDAO {
private String requestId;
private Object[] exceptionArgs;
public ExceptionDAO(String requestId, Object... exceptionArgs) {
this.requestId = requestId;
this.exceptionArgs = exceptionArgs;
}
public String getRequestId() {
return requestId;
}
public Object[] getExceptionArgs() {
return exceptionArgs;
}
}

@ -0,0 +1,15 @@
package com.mfsys.common.configuration.exception;
import org.slf4j.MDC;
import java.io.PrintWriter;
import java.io.StringWriter;
public class ExceptionUtil {
public static final ExceptionDAO toExceptionDAO(Throwable e) {
StringWriter errors = new StringWriter();
e.printStackTrace(new PrintWriter(errors));
String err = errors.toString();
return new ExceptionDAO("restquestId={} , stacktrace={}", MDC.get("request_id"), err);
}
}

@ -0,0 +1,7 @@
package com.mfsys.common.configuration.exception;
public class ResourceNotFoundException extends ApplicationException {
public ResourceNotFoundException(String porOrgacode, ErrorMessage errCode){
super(porOrgacode, errCode);
}
}

@ -0,0 +1,215 @@
package com.mfsys.common.configuration.filter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.mfsys.common.configuration.constant.FilterPriority;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;
import org.springframework.web.filter.OncePerRequestFilter;
@Component
@Order(FilterPriority.CORS)
public class CORSResponseFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException {
HttpServletRequest processedRequest = request;
if(request.getMethod().equals("POST") || request.getMethod().equals("PATCH")|| request.getMethod().equals("PUT")) {
if(request.getHeader("X-Encrypted") != null) {
processedRequest = getDataFromRequest(request);
} else {
// Even for non-encrypted requests, wrap to allow multiple reads
String contentType = request.getContentType();
if (contentType == null || !contentType.startsWith("multipart/")) {
processedRequest = new CachedBodyHttpServletRequest(request);
}
}
}
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Expose-Headers", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE");
if (!(request.getMethod().equals("OPTIONS"))) {
filterChain.doFilter(processedRequest, response);
}
}
private Map<String, String> extractDataFromSecretKey(String secretKey) {
int firstInteger = Character.getNumericValue(secretKey.charAt(0));
int secondInteger = Character.getNumericValue(secretKey.charAt(1));
int key1Length = 16 + (firstInteger - 1) * 8;
String dataBeforeKey1 = secretKey.substring(2, 2 + secondInteger);
String key1 = secretKey.substring(2 + secondInteger, 2 + secondInteger + key1Length);
int totalLengthFromStart = 2 + secondInteger + key1Length;
String finalData = secretKey.substring(totalLengthFromStart);
finalData = dataBeforeKey1 + finalData;
int lastInteger = Character.getNumericValue(secretKey.charAt(secretKey.length() - 1));
int secondIntegerOffset = Character.getNumericValue(secretKey.charAt(secretKey.length() - 2));
int key2Length = 16 + (lastInteger - 1) * 8;
String skipLastTwo = secretKey.substring(0, secretKey.length() - 2);
String dataBeforeKey2 = skipLastTwo.substring(skipLastTwo.length() - secondIntegerOffset);
String skipCharatersTillKey2 = skipLastTwo.substring(0, skipLastTwo.length() - secondIntegerOffset);
String key2 = skipCharatersTillKey2.substring(skipCharatersTillKey2.length() - key2Length);
int totalLengthFromEND = 2 + secondIntegerOffset + key2Length;
finalData = finalData.substring(0, finalData.length() - totalLengthFromEND);
finalData = finalData + dataBeforeKey2;
Map<String, String> map = new HashMap<String, String>();
map.put("Key1", key1);
map.put("Key2", key2);
map.put("data", finalData);
return map;
}
private HttpServletRequest getDataFromRequest(HttpServletRequest request) throws IOException {
String contentType = request.getContentType();
if(contentType != null && contentType.contains("application/json")) {
// First, cache the original body
CachedBodyHttpServletRequest cachedRequest = new CachedBodyHttpServletRequest(request);
// Now read from the cached body (won't consume the original)
String requestBody = StreamUtils.copyToString(cachedRequest.getInputStream(), StandardCharsets.UTF_8);
String data = "";
try {
data = decrypt(new ObjectMapper().readTree(requestBody).get("data").asText());
} catch (Exception e) {
e.printStackTrace();
// If decryption fails, return the cached request with original body
return cachedRequest;
}
JsonNode jsonNode = new ObjectMapper().readTree(data);
// Create a new request wrapper with the decrypted data
final byte[] decryptedBodyBytes = jsonNode.toString().getBytes(StandardCharsets.UTF_8);
return new HttpServletRequestWrapper(cachedRequest) {
@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStreamImpl(new ByteArrayInputStream(decryptedBodyBytes));
}
@Override
public int getContentLength() {
return decryptedBodyBytes.length;
}
@Override
public long getContentLengthLong() {
return decryptedBodyBytes.length;
}
};
} else {
if (contentType == null || !contentType.startsWith("multipart/")) {
return new CachedBodyHttpServletRequest(request);
}
// For non-JSON content, just cache the body for multiple reads
return request;
}
}
private String decrypt(String encryptedInput) throws Exception {
Map<String, String> map = extractDataFromSecretKey(encryptedInput);
String key1 = map.get("Key1");
String Key2 = map.get("Key2");
String data = map.get("data");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key1.getBytes(StandardCharsets.UTF_8), "AES");
IvParameterSpec ivSpec = new IvParameterSpec(Key2.getBytes(StandardCharsets.UTF_8));
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(data));
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
// Reusable cached body request wrapper
private static class CachedBodyHttpServletRequest extends HttpServletRequestWrapper {
private final byte[] cachedBody;
public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {
super(request);
this.cachedBody = StreamUtils.copyToByteArray(request.getInputStream());
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStreamImpl(new ByteArrayInputStream(this.cachedBody));
}
@Override
public int getContentLength() {
return cachedBody.length;
}
@Override
public long getContentLengthLong() {
return cachedBody.length;
}
}
private static class ServletInputStreamImpl extends ServletInputStream {
private final InputStream inputStream;
public ServletInputStreamImpl(ByteArrayInputStream byteArrayInputStream) {
this.inputStream = byteArrayInputStream;
}
@Override
public boolean isFinished() {
try {
return inputStream.available() == 0;
} catch (IOException e) {
return true;
}
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
// Do nothing
}
@Override
public int read() throws IOException {
return inputStream.read();
}
}
}

@ -0,0 +1,95 @@
package com.mfsys.common.configuration.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mfsys.common.configuration.constant.FilterPriority;
import com.mfsys.common.configuration.model.Logger;
import com.mfsys.common.configuration.repository.LoggerRepository;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
@Component
@Order(FilterPriority.LOGGING)
public class LoggingFilter extends OncePerRequestFilter {
private final LoggerRepository loggerRepo;
private final ObjectMapper objectMapper;
@Autowired
public LoggingFilter(LoggerRepository loggerRepo) {
this.loggerRepo = loggerRepo;
this.objectMapper = new ObjectMapper();
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
filterChain.doFilter(request, response);
return;
}
// Read request body safely
String requestBody = getRequestBody(request);
// Save start time
LocalDateTime startTime = LocalDateTime.now();
// Continue request processing
filterChain.doFilter(request, response);
try {
Logger log = new Logger();
log.setDateTime(startTime);
log.setMethod(request.getMethod());
log.setRequestUri(request.getRequestURI());
log.setRequestBody(requestBody);
log.setRemoteIp(request.getRemoteAddr());
log.setResponseCode(response.getStatus());
// Try to extract userId from header or session
String userId = request.getHeader("X-USER-ID");
if (userId == null || userId.isEmpty()) {
userId = "ANONYMOUS";
}
log.setUserId(userId);
loggerRepo.save(log);
} catch (Exception e) {
System.err.println("Failed to save log: " + e.getMessage());
e.printStackTrace();
}
}
private String getRequestBody(HttpServletRequest request) {
try {
if (!("POST".equalsIgnoreCase(request.getMethod()) ||
"PUT".equalsIgnoreCase(request.getMethod()) ||
"PATCH".equalsIgnoreCase(request.getMethod()))) {
return "{}";
}
int contentLength = request.getContentLength();
if (contentLength <= 0) {
return "{}";
}
String body = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);
return (body != null && !body.trim().isEmpty()) ? body : "{}";
} catch (IOException e) {
return "Error reading request body: " + e.getMessage();
}
}
}

@ -0,0 +1,70 @@
package com.mfsys.common.configuration.filter;
import java.io.IOException;
import java.util.Objects;
import com.mfsys.common.configuration.constant.PropertyConstant;
import com.mfsys.common.configuration.constant.TokenBypassURI;
import com.mfsys.common.configuration.service.JwtService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import com.mfsys.common.configuration.constant.FilterPriority;
@Component
@Order(FilterPriority.AUTHENTICATION)
public class TokenAuthenticationFilter extends OncePerRequestFilter {
private JwtService jwtService;
@Autowired
public TokenAuthenticationFilter(JwtService jwtService) {
this.jwtService = jwtService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// TODO: For porOrga-change we Will removed it later
if (!(request.getMethod().equals("OPTIONS"))) {
System.out.println(">> " + request.getRequestURI() + " <<");
// TODO:
// important add all mconnect url in tokenbypass uri and remove this if
// condition or implement jwt in mconnect module
System.out.println(request.getHeaderNames());
if (!(TokenBypassURI.URIs.contains(request.getRequestURI()) || request.getRequestURI().startsWith("/MCONNECT/actuator"))) {
String token = parseJwt(request);
if (Objects.isNull(token)) {
response.setStatus(403);
return;
} else {
// String porOrgacode = request.getHeader(FormPropertyConst.POR_ORGACODE);
String userSubject = request.getHeader("userSubject");
if (!jwtService.validateToken(token,userSubject)) {
return;
}
}
}
filterChain.doFilter(request, response);
}
}
private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader("Authorization");
if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
return headerAuth.substring(7, headerAuth.length());
}
return null;
}
}

@ -0,0 +1,41 @@
package com.mfsys.common.configuration.model;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Entity
@Table(name = "TBL_LOGS")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Logger {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "METHOD", nullable = false, length = 10)
private String method;
@Column(name = "REQUEST_URI", nullable = false, length = 200)
private String requestUri;
@Column(name = "REQUEST_BODY", length = 4000)
private String requestBody;
@Column(name = "REMOTE_IP", nullable = false, length = 50)
private String remoteIp;
@Column(name = "RESPONSE_CODE", nullable = false)
private Integer responseCode;
@Column(name = "DATE_TIME", nullable = false)
private LocalDateTime dateTime;
@Column(name = "USER_ID", nullable = false, length = 50)
private String userId;
}

@ -0,0 +1,13 @@
package com.mfsys.common.configuration.repository;
import com.mfsys.common.configuration.model.Logger;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.time.LocalDateTime;
import java.util.List;
@Repository
public interface LoggerRepository extends JpaRepository<Logger, Integer> {
List<Logger> findByDateTimeBetween(LocalDateTime fromDateTime, LocalDateTime toDateTime);
}

@ -0,0 +1,98 @@
package com.mfsys.common.configuration.service;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@Service
public class JwtService {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
@Value("${jwt.refresh-expiration}")
private Long refreshExpiration;
public String extractUsername(String token) {
return extractClaim(token, Claims::getSubject);
}
public Date extractExpiration(String token) {
return extractClaim(token, Claims::getExpiration);
}
public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}
private Claims extractAllClaims(String token) {
try {
return Jwts.parser()
.verifyWith((SecretKey) getSigningKey())
.build()
.parseSignedClaims(token)
.getPayload();
} catch (JwtException e) {
throw new RuntimeException("Invalid JWT token", e);
}
}
private Boolean isTokenExpired(String token) {
return extractExpiration(token).before(new Date());
}
public String generateToken(String subject) {
Map<String, Object> claims = new HashMap<>();
return createToken(claims, subject, expiration);
}
public String generateRefreshToken(String subject) {
Map<String, Object> claims = new HashMap<>();
return createToken(claims, subject, refreshExpiration);
}
private String createToken(Map<String, Object> claims, String subject, Long expiration) {
Instant now = Instant.now();
return Jwts.builder()
.claims(claims)
.subject(subject)
.issuedAt(Date.from(now))
.expiration(Date.from(now.plusMillis(expiration)))
.signWith(getSigningKey())
.compact();
}
public Boolean validateToken(String token, String subject) {
final String username = extractUsername(token);
return (username.equals(subject) && !isTokenExpired(token));
}
public Boolean isTokenValid(String token) {
try {
return !isTokenExpired(token);
} catch (Exception e) {
return false;
}
}
private Key getSigningKey() {
byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
return Keys.hmacShaKeyFor(keyBytes);
}
}

@ -0,0 +1,30 @@
package com.mfsys.common.configuration.service;
import com.mfsys.common.configuration.model.Logger;
import com.mfsys.common.configuration.repository.LoggerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
@Service
public class LoggerService {
LoggerRepository loggerRepository;
@Autowired
public LoggerService(LoggerRepository loggerRepository) {
this.loggerRepository = loggerRepository;
}
public List<Logger> findLogsBetweenDates(LocalDate fromDate, LocalDate toDate) {
// Convert LocalDate to LocalDateTime (start of day to end of day)
LocalDateTime fromDateTime = fromDate.atStartOfDay();
LocalDateTime toDateTime = toDate.atTime(LocalTime.MAX);
return loggerRepository.findByDateTimeBetween(fromDateTime, toDateTime);
}
}

@ -0,0 +1,17 @@
package com.mfsys.common.configuration.service;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.stereotype.Service;
@Service
public class PasswordEncryptionService {
public String hashPassword(String plainPassword) {
return BCrypt.hashpw(plainPassword, BCrypt.gensalt(12));
}
public static boolean verifyPassword(String plainPassword, String hashedPassword) {
return BCrypt.checkpw(plainPassword, hashedPassword);
}
}

@ -0,0 +1,142 @@
package com.mfsys.common.configuration.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.databind.Module;
@Component
public class JSONUtil {
protected final ObjectMapper mapper;
private JSONUtil(Module... modules) {
mapper = new ObjectMapper();
mapper.registerModules(modules);
}
public <T> List<T> convertJSONDataToList(InputStream inStream, Class<T> tClass) {
CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, tClass);
try {
return mapper.readValue(inStream, listType);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public <T> List<T> convertJSONDataToList(String data, Class<T> tClass) {
CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, tClass);
try {
return mapper.readValue(data, listType);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public <K, V> Map<K, V> convertJSONDataToMap(String data, TypeReference<? extends Map<K, V>> typeRef) {
try {
return mapper.readValue(data, typeRef);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public String toJsonString(Object o) {
try {
return mapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public <T> T toObject(String json, Class<T> c) {
try {
return mapper.readValue(json, c);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public <T> T toObject(Map<String, Object> map, Class<T> c) {
return mapper.convertValue(map, c);
}
public Map<String, Object> toHashMap(Object o) {
return mapper.convertValue(o, new TypeReference<HashMap<String, Object>>() {
});
}
public static JSONUtilBuilder custom() {
return new JSONUtilBuilder();
}
public static class JSONUtilBuilder {
// private static Map<Class<?>, JsonSerializer<Object>> serializer = new HashMap<>();
// private static Map<Class , JsonDeserializer<?>> deSerializer = new HashMap<>();
private List<Serializer> serializers = new ArrayList<>();
private List<Deserializer> deserializers = new ArrayList<>();
public JSONUtilBuilder() {
}
public <T> JSONUtilBuilder addSerializer(Class<T> c, JsonSerializer<T> obj) {
serializers.add(new Serializer<T>(c, obj));
return this;
}
public <T> JSONUtilBuilder addDeserializer(Class<T> c, JsonDeserializer<T> obj) {
deserializers.add(new Deserializer<T>(c, obj));
return this;
}
public JSONUtil build() {
final SimpleModule module = new SimpleModule();
serializers.forEach((k) -> module.addSerializer(k.serClass, k.serImpl));
deserializers.forEach((k) -> module.addDeserializer(k.deserClass, k.deserImpl));
return new JSONUtil(module, new JavaTimeModule());
}
private class Serializer<T> {
Class<T> serClass;
JsonSerializer<T> serImpl;
Serializer(Class<T> serClass, JsonSerializer<T> serImpl) {
this.serClass = serClass;
this.serImpl = serImpl;
}
}
private static class Deserializer<T> {
Class<T> deserClass;
JsonDeserializer<T> deserImpl;
Deserializer(Class<T> deserClass, JsonDeserializer<T> obj) {
this.deserClass = deserClass;
this.deserImpl = obj;
}
}
}
}

@ -0,0 +1,19 @@
# 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
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip

259
parent/mvnw vendored

@ -0,0 +1,259 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# 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
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.3.2
#
# Optional ENV vars
# -----------------
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
# MVNW_REPOURL - repo url base for downloading maven distribution
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN* | MINGW*)
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
native_path() { cygpath --path --windows "$1"; }
;;
esac
# set JAVACMD and JAVACCMD
set_java_home() {
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
if [ -n "${JAVA_HOME-}" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACCMD="$JAVA_HOME/jre/sh/javac"
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACCMD="$JAVA_HOME/bin/javac"
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
return 1
fi
fi
else
JAVACMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v java
)" || :
JAVACCMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v javac
)" || :
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
return 1
fi
fi
}
# hash string like Java String::hashCode
hash_string() {
str="${1:-}" h=0
while [ -n "$str" ]; do
char="${str%"${str#?}"}"
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
str="${str#?}"
done
printf %x\\n $h
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
die() {
printf %s\\n "$1" >&2
exit 1
}
trim() {
# MWRAPPER-139:
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
# Needed for removing poorly interpreted newline sequences when running in more
# exotic environments such as mingw bash on Windows.
printf "%s" "${1}" | tr -d '[:space:]'
}
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
case "${key-}" in
distributionUrl) distributionUrl=$(trim "${value-}") ;;
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
esac
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
*)
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
distributionPlatform=linux-amd64
;;
esac
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
;;
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
trap clean HUP INT TERM EXIT
else
die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
distributionUrl="${distributionUrl%.zip}.tar.gz"
distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
verbose "Found wget ... using wget"
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
verbose "Found curl ... using curl"
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
verbose "Falling back to use Java to download"
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
cat >"$javaSource" <<-END
public class Downloader extends java.net.Authenticator
{
protected java.net.PasswordAuthentication getPasswordAuthentication()
{
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
}
public static void main( String[] args ) throws Exception
{
setDefault( new Downloader() );
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
}
}
END
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
verbose " - Compiling Downloader.java ..."
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
verbose " - Running Downloader.java ..."
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
distributionSha256Result=false
if [ "$MVN_CMD" = mvnd.sh ]; then
echo "Checksum validation is not supported for maven-mvnd." >&2
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
elif command -v sha256sum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
elif command -v shasum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
fi
if [ $distributionSha256Result = false ]; then
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
exit 1
fi
fi
# unzip and move
if command -v unzip >/dev/null; then
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
clean || :
exec_maven "$@"

149
parent/mvnw.cmd vendored

@ -0,0 +1,149 @@
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.3.2
@REM
@REM Optional ENV vars
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
if ($env:MAVEN_USER_HOME) {
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
}
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
}
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mfsys</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
<name>parent</name>
<packaging>pom</packaging>
<description>aConnect Project</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
</properties>
<modules>
<module>../common</module>
<module>../aconnect</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.21.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
Loading…
Cancel
Save