diff --git a/services/pic-sure-auth-microapp/.github/release.yml b/services/pic-sure-auth-microapp/.github/release.yml
new file mode 100644
index 000000000..0db6cd02d
--- /dev/null
+++ b/services/pic-sure-auth-microapp/.github/release.yml
@@ -0,0 +1,20 @@
+changelog:
+ exclude:
+ labels:
+ - ignore-for-release
+ categories:
+ - title: Breaking Changes
+ labels:
+ - breaking-change
+ - title: Features
+ labels:
+ - feature
+ - title: Enhancements
+ labels:
+ - enhancement
+ - title: Bug Fixes
+ labels:
+ - bug
+ - title: Other Changes
+ labels:
+ - "*"
diff --git a/services/pic-sure-auth-microapp/.github/workflows/github-actions-test.yml b/services/pic-sure-auth-microapp/.github/workflows/github-actions-test.yml
new file mode 100644
index 000000000..f81f41466
--- /dev/null
+++ b/services/pic-sure-auth-microapp/.github/workflows/github-actions-test.yml
@@ -0,0 +1,23 @@
+name: Maven Run Tests
+
+on:
+ push:
+ branches: [ "main", "release" ]
+ pull_request:
+ branches: [ "main", "release" ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
+ - name: Set up JDK 25
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0
+ with:
+ java-version: '25'
+ distribution: 'temurin'
+ - name: Test with Maven
+ run: mvn test
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/.github/workflows/label-checker.yml b/services/pic-sure-auth-microapp/.github/workflows/label-checker.yml
new file mode 100644
index 000000000..4806967a4
--- /dev/null
+++ b/services/pic-sure-auth-microapp/.github/workflows/label-checker.yml
@@ -0,0 +1,21 @@
+name: Label Checker
+on:
+ pull_request:
+ types:
+ - opened
+ - synchronize
+ - reopened
+ - labeled
+ - unlabeled
+
+jobs:
+
+ check_labels:
+ name: Check labels
+ runs-on: ubuntu-latest
+ steps:
+ - uses: agilepathway/label-checker@c3d16ad512e7cea5961df85ff2486bb774caf3c5 # v1.6.65
+ with:
+ one_of: breaking-change,enhancement,bug,documentation,ignore-for-release,dependencies
+ repo_token: ${{ secrets.GITHUB_TOKEN }}
+
diff --git a/services/pic-sure-auth-microapp/.gitignore b/services/pic-sure-auth-microapp/.gitignore
new file mode 100644
index 000000000..ca3c22122
--- /dev/null
+++ b/services/pic-sure-auth-microapp/.gitignore
@@ -0,0 +1,37 @@
+target/
+.idea/
+.vscode/
+*.iml
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+
+# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
+!/.mvn/wrapper/maven-wrapper.jar
+
+
+httpd/pic-sure-auth-ui-webapp.zip
+
+.project
+.settings/
+.classpath
+.vscode/
+
+.env
+.DS_Store
+.idea
+
+.docker-compose.yml.swp
+pic-sure-auth-services.war
+pic-sure-auth-services.war.deployed
+*.war
+*.deployed
+*.failed
+
+.m2
+!.m2/README.md
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/.m2/README.md b/services/pic-sure-auth-microapp/.m2/README.md
new file mode 100644
index 000000000..c6bc8a5a4
--- /dev/null
+++ b/services/pic-sure-auth-microapp/.m2/README.md
@@ -0,0 +1,4 @@
+The .m2 dir is used to pass proxy args to Jenkins
+for environments that access the outside internet via
+an HTTP proxy
+
diff --git a/services/pic-sure-auth-microapp/.sdkmanrc b/services/pic-sure-auth-microapp/.sdkmanrc
new file mode 100644
index 000000000..6217ebafd
--- /dev/null
+++ b/services/pic-sure-auth-microapp/.sdkmanrc
@@ -0,0 +1 @@
+java=24.0.2-tem
diff --git a/services/pic-sure-auth-microapp/CODE_OF_CONDUCT.md b/services/pic-sure-auth-microapp/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..e0cf97b8f
--- /dev/null
+++ b/services/pic-sure-auth-microapp/CODE_OF_CONDUCT.md
@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+avillach_lab_developers@googlegroups.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/services/pic-sure-auth-microapp/Jenkinsfile.fence b/services/pic-sure-auth-microapp/Jenkinsfile.fence
new file mode 100644
index 000000000..b4e38ce8d
--- /dev/null
+++ b/services/pic-sure-auth-microapp/Jenkinsfile.fence
@@ -0,0 +1,55 @@
+pipeline {
+ agent any
+
+ parameters {
+ string(name: 'DOCKER_REGISTRY', description: 'Docker registry URL (e.g., ECR URL)', defaultValue: 'hms-dbmi')
+ string(name: 'REPOSITORY_NAME', description: 'Docker repository name', defaultValue: 'psama')
+ string(name: 'DATASOURCE_URL', description: 'Datasource URL', defaultValue: '${database_host_address}')
+ string(name: 'DATASOURCE_USERNAME', description: 'Datasource username', defaultValue: '${database_app_user_secret_name}')
+ string(name: 'STACK_SPECIFIC_APPLICATION_ID', description: 'Application ID for base query', defaultValue: '${application_id_for_base_query}')
+ string(name: 'TARGET_STACK', description: 'Target stack for application deployment.')
+ string(name: 'STACK_S3_BUCKET', description: 'The s3 bucket', defaultValue: '${stack_s3_bucket}')
+ }
+
+ environment {
+ DOCKER_BUILD_ARGS = "-f ./pic-sure-auth-services/bdc.Dockerfile"
+ GIT_BRANCH_SHORT = sh(script: 'echo ${GIT_BRANCH} | cut -d "/" -f 2', returnStdout: true).trim()
+ GIT_COMMIT_SHORT = sh(script: 'echo ${GIT_COMMIT} | cut -c1-7', returnStdout: true).trim()
+ IMAGE_TAG = "${GIT_BRANCH_SHORT}_${GIT_COMMIT_SHORT}"
+ LATEST_TAG = "latest"
+ }
+
+ stages {
+ stage('Maven Build') {
+ steps {
+ sh '''docker run --rm \
+ -v "/var/jenkins_home/workspace/${JOB_NAME}/:/app:z" \
+ -v maven_m2_cache:/root/.m2 \
+ -w /app \
+ --platform=linux/amd64 \
+ maven:3.9-amazoncorretto-25 \
+ sh -lc "mvn clean install -DskipTests"'''
+ }
+ }
+
+ stage('Build Docker Image') {
+ steps {
+ script {
+ // Define the build args
+ def buildArgs = " --build-arg DATASOURCE_URL=${env.DATASOURCE_URL} " +
+ " --build-arg DATASOURCE_USERNAME=${env.DATASOURCE_USERNAME} " +
+ " --build-arg STACK_SPECIFIC_APPLICATION_ID=${env.STACK_SPECIFIC_APPLICATION_ID} "
+
+ sh "docker build --load ${DOCKER_BUILD_ARGS} ${buildArgs} -t ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${IMAGE_TAG} ."
+ sh "docker tag ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${IMAGE_TAG} ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${LATEST_TAG}"
+ }
+ }
+ }
+ stage('Deploy Docker Image') {
+ steps {
+ sh "docker save ${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}:${LATEST_TAG} | gzip > psama.tar.gz"
+ sh "aws s3 --sse=AES256 cp psama.tar.gz s3://$STACK_S3_BUCKET/$TARGET_STACK/containers/psama.tar.gz"
+ }
+ }
+ }
+}
diff --git a/services/pic-sure-auth-microapp/LICENSE b/services/pic-sure-auth-microapp/LICENSE
new file mode 100644
index 000000000..261eeb9e9
--- /dev/null
+++ b/services/pic-sure-auth-microapp/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
diff --git a/services/pic-sure-auth-microapp/README.md b/services/pic-sure-auth-microapp/README.md
new file mode 100644
index 000000000..6c0a8c6ca
--- /dev/null
+++ b/services/pic-sure-auth-microapp/README.md
@@ -0,0 +1,66 @@
+# PIC-SURE Auth MicroApp
+
+### Local Development
+At present, local development is conducted using our [All-In-One](https://github.com/hms-dbmi/pic-sure-all-in-one) Virtual Box. We offer implementations for both [CentOS](https://github.com/hms-dbmi/pic-sure-all-in-one/tree/master) and [Redhat](https://github.com/hms-dbmi/pic-sure-all-in-one/tree/feature/redhat) based operating systems. To get started, please consult the [README](https://github.com/hms-dbmi/pic-sure-all-in-one/tree/master#readme) section of the [All-In-One](https://github.com/hms-dbmi/pic-sure-all-in-one) repository.
+
+Before contributing code, please set up our git hook:
+`cp code-formatting/pre-commit.sh .git/hooks/pre-commit`
+To skip formatting on a block of code, wrap in `spotless:off`, `spotless:on` comments
+
+
+
+#### To add an initial top admin user in the system
+If you follow the steps above, spins up the docker containers and you can see the login page in the browser, you are almost there.
+
+You just need to add a top admin user in the system to be able to play with all features.
+
+There is a sql script in source code for adding the top admin user with some initial setup, you can import the script
+into your database.
+
+Open the file under `/{{root_pic-sure-auth-microapp}}/pic-sure-auth-db/db/tools/first_time_run_the_system_and_insert_admin_user.sql`,
+modify the configuration data - `@user_email` with your own google email
+
+#### Terms of Service
+
+The content of the terms of service is stored in the termsOfService table in the database. This is html that is rendered on the page.
+Some example termsOfService content would be:
+
+```aidl
+These are the terms of service.
+
+This box must be checked
+
+
+
+```
+
+#### Email templates configuration
+
+PSAMA has mechanism of sending various emails to the users and admins depending of the action.
+MailService.class is responsible for compiling Mustache templates and populating it with required information based on parameters. There are few settings configured in standalone.xml for that.
+
+Email Template Path is where email templates could be stored, so that it can be configured per stack if needed.
+```
+
+```
+Email Template Path can be mapped as a volume in a container, so that application can discover it, where directory matching the one from standalone.xml:
+```
+volumes:
+ - $PWD/config/psama/emailTemplates:/usr/local/shared/applications
+```
+
+Denied Email Enabled is flag to enable sending email to admin if user has not been added to system and trying to login.
+```
+
+```
+
+List of admin email configured as below. Provide comma separated list of admin.
+```
+
+```
diff --git a/services/pic-sure-auth-microapp/cache.http b/services/pic-sure-auth-microapp/cache.http
new file mode 100644
index 000000000..8b380736c
--- /dev/null
+++ b/services/pic-sure-auth-microapp/cache.http
@@ -0,0 +1,12 @@
+# This class can be used to interact with the CacheController in the PSAMA API
+# The CacheController must be enable in the application.properties file
+# You can enable it by setting the following property:
+# app.cache.inspect.enabled=true
+# If you are using a environment variable to set the property, you can set it like this:
+# CACHE_INSPECT_ENABLED=true
+
+### GET /cache - Get a list of all caches in the application
+GET https://dev.picsure.biodatacatalyst.nhlbi.nih.gov/psama/cache
+
+### GET /cache/{cacheName} - Get the contents of a specific cache
+GET https://dev.picsure.biodatacatalyst.nhlbi.nih.gov/psama/cache/mergedRulesCache
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/code-formatting/eclipse-formatter.xml b/services/pic-sure-auth-microapp/code-formatting/eclipse-formatter.xml
new file mode 100644
index 000000000..e7cfababf
--- /dev/null
+++ b/services/pic-sure-auth-microapp/code-formatting/eclipse-formatter.xml
@@ -0,0 +1,402 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/services/pic-sure-auth-microapp/code-formatting/pre-commit.sh b/services/pic-sure-auth-microapp/code-formatting/pre-commit.sh
new file mode 100755
index 000000000..ed051d182
--- /dev/null
+++ b/services/pic-sure-auth-microapp/code-formatting/pre-commit.sh
@@ -0,0 +1,28 @@
+#!/bin/sh -e
+CWD=$(pwd)
+cd $(git rev-parse --show-toplevel)
+format_cmd=""
+
+# skip if NO_VERIFY env var set
+if [ "$NO_VERIFY" ]; then
+ echo 'code formatting skipped' 1>&2
+ exit 0
+fi
+
+# I'm not great at bash, so this is a bit ugly, but I'll explain each pipe
+# 1. Get all staged files
+# 2. Reduce to just .java files
+# 3. Replace newlines with commas (this was really hard to do in sed)
+# 4. Replace commas with $,^.*
+# 5. Crop off the last 4 chars
+# This results in foo.java$,^.*bar.java$,^.*baz.java$
+# I then append ^.* to the beginning of that.
+STAGED_JAVA_FILES_AS_REGEX=$(git diff --staged --name-only --diff-filter=ACMR | grep '.java$' | tr '\n' ',' | sed -e 's/,/$,^.*/g' | sed 's/.\{4\}$//')
+FILES_TO_RESTAGE=$(git diff --staged --name-only --diff-filter=ACMR)
+if [ -n "$STAGED_JAVA_FILES_AS_REGEX" ]; then
+ echo "Found the following staged java files to format: $STAGED_JAVA_FILES_AS_REGEX"
+ mvn spotless:apply -DspotlessFiles=^.*$STAGED_JAVA_FILES_AS_REGEX
+ git add $FILES_TO_RESTAGE
+fi
+
+cd $CWD
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/config/psama/bdc/psama-db-config.properties b/services/pic-sure-auth-microapp/config/psama/bdc/psama-db-config.properties
new file mode 100644
index 000000000..4d0461862
--- /dev/null
+++ b/services/pic-sure-auth-microapp/config/psama/bdc/psama-db-config.properties
@@ -0,0 +1,4 @@
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
+spring.datasource.driver-class-name=com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver
+spring.datasource.url=jdbc-secretsmanager:mysql://${DATASOURCE_URL}/auth?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&autoReconnectForPools=true
+spring.datasource.username=${DATASOURCE_USERNAME}
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/config/psama/emailTemplates/accessEmail.mustache b/services/pic-sure-auth-microapp/config/psama/emailTemplates/accessEmail.mustache
new file mode 100644
index 000000000..8b699bc69
--- /dev/null
+++ b/services/pic-sure-auth-microapp/config/psama/emailTemplates/accessEmail.mustache
@@ -0,0 +1,17 @@
+Access Changed:
+
+{{#rolesExists}}
+You have been granted access to {{systemName}} with the following roles:
+{{/rolesExists}}
+{{#roles}}
+{{name}} : {{#privileges}} {{description}} {{/privileges}}
+{{/roles}}
+{{^roles}}
+Currently NO roles have been granted for you to {{systemName}}.
+{{/roles}}
+ {{#documentation}}
+You can find documentation at the following links:
+ {{.}}
+{{/documentation}}
+
+Have a good day!
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/config/psama/emailTemplates/deniedAccessEmail.mustache b/services/pic-sure-auth-microapp/config/psama/emailTemplates/deniedAccessEmail.mustache
new file mode 100644
index 000000000..abab886ba
--- /dev/null
+++ b/services/pic-sure-auth-microapp/config/psama/emailTemplates/deniedAccessEmail.mustache
@@ -0,0 +1,6 @@
+The following user has been denied access to the {{systemName}} environment because their user has not been configured.
+
+First Name : {{given_name}}
+Last Name : {{family_name}}
+Email : {{email}}
+ID : {{nickname}}
diff --git a/services/pic-sure-auth-microapp/config/psama/psama.env b/services/pic-sure-auth-microapp/config/psama/psama.env
new file mode 100644
index 000000000..9c519b745
--- /dev/null
+++ b/services/pic-sure-auth-microapp/config/psama/psama.env
@@ -0,0 +1,32 @@
+# This is a template file that can be used to configure the application. Pass this to the dockerfile and
+# the application will be configured with the values provided in this file.
+
+# These properties are used to configure our applications JWT token.
+# The JWT token is used to authenticate the user and authorize them to access the application
+# after initial login.
+APPLICATION_CLIENT_SECRET=
+APPLICATION_CLIENT_SECRET_IS_BASE_64=false
+STACK_SPECIFIC_APPLICATION_ID=
+
+# Fence IDP Configuration
+FENCE_IDP_PROVIDER_IS_ENABLED=false
+FENCE_CLIENT_ID=
+FENCE_CLIENT_SECRET=
+FENCE_IDP_PROVIDER_URI=
+
+# AIM AHEAD Authorized Access (A4) OKTA IDP Configuration
+A4_OKTA_IDP_PROVIDER_IS_ENABLED=false
+A4_OKTA_CLIENT_SECRET=
+A4_OKTA_CLIENT_ID=
+A4_OKTA_CONNECTION_ID=
+A4_OKTA_IDP_PROVIDER_URI=
+
+# Auth0 IDP Configuration (Generally, this is used for the All-In-One and Authorized Access)
+AUTH0_IDP_PROVIDER_IS_ENABLED=false
+AUTH0_HOST=
+AUTH0_DENIED_EMAIL_ENABLED=
+
+# Open Access IDP Configuration
+OPEN_IDP_PROVIDER_IS_ENABLED=false
+
+SYSTEM_NAME=PIC-SURE BioDataCatalyst
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/docker-compose.dev.yml b/services/pic-sure-auth-microapp/docker-compose.dev.yml
new file mode 100644
index 000000000..4fba9d733
--- /dev/null
+++ b/services/pic-sure-auth-microapp/docker-compose.dev.yml
@@ -0,0 +1,52 @@
+version: '3.8'
+services:
+ pic-sure-auth-service:
+ build:
+ context: .
+ dockerfile: ./pic-sure-auth-services/dev.Dockerfile
+ environment:
+ JAVA_OPTS: "-Xmx1024m -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
+ # Note: To use this you will need to set ENVIRONMENT variables for the application.properties
+ ports:
+ - "8090:8090" # Application port
+ - "5005:5005" # Debug port
+ depends_on:
+ auth-flyway:
+ condition: service_started
+
+ picsure-db:
+ build:
+ context: ./pic-sure-auth-db/
+ dockerfile: Dockerfile
+ environment:
+ MYSQL_DATABASE: auth
+ MYSQL_ROOT_PASSWORD: password
+ ports:
+ - "3306:3306" # MySQL port
+ command:
+ - --default-authentication-plugin=mysql_native_password # Required for MySQL 8.0
+ healthcheck:
+ test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+ auth-flyway:
+ image: flyway/flyway:latest
+ volumes:
+ - ./pic-sure-auth-db/db/sql:/flyway/sql
+ # linux/amd64
+ platform: linux/amd64
+ environment:
+ - FLYWAY_URL=jdbc:mysql://picsure-db:3306/auth?useSSL=false
+ - FLYWAY_USER=root
+ - FLYWAY_PASSWORD=password
+ - FLYWAY_SCHEMAS=auth
+ - FLYWAY_LOCATIONS=filesystem:/flyway/sql
+ - FLYWAY_IGNORE_MISSING_MIGRATIONS=true
+ - FLYWAY_BASELINE_ON_MIGRATE=true
+ command:
+ - migrate
+ depends_on:
+ picsure-db:
+ condition: service_healthy
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/docker-compose.yml b/services/pic-sure-auth-microapp/docker-compose.yml
new file mode 100644
index 000000000..2e121f1cb
--- /dev/null
+++ b/services/pic-sure-auth-microapp/docker-compose.yml
@@ -0,0 +1,52 @@
+version: '3'
+services:
+ picsureauth:
+ build:
+ context: pic-sure-auth-services
+ dockerfile: Dockerfile
+ command: --debug *:8787
+ depends_on:
+ - picsureauthdb
+ environment:
+ - AUTH_CLIENT_SECRET=${AUTH_CLIENT_SECRET:-secret}
+ - AUTH_CLIENT_ID=${AUTH_CLIENT_ID:-client_id}
+ - AUTH_USER_ID_CLAIM=sub
+ - AUTH_MYSQLADDRESS=picsureauthdb
+ - AUTH0TOKEN=${AUTH0TOKEN:-nothing}
+ - AUTH0HOST=https://avillachlab.auth0.com
+ - systemName=${systemName:-PICSURE}
+ - EMAIL_TEMPLATE_PATH=${EMAIL_TEMPLATE_PATH:-/opt/jboss/wildfly/emailTemplates}/
+ - DENIED_EMAIL_ENABLED=${DENIED_EMAIL_ENABLED:-false}
+ - COMMA_SEPARATED_EMAILS=${COMMA_SEPARATED_EMAILS:-dummyemail}
+ - accessGrantEmailSubject=Testing
+ - MAIL_USERNAME=${MAIL_USERNAME:-emailuser@avillach.lab}
+ - MAIL_PASSWORD=${MAIL_PASSWORD:-email_password}
+ - TOS_ENABLED:false
+ ports:
+ - 8787:8787
+ expose:
+ - 8080
+ volumes:
+ - ./pic-sure-auth-services/src/main/resources/emailTemplates:${EMAIL_TEMPLATE_PATH:-/opt/jboss/wildfly/emailTemplates}
+ networks:
+ - public
+ env_file:
+ - .env
+
+ picsureauthdb:
+ build:
+ context: pic-sure-auth-db
+ dockerfile: Dockerfile
+ environment:
+ - MYSQL_ROOT_PASSWORD=${AUTH_MYSQL_ROOT_PASSWORD:-password}
+ - MYSQL_DATABASE=auth
+ restart: always
+ expose:
+ - 3306
+ ports:
+ - 3306:3306
+ networks:
+ - public
+
+networks:
+ public:
diff --git a/services/pic-sure-auth-microapp/jenkinsfile b/services/pic-sure-auth-microapp/jenkinsfile
new file mode 100644
index 000000000..9ad27b9eb
--- /dev/null
+++ b/services/pic-sure-auth-microapp/jenkinsfile
@@ -0,0 +1,83 @@
+pipeline {
+ agent any
+
+ parameters {
+ string(name: 'DOCKER_REGISTRY', description: 'Docker registry URL (e.g., ECR URL)', defaultValue: 'hms-dbmi')
+ string(name: 'REPOSITORY_NAME', description: 'Docker repository name', defaultValue: 'psama')
+ booleanParam(name: 'DEPLOY', description: 'Deploy the image to the registry', defaultValue: true)
+ }
+
+ environment {
+ LATEST_TAG = "LATEST"
+ EMAIL_TEMPLATE_VOLUME = "-v $DOCKER_CONFIG_DIR/wildfly/emailTemplates:/opt/jboss/wildfly/standalone/configuration/emailTemplates"
+ TRUSTSTORE_VOLUME = "-v $DOCKER_CONFIG_DIR/wildfly/application.truststore:/opt/jboss/wildfly/standalone/configuration/application.truststore"
+ PSAMA_OPTS = "-Xms1g -Xmx2g -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true"
+ TRUSTSTORE_JAVA_OPTS = "-Djavax.net.ssl.trustStore=/opt/jboss/wildfly/standalone/configuration/application.truststore -Djavax.net.ssl.trustStorePassword=password"
+
+ // If you need proxy args during docker build
+ DOCKER_BUILD_ARGS = "-f ./pic-sure-auth-services/Dockerfile " +
+ "--build-arg http_proxy=$http_proxy --build-arg https_proxy=$http_proxy --build-arg no_proxy=\"$no_proxy\" " +
+ "--build-arg HTTP_PROXY=$http_proxy --build-arg HTTPS_PROXY=$http_proxy --build-arg NO_PROXY=\"$no_proxy\""
+ }
+
+ stages {
+ stage('init') {
+ steps {
+ script {
+ env.GIT_BRANCH_SHORT = sh(script: 'echo "${GIT_BRANCH}" | awk -F/ \'{print $NF}\'', returnStdout: true).trim()
+ env.GIT_COMMIT_SHORT = sh(script: 'echo "${GIT_COMMIT}" | cut -c1-7', returnStdout: true).trim()
+ env.IMAGE_TAG = "${env.GIT_BRANCH_SHORT}_${env.GIT_COMMIT_SHORT}"
+ env.IMAGE_NAME = "${params.DOCKER_REGISTRY}/${params.REPOSITORY_NAME}"
+ }
+ }
+ }
+
+ stage('build jar (docker run)') {
+ steps {
+ sh '''
+ set -euo pipefail
+
+ # Build in a Maven container, output goes into the mounted workspace (target/ created here)
+ docker run --rm \
+ -v "$DOCKER_CONFIG_DIR/jenkins_home/workspace/$JOB_NAME/:/app" \
+ -v maven_m2_cache:/root/.m2 \
+ -w /app \
+ maven:3.9-amazoncorretto-25 \
+ sh -lc "mvn clean install -B -T 1C -DskipTests"
+
+ ls -lah pic-sure-auth-services/target || true
+ '''
+ }
+ }
+
+ stage('build image') {
+ steps {
+ sh '''
+ set -euo pipefail
+ docker build ${DOCKER_BUILD_ARGS} -t "${IMAGE_NAME}:${IMAGE_TAG}" .
+ docker tag "${IMAGE_NAME}:${IMAGE_TAG}" "${IMAGE_NAME}:${LATEST_TAG}"
+ '''
+ }
+ }
+
+ stage('deploy') {
+ when { expression { return params.DEPLOY } }
+ steps {
+ sh '''
+ set +e
+ docker stop psama
+ docker rm psama
+ set -e
+
+ docker run --name=psama --restart always \
+ --network=picsure \
+ --env-file /usr/local/docker-config/psama/psama.env \
+ ${EMAIL_TEMPLATE_VOLUME} \
+ ${TRUSTSTORE_VOLUME} \
+ -e JAVA_OPTS="${PSAMA_OPTS} ${TRUSTSTORE_JAVA_OPTS}" \
+ -d "${IMAGE_NAME}:${IMAGE_TAG}"
+ '''
+ }
+ }
+ }
+}
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/.gitignore b/services/pic-sure-auth-microapp/pic-sure-auth-db/.gitignore
new file mode 100644
index 000000000..ae3c17260
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/Dockerfile b/services/pic-sure-auth-microapp/pic-sure-auth-db/Dockerfile
new file mode 100644
index 000000000..b9f5cc3b2
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/Dockerfile
@@ -0,0 +1,9 @@
+FROM mysql:8.2.0
+
+RUN mkdir /tempsql/
+COPY db/picsure-auth-dump-initial.sql /tempsql/picsure-auth-dump-initial.sql
+
+EXPOSE 3306
+
+ENTRYPOINT ["docker-entrypoint.sh"]
+CMD ["mysqld","--init-file","/tempsql/picsure-auth-dump-initial.sql"]
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/create_db_auth.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/create_db_auth.sql
new file mode 100644
index 000000000..bbaa8b7dc
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/create_db_auth.sql
@@ -0,0 +1,222 @@
+DROP DATABASE IF EXISTS `auth`;
+
+CREATE DATABASE IF NOT EXISTS `auth` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;
+USE `auth`;
+-- MySQL dump 10.13 Distrib 5.7.17, for macos10.12 (x86_64)
+--
+-- Host: 127.0.0.1 Database: auth
+-- ------------------------------------------------------
+-- Server version 5.7.20
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `privilege`
+--
+
+-- DROP TABLE IF EXISTS `privilege`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `privilege` (
+ `uuid` binary(16) NOT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `application_id` binary(16) DEFAULT NULL,
+ `queryTemplate` varchar(8192) DEFAULT NULL,
+ `queryScope` varchar(512) DEFAULT NULL,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `UK_h7iwbdg4ev8mgvmij76881tx8` (`name`),
+ KEY `FK61h3jewffk70b5ni4tsi5rhoy` (`application_id`),
+ CONSTRAINT `FK61h3jewffk70b5ni4tsi5rhoy` FOREIGN KEY (`application_id`) REFERENCES `application` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `role`
+--
+
+-- DROP TABLE IF EXISTS `role`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `role` (
+ `uuid` binary(16) NOT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `role_privilege`
+--
+
+-- DROP TABLE IF EXISTS `role_privilege`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `role_privilege` (
+ `role_id` binary(16) NOT NULL,
+ `privilege_id` binary(16) NOT NULL,
+ PRIMARY KEY (`role_id`,`privilege_id`),
+ KEY `FKdkwbrwb5r8h74m1v7dqmhp99c` (`privilege_id`),
+ CONSTRAINT `FKdkwbrwb5r8h74m1v7dqmhp99c` FOREIGN KEY (`privilege_id`) REFERENCES `privilege` (`uuid`),
+ CONSTRAINT `FKsykrtrdngu5iexmbti7lu9xa` FOREIGN KEY (`role_id`) REFERENCES `role` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `user`
+--
+
+-- DROP TABLE IF EXISTS `user`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `user` (
+ `uuid` binary(16) NOT NULL,
+ `auth0_metadata` varchar(8000) COLLATE utf8_bin DEFAULT NULL,
+ `general_metadata` varchar(9000) COLLATE utf8_bin DEFAULT NULL,
+ `acceptedTOS` datetime COLLATE utf8_bin DEFAULT NULL,
+ `connectionId` binary(16) DEFAULT NULL,
+ `email` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `matched` bit(1) NOT NULL DEFAULT FALSE,
+ `subject` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `is_active` bit(1) NOT NULL DEFAULT TRUE,
+ `long_term_token` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `UK_r8xpakluitn685ua7pt8xjy9r` (`subject`),
+ UNIQUE KEY `email_UNIQUE` (`email`),
+ KEY `FKn8bku0vydfcnuwbqwgnbgg8ry` (`connectionId`),
+ CONSTRAINT `FKn8bku0vydfcnuwbqwgnbgg8ry` FOREIGN KEY (`connectionId`) REFERENCES `connection` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `userMetadataMapping`
+--
+
+-- DROP TABLE IF EXISTS `userMetadataMapping`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `userMetadataMapping` (
+ `uuid` binary(16) NOT NULL,
+ `auth0MetadataJsonPath` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `connectionId` binary(16) DEFAULT NULL,
+ `generalMetadataJsonPath` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`),
+ KEY `FKayr8vrvvwpgsdhxdyryt6k590` (`connectionId`),
+ CONSTRAINT `FKayr8vrvvwpgsdhxdyryt6k590` FOREIGN KEY (`connectionId`) REFERENCES `connection` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `user_role`
+--
+
+-- DROP TABLE IF EXISTS `user_role`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `user_role` (
+ `user_id` binary(16) NOT NULL,
+ `role_id` binary(16) NOT NULL,
+ PRIMARY KEY (`user_id`,`role_id`),
+ KEY `FKa68196081fvovjhkek5m97n3y` (`role_id`),
+ CONSTRAINT `FK859n2jvi8ivhui0rl0esws6o` FOREIGN KEY (`user_id`) REFERENCES `user` (`uuid`),
+ CONSTRAINT `FKa68196081fvovjhkek5m97n3y` FOREIGN KEY (`role_id`) REFERENCES `role` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+CREATE TABLE `termsOfService` (
+ `uuid` binary(16) NOT NULL,
+ `dateUpdated` timestamp,
+ `content` varchar(9000) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `connection` (
+ `uuid` binary(16) NOT NULL,
+ `label` varchar(255) COLLATE utf8_bin NOT NULL,
+ `id` varchar(255) COLLATE utf8_bin NOT NULL,
+ `subprefix` varchar(255) COLLATE utf8_bin NOT NULL,
+ `requiredFields` varchar(9000) COLLATE utf8_bin NOT NULL,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `id` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+CREATE TABLE `application` (
+ `uuid` binary(16) NOT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `enable` bit(1) NOT NULL DEFAULT b'1',
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `token` varchar(2000) COLLATE utf8_bin DEFAULT NULL,
+ `url` varchar(500) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `access_rule` (
+ `uuid` binary(16) NOT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `description` varchar(2000) COLLATE utf8_bin DEFAULT NULL,
+ `rule` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `type` int(11) DEFAULT NULL,
+ `value` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `checkMapKeyOnly` bit(1) NOT NULL,
+ `checkMapNode` bit(1) NOT NULL,
+ `subAccessRuleParent_uuid` binary(16) DEFAULT NULL,
+ `isGateAnyRelation` bit(1) NOT NULL,
+ `isEvaluateOnlyByGates` bit(1) NOT NULL,
+ PRIMARY KEY (`uuid`),
+ KEY `FK8rovvx363ui99ce21sksmg6uy` (`subAccessRuleParent_uuid`),
+ CONSTRAINT `FK8rovvx363ui99ce21sksmg6uy` FOREIGN KEY (`subAccessRuleParent_uuid`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `accessRule_privilege` (
+ `privilege_id` binary(16) NOT NULL,
+ `accessRule_id` binary(16) NOT NULL,
+ PRIMARY KEY (`privilege_id`,`accessRule_id`),
+ KEY `FK89rf30kbf9d246jty2dd7qk99` (`accessRule_id`),
+ CONSTRAINT `FK7x47w81gpua380qd7lp9x94l1` FOREIGN KEY (`privilege_id`) REFERENCES `privilege` (`uuid`),
+ CONSTRAINT `FK89rf30kbf9d246jty2dd7qk99` FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `accessRule_gate` (
+ `accessRule_id` binary(16) NOT NULL,
+ `gate_id` binary(16) NOT NULL,
+ PRIMARY KEY (`accessRule_id`,`gate_id`),
+ KEY `FK6re4kcq9tyl45jv9yg584doem` (`gate_id`),
+ CONSTRAINT `FK6re4kcq9tyl45jv9yg584doem` FOREIGN KEY (`gate_id`) REFERENCES `access_rule` (`uuid`),
+ CONSTRAINT `FKe6l5ee7f207958mm3anpsmqom` FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE OR REPLACE VIEW `management_view`
+AS SELECT
+ `role`.`uuid` AS `uuid`,
+ `role`.`name` AS `role_name`,
+ `privilege`.`name` AS `privilege_name`
+ FROM
+ ((`role` JOIN `role_privilege`) JOIN `privilege`)
+ WHERE
+ ((`role`.`uuid` = `role_privilege`.`role_id`)
+ AND
+ (`privilege`.`uuid` = `role_privilege`.`privilege_id`));
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2018-10-16 19:48:56
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_connection_Google.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_connection_Google.sql
new file mode 100644
index 000000000..da4de9e61
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_connection_Google.sql
@@ -0,0 +1,20 @@
+
+START TRANSACTION;
+
+SET @uuidConnection = REPLACE(uuid(),'-','');
+
+INSERT INTO `connection` (
+ `uuid`,
+ `label`,
+ `id`,
+ `subprefix`,
+ `requiredFields`
+) VALUES (
+ unhex(@uuidConnection),
+ 'Google',
+ 'google-oauth2',
+ 'google-oauth2|',
+ '[{\"label\":\"Email\", \"id\":\"email\"}]'
+);
+
+COMMIT;
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_privilege_ADMIN.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_privilege_ADMIN.sql
new file mode 100644
index 000000000..559084785
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_privilege_ADMIN.sql
@@ -0,0 +1,23 @@
+#
+# Create a connection definition in the database
+# of Google type. This example requires the Email
+# field in the authentication definition to exist
+#
+START TRANSACTION;
+
+SET @uuidPrivilege = REPLACE(uuid(),'-','');
+
+INSERT INTO `privilege` (
+ `uuid`,
+ `name`,
+ `description`,
+ `application_id`
+)
+VALUES (
+ unhex(@uuidPrivilege),
+ 'ADMIN',
+ 'PIC-SURE Auth admin for managing users.',
+ NULL
+);
+
+COMMIT;
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_privilege_SUPER_ADMIN.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_privilege_SUPER_ADMIN.sql
new file mode 100644
index 000000000..d611b7fbf
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_privilege_SUPER_ADMIN.sql
@@ -0,0 +1,23 @@
+#
+# Create a connection definition in the database
+# of Google type. This example requires the Email
+# field in the authentication definition to exist
+#
+START TRANSACTION;
+
+SET @uuidPrivilege = REPLACE(uuid(),'-','');
+
+INSERT INTO `privilege` (
+ `uuid`,
+ `name`,
+ `description`,
+ `application_id`
+)
+VALUES (
+ unhex(@uuidPrivilege),
+ 'SUPER_ADMIN',
+ 'PIC-SURE Auth super admin for managing roles/privileges/application/connections',
+ NULL
+);
+
+COMMIT;
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_role_TOPADMIN.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_role_TOPADMIN.sql
new file mode 100644
index 000000000..0962139e2
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_role_TOPADMIN.sql
@@ -0,0 +1,39 @@
+#
+# Create a role, which is a collection of privileges
+#
+START TRANSACTION;
+
+SET @uuidRole = REPLACE(uuid(),'-','');
+
+# This is an example, where the SUPERUSER role is added.
+INSERT INTO `role` (
+ `uuid`,
+ `name`,
+ `description`
+)
+VALUES (
+ unhex(@uuidRole),
+ 'PIC-SURE Top Admin',
+ 'PIC-SURE Auth Micro App Top admin including Admin and super Admin'
+);
+
+# This is an example, where the role is associated with the 'SUPER_ADMIN' privilege
+INSERT INTO `role_privilege` (
+ `role_id`,
+ `privilege_id`
+)
+VALUES (
+ unhex(@uuidRole),
+ (SELECT uuid FROM `privilege` WHERE `name` = 'SUPER_ADMIN')
+);
+
+INSERT INTO `role_privilege` (
+ `role_id`,
+ `privilege_id`
+)
+VALUES (
+ unhex(@uuidRole),
+ (SELECT uuid FROM `privilege` WHERE `name` = 'ADMIN')
+);
+
+COMMIT;
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_user_ADMINGMAIL.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_user_ADMINGMAIL.sql
new file mode 100644
index 000000000..69ccaff7e
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/insert_user_ADMINGMAIL.sql
@@ -0,0 +1,64 @@
+#
+# This script will insert the initial superuser account
+# and corresponding information into the appropriate tables.
+# Assuming, that all objects (tables and views) have been
+# created, and the initial privileges and roles have been
+# inserted into the appropriate tables already.
+#
+# Just in case clearing the underlying tables is required
+# One might execute the folloring scripts, but BEWARE that
+# these commands will remove ALL user information from
+# the database.
+#
+#
+# DELETE FROM `user_role`;
+# DELETE FROM `user`;
+# DELETE FROM `userMetadataMapping`;
+# DELETE FROM `connection`;
+#
+#
+START TRANSACTION;
+
+#configuration for connection table
+SET @uuidUser = REPLACE(uuid(),'-','');
+
+INSERT INTO user (
+ `uuid`,
+ `general_metadata`,
+ `connectionId`,
+ `matched`
+) VALUES (
+ unhex(@uuidUser),
+ "{\"email\":\"__SUPERUSER_GMAIL_ADDRESS__\"}",
+ (SELECT `uuid` FROM `connection` WHERE `label` = 'Google'),
+ false
+);
+
+# Add the initial ADMIN role for the user.
+# Assuming, that all superuser privileges have been
+# assigned to this role, already, during creation
+# of the database.
+INSERT INTO user_role (
+ `user_id`,
+ `role_id`
+) VALUES (
+ UNHEX(@uuidUser),
+ (SELECT `uuid` FROM `role` WHERE name = 'PIC-SURE Top Admin')
+);
+
+#### insert into userMetadataMapping
+SET @uuidMetaData = REPLACE(uuid(),'-','');
+
+INSERT INTO `userMetadataMapping` (
+ `uuid`,
+ `auth0MetadataJsonPath`,
+ `connectionId`,
+ `generalMetadataJsonPath`
+) VALUES (
+ unhex(@uuidMetaData),
+ '$.email',
+ (SELECT `uuid` FROM `connection` WHERE `label` = 'Google'),
+ '$.email'
+);
+
+COMMIT;
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/picsure-auth-dump-initial.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/picsure-auth-dump-initial.sql
new file mode 100644
index 000000000..37be5c779
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/picsure-auth-dump-initial.sql
@@ -0,0 +1,208 @@
+CREATE DATABASE IF NOT EXISTS `auth` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;
+USE `auth`;
+-- MySQL dump 10.13 Distrib 5.7.17, for macos10.12 (x86_64)
+--
+-- Host: 127.0.0.1 Database: auth
+-- ------------------------------------------------------
+-- Server version 5.7.20
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `privilege`
+--
+
+-- DROP TABLE IF EXISTS `privilege`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `privilege` (
+ `uuid` binary(16) NOT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `application_id` binary(16) DEFAULT NULL,
+ `queryTemplate` varchar(8192) DEFAULT NULL,
+ `queryScope` varchar(512) DEFAULT NULL,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `UK_h7iwbdg4ev8mgvmij76881tx8` (`name`),
+ KEY `FK61h3jewffk70b5ni4tsi5rhoy` (`application_id`),
+ CONSTRAINT `FK61h3jewffk70b5ni4tsi5rhoy` FOREIGN KEY (`application_id`) REFERENCES `application` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `role`
+--
+
+-- DROP TABLE IF EXISTS `role`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `role` (
+ `uuid` binary(16) NOT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `role_privilege`
+--
+
+-- DROP TABLE IF EXISTS `role_privilege`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `role_privilege` (
+ `role_id` binary(16) NOT NULL,
+ `privilege_id` binary(16) NOT NULL,
+ PRIMARY KEY (`role_id`,`privilege_id`),
+ KEY `FKdkwbrwb5r8h74m1v7dqmhp99c` (`privilege_id`),
+ CONSTRAINT `FKdkwbrwb5r8h74m1v7dqmhp99c` FOREIGN KEY (`privilege_id`) REFERENCES `privilege` (`uuid`),
+ CONSTRAINT `FKsykrtrdngu5iexmbti7lu9xa` FOREIGN KEY (`role_id`) REFERENCES `role` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `user`
+--
+
+-- DROP TABLE IF EXISTS `user`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `user` (
+ `uuid` binary(16) NOT NULL,
+ `auth0_metadata` varchar(8000) COLLATE utf8_bin DEFAULT NULL,
+ `general_metadata` varchar(9000) COLLATE utf8_bin DEFAULT NULL,
+ `acceptedTOS` datetime COLLATE utf8_bin DEFAULT NULL,
+ `connectionId` binary(16) DEFAULT NULL,
+ `email` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `matched` bit(1) NOT NULL DEFAULT FALSE,
+ `subject` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `is_active` bit(1) NOT NULL DEFAULT TRUE,
+ `long_term_token` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
+ `isGateAnyRelation` bit(1) NOT NULL DEFAULT TRUE,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `UK_r8xpakluitn685ua7pt8xjy9r` (`subject`),
+ KEY `FKn8bku0vydfcnuwbqwgnbgg8ry` (`connectionId`),
+ CONSTRAINT `FKn8bku0vydfcnuwbqwgnbgg8ry` FOREIGN KEY (`connectionId`) REFERENCES `connection` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `userMetadataMapping`
+--
+
+-- DROP TABLE IF EXISTS `userMetadataMapping`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `userMetadataMapping` (
+ `uuid` binary(16) NOT NULL,
+ `auth0MetadataJsonPath` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `connectionId` binary(16) DEFAULT NULL,
+ `generalMetadataJsonPath` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`),
+ KEY `FKayr8vrvvwpgsdhxdyryt6k590` (`connectionId`),
+ CONSTRAINT `FKayr8vrvvwpgsdhxdyryt6k590` FOREIGN KEY (`connectionId`) REFERENCES `connection` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `user_role`
+--
+
+-- DROP TABLE IF EXISTS `user_role`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `user_role` (
+ `user_id` binary(16) NOT NULL,
+ `role_id` binary(16) NOT NULL,
+ PRIMARY KEY (`user_id`,`role_id`),
+ KEY `FKa68196081fvovjhkek5m97n3y` (`role_id`),
+ CONSTRAINT `FK859n2jvi8ivhui0rl0esws6o` FOREIGN KEY (`user_id`) REFERENCES `user` (`uuid`),
+ CONSTRAINT `FKa68196081fvovjhkek5m97n3y` FOREIGN KEY (`role_id`) REFERENCES `role` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+CREATE TABLE `termsOfService` (
+ `uuid` binary(16) NOT NULL,
+ `dateUpdated` timestamp,
+ `content` varchar(9000) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `connection` (
+ `uuid` binary(16) NOT NULL,
+ `label` varchar(255) COLLATE utf8_bin NOT NULL,
+ `id` varchar(255) COLLATE utf8_bin NOT NULL,
+ `subprefix` varchar(255) COLLATE utf8_bin NOT NULL,
+ `requiredFields` varchar(9000) COLLATE utf8_bin NOT NULL,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `id` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+CREATE TABLE `application` (
+ `uuid` binary(16) NOT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `enable` bit(1) NOT NULL DEFAULT b'1',
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `token` varchar(2000) COLLATE utf8_bin DEFAULT NULL,
+ `url` varchar(500) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `access_rule` (
+ `uuid` binary(16) NOT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `description` varchar(2000) COLLATE utf8_bin DEFAULT NULL,
+ `rule` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `type` int(11) DEFAULT NULL,
+ `value` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `checkMapKeyOnly` bit(1) NOT NULL,
+ `checkMapNode` bit(1) NOT NULL,
+ `subAccessRuleParent_uuid` binary(16) DEFAULT NULL,
+ `isGateAnyRelation` bit(1) NOT NULL,
+ `isEvaluateOnlyByGates` bit(1) NOT NULL,
+ PRIMARY KEY (`uuid`),
+ KEY `FK8rovvx363ui99ce21sksmg6uy` (`subAccessRuleParent_uuid`),
+ CONSTRAINT `FK8rovvx363ui99ce21sksmg6uy` FOREIGN KEY (`subAccessRuleParent_uuid`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `accessRule_privilege` (
+ `privilege_id` binary(16) NOT NULL,
+ `accessRule_id` binary(16) NOT NULL,
+ PRIMARY KEY (`privilege_id`,`accessRule_id`),
+ KEY `FK89rf30kbf9d246jty2dd7qk99` (`accessRule_id`),
+ CONSTRAINT `FK7x47w81gpua380qd7lp9x94l1` FOREIGN KEY (`privilege_id`) REFERENCES `privilege` (`uuid`),
+ CONSTRAINT `FK89rf30kbf9d246jty2dd7qk99` FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `accessRule_gate` (
+ `accessRule_id` binary(16) NOT NULL,
+ `gate_id` binary(16) NOT NULL,
+ PRIMARY KEY (`accessRule_id`,`gate_id`),
+ KEY `FK6re4kcq9tyl45jv9yg584doem` (`gate_id`),
+ CONSTRAINT `FK6re4kcq9tyl45jv9yg584doem` FOREIGN KEY (`gate_id`) REFERENCES `access_rule` (`uuid`),
+ CONSTRAINT `FKe6l5ee7f207958mm3anpsmqom` FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2018-10-16 19:48:56
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/psama_fence_setup.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/psama_fence_setup.sql
new file mode 100644
index 000000000..37be5c779
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/psama_fence_setup.sql
@@ -0,0 +1,208 @@
+CREATE DATABASE IF NOT EXISTS `auth` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;
+USE `auth`;
+-- MySQL dump 10.13 Distrib 5.7.17, for macos10.12 (x86_64)
+--
+-- Host: 127.0.0.1 Database: auth
+-- ------------------------------------------------------
+-- Server version 5.7.20
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `privilege`
+--
+
+-- DROP TABLE IF EXISTS `privilege`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `privilege` (
+ `uuid` binary(16) NOT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `application_id` binary(16) DEFAULT NULL,
+ `queryTemplate` varchar(8192) DEFAULT NULL,
+ `queryScope` varchar(512) DEFAULT NULL,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `UK_h7iwbdg4ev8mgvmij76881tx8` (`name`),
+ KEY `FK61h3jewffk70b5ni4tsi5rhoy` (`application_id`),
+ CONSTRAINT `FK61h3jewffk70b5ni4tsi5rhoy` FOREIGN KEY (`application_id`) REFERENCES `application` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `role`
+--
+
+-- DROP TABLE IF EXISTS `role`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `role` (
+ `uuid` binary(16) NOT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `role_privilege`
+--
+
+-- DROP TABLE IF EXISTS `role_privilege`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `role_privilege` (
+ `role_id` binary(16) NOT NULL,
+ `privilege_id` binary(16) NOT NULL,
+ PRIMARY KEY (`role_id`,`privilege_id`),
+ KEY `FKdkwbrwb5r8h74m1v7dqmhp99c` (`privilege_id`),
+ CONSTRAINT `FKdkwbrwb5r8h74m1v7dqmhp99c` FOREIGN KEY (`privilege_id`) REFERENCES `privilege` (`uuid`),
+ CONSTRAINT `FKsykrtrdngu5iexmbti7lu9xa` FOREIGN KEY (`role_id`) REFERENCES `role` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `user`
+--
+
+-- DROP TABLE IF EXISTS `user`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `user` (
+ `uuid` binary(16) NOT NULL,
+ `auth0_metadata` varchar(8000) COLLATE utf8_bin DEFAULT NULL,
+ `general_metadata` varchar(9000) COLLATE utf8_bin DEFAULT NULL,
+ `acceptedTOS` datetime COLLATE utf8_bin DEFAULT NULL,
+ `connectionId` binary(16) DEFAULT NULL,
+ `email` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `matched` bit(1) NOT NULL DEFAULT FALSE,
+ `subject` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `is_active` bit(1) NOT NULL DEFAULT TRUE,
+ `long_term_token` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
+ `isGateAnyRelation` bit(1) NOT NULL DEFAULT TRUE,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `UK_r8xpakluitn685ua7pt8xjy9r` (`subject`),
+ KEY `FKn8bku0vydfcnuwbqwgnbgg8ry` (`connectionId`),
+ CONSTRAINT `FKn8bku0vydfcnuwbqwgnbgg8ry` FOREIGN KEY (`connectionId`) REFERENCES `connection` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `userMetadataMapping`
+--
+
+-- DROP TABLE IF EXISTS `userMetadataMapping`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `userMetadataMapping` (
+ `uuid` binary(16) NOT NULL,
+ `auth0MetadataJsonPath` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `connectionId` binary(16) DEFAULT NULL,
+ `generalMetadataJsonPath` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`),
+ KEY `FKayr8vrvvwpgsdhxdyryt6k590` (`connectionId`),
+ CONSTRAINT `FKayr8vrvvwpgsdhxdyryt6k590` FOREIGN KEY (`connectionId`) REFERENCES `connection` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `user_role`
+--
+
+-- DROP TABLE IF EXISTS `user_role`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `user_role` (
+ `user_id` binary(16) NOT NULL,
+ `role_id` binary(16) NOT NULL,
+ PRIMARY KEY (`user_id`,`role_id`),
+ KEY `FKa68196081fvovjhkek5m97n3y` (`role_id`),
+ CONSTRAINT `FK859n2jvi8ivhui0rl0esws6o` FOREIGN KEY (`user_id`) REFERENCES `user` (`uuid`),
+ CONSTRAINT `FKa68196081fvovjhkek5m97n3y` FOREIGN KEY (`role_id`) REFERENCES `role` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+CREATE TABLE `termsOfService` (
+ `uuid` binary(16) NOT NULL,
+ `dateUpdated` timestamp,
+ `content` varchar(9000) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `connection` (
+ `uuid` binary(16) NOT NULL,
+ `label` varchar(255) COLLATE utf8_bin NOT NULL,
+ `id` varchar(255) COLLATE utf8_bin NOT NULL,
+ `subprefix` varchar(255) COLLATE utf8_bin NOT NULL,
+ `requiredFields` varchar(9000) COLLATE utf8_bin NOT NULL,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `id` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+CREATE TABLE `application` (
+ `uuid` binary(16) NOT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `enable` bit(1) NOT NULL DEFAULT b'1',
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `token` varchar(2000) COLLATE utf8_bin DEFAULT NULL,
+ `url` varchar(500) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `access_rule` (
+ `uuid` binary(16) NOT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `description` varchar(2000) COLLATE utf8_bin DEFAULT NULL,
+ `rule` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `type` int(11) DEFAULT NULL,
+ `value` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `checkMapKeyOnly` bit(1) NOT NULL,
+ `checkMapNode` bit(1) NOT NULL,
+ `subAccessRuleParent_uuid` binary(16) DEFAULT NULL,
+ `isGateAnyRelation` bit(1) NOT NULL,
+ `isEvaluateOnlyByGates` bit(1) NOT NULL,
+ PRIMARY KEY (`uuid`),
+ KEY `FK8rovvx363ui99ce21sksmg6uy` (`subAccessRuleParent_uuid`),
+ CONSTRAINT `FK8rovvx363ui99ce21sksmg6uy` FOREIGN KEY (`subAccessRuleParent_uuid`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `accessRule_privilege` (
+ `privilege_id` binary(16) NOT NULL,
+ `accessRule_id` binary(16) NOT NULL,
+ PRIMARY KEY (`privilege_id`,`accessRule_id`),
+ KEY `FK89rf30kbf9d246jty2dd7qk99` (`accessRule_id`),
+ CONSTRAINT `FK7x47w81gpua380qd7lp9x94l1` FOREIGN KEY (`privilege_id`) REFERENCES `privilege` (`uuid`),
+ CONSTRAINT `FK89rf30kbf9d246jty2dd7qk99` FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `accessRule_gate` (
+ `accessRule_id` binary(16) NOT NULL,
+ `gate_id` binary(16) NOT NULL,
+ PRIMARY KEY (`accessRule_id`,`gate_id`),
+ KEY `FK6re4kcq9tyl45jv9yg584doem` (`gate_id`),
+ CONSTRAINT `FK6re4kcq9tyl45jv9yg584doem` FOREIGN KEY (`gate_id`) REFERENCES `access_rule` (`uuid`),
+ CONSTRAINT `FKe6l5ee7f207958mm3anpsmqom` FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2018-10-16 19:48:56
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V1__CREATE_AUTH_INITIAL.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V1__CREATE_AUTH_INITIAL.sql
new file mode 100644
index 000000000..885e45082
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V1__CREATE_AUTH_INITIAL.sql
@@ -0,0 +1,216 @@
+USE `auth`;
+-- MySQL dump 10.13 Distrib 5.7.17, for macos10.12 (x86_64)
+--
+-- Host: 127.0.0.1 Database: auth
+-- ------------------------------------------------------
+-- Server version 5.7.20
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `privilege`
+--
+
+-- DROP TABLE IF EXISTS `privilege`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `privilege` (
+ `uuid` binary(16) NOT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `application_id` binary(16) DEFAULT NULL,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `UK_h7iwbdg4ev8mgvmij76881tx8` (`name`),
+ KEY `FK61h3jewffk70b5ni4tsi5rhoy` (`application_id`),
+ CONSTRAINT `FK61h3jewffk70b5ni4tsi5rhoy` FOREIGN KEY (`application_id`) REFERENCES `application` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `role`
+--
+
+-- DROP TABLE IF EXISTS `role`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `role` (
+ `uuid` binary(16) NOT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `role_privilege`
+--
+
+-- DROP TABLE IF EXISTS `role_privilege`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `role_privilege` (
+ `role_id` binary(16) NOT NULL,
+ `privilege_id` binary(16) NOT NULL,
+ PRIMARY KEY (`role_id`,`privilege_id`),
+ KEY `FKdkwbrwb5r8h74m1v7dqmhp99c` (`privilege_id`),
+ CONSTRAINT `FKdkwbrwb5r8h74m1v7dqmhp99c` FOREIGN KEY (`privilege_id`) REFERENCES `privilege` (`uuid`),
+ CONSTRAINT `FKsykrtrdngu5iexmbti7lu9xa` FOREIGN KEY (`role_id`) REFERENCES `role` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `user`
+--
+
+-- DROP TABLE IF EXISTS `user`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `user` (
+ `uuid` binary(16) NOT NULL,
+ `auth0_metadata` varchar(8000) COLLATE utf8_bin DEFAULT NULL,
+ `general_metadata` varchar(9000) COLLATE utf8_bin DEFAULT NULL,
+ `acceptedTOS` datetime COLLATE utf8_bin DEFAULT NULL,
+ `connectionId` binary(16) DEFAULT NULL,
+ `email` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `matched` bit(1) NOT NULL DEFAULT FALSE,
+ `subject` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `is_active` bit(1) NOT NULL DEFAULT TRUE,
+ `long_term_token` varchar(4000) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `UK_r8xpakluitn685ua7pt8xjy9r` (`subject`),
+ KEY `FKn8bku0vydfcnuwbqwgnbgg8ry` (`connectionId`),
+ CONSTRAINT `FKn8bku0vydfcnuwbqwgnbgg8ry` FOREIGN KEY (`connectionId`) REFERENCES `connection` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `userMetadataMapping`
+--
+
+-- DROP TABLE IF EXISTS `userMetadataMapping`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `userMetadataMapping` (
+ `uuid` binary(16) NOT NULL,
+ `auth0MetadataJsonPath` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `connectionId` binary(16) DEFAULT NULL,
+ `generalMetadataJsonPath` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`),
+ KEY `FKayr8vrvvwpgsdhxdyryt6k590` (`connectionId`),
+ CONSTRAINT `FKayr8vrvvwpgsdhxdyryt6k590` FOREIGN KEY (`connectionId`) REFERENCES `connection` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `user_role`
+--
+
+-- DROP TABLE IF EXISTS `user_role`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `user_role` (
+ `user_id` binary(16) NOT NULL,
+ `role_id` binary(16) NOT NULL,
+ PRIMARY KEY (`user_id`,`role_id`),
+ KEY `FKa68196081fvovjhkek5m97n3y` (`role_id`),
+ CONSTRAINT `FK859n2jvi8ivhui0rl0esws6o` FOREIGN KEY (`user_id`) REFERENCES `user` (`uuid`),
+ CONSTRAINT `FKa68196081fvovjhkek5m97n3y` FOREIGN KEY (`role_id`) REFERENCES `role` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+CREATE TABLE `termsOfService` (
+ `uuid` binary(16) NOT NULL,
+ `dateUpdated` timestamp,
+ `content` varchar(9000) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `connection` (
+ `uuid` binary(16) NOT NULL,
+ `label` varchar(255) COLLATE utf8_bin NOT NULL,
+ `id` varchar(255) COLLATE utf8_bin NOT NULL,
+ `subprefix` varchar(255) COLLATE utf8_bin NOT NULL,
+ `requiredFields` varchar(9000) COLLATE utf8_bin NOT NULL,
+ PRIMARY KEY (`uuid`),
+ UNIQUE KEY `id` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+CREATE TABLE `application` (
+ `uuid` binary(16) NOT NULL,
+ `description` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `enable` bit(1) NOT NULL DEFAULT b'1',
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `token` varchar(2000) COLLATE utf8_bin DEFAULT NULL,
+ `url` varchar(500) COLLATE utf8_bin DEFAULT NULL,
+ PRIMARY KEY (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `access_rule` (
+ `uuid` binary(16) NOT NULL,
+ `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `description` varchar(2000) COLLATE utf8_bin DEFAULT NULL,
+ `rule` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `type` int(11) DEFAULT NULL,
+ `value` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `checkMapKeyOnly` bit(1) NOT NULL,
+ `checkMapNode` bit(1) NOT NULL,
+ `subAccessRuleParent_uuid` binary(16) DEFAULT NULL,
+ `isGateAnyRelation` bit(1) NOT NULL,
+ `isEvaluateOnlyByGates` bit(1) NOT NULL,
+ PRIMARY KEY (`uuid`),
+ KEY `FK8rovvx363ui99ce21sksmg6uy` (`subAccessRuleParent_uuid`),
+ CONSTRAINT `FK8rovvx363ui99ce21sksmg6uy` FOREIGN KEY (`subAccessRuleParent_uuid`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `accessRule_privilege` (
+ `privilege_id` binary(16) NOT NULL,
+ `accessRule_id` binary(16) NOT NULL,
+ PRIMARY KEY (`privilege_id`,`accessRule_id`),
+ KEY `FK89rf30kbf9d246jty2dd7qk99` (`accessRule_id`),
+ CONSTRAINT `FK7x47w81gpua380qd7lp9x94l1` FOREIGN KEY (`privilege_id`) REFERENCES `privilege` (`uuid`),
+ CONSTRAINT `FK89rf30kbf9d246jty2dd7qk99` FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `accessRule_gate` (
+ `accessRule_id` binary(16) NOT NULL,
+ `gate_id` binary(16) NOT NULL,
+ PRIMARY KEY (`accessRule_id`,`gate_id`),
+ KEY `FK6re4kcq9tyl45jv9yg584doem` (`gate_id`),
+ CONSTRAINT `FK6re4kcq9tyl45jv9yg584doem` FOREIGN KEY (`gate_id`) REFERENCES `access_rule` (`uuid`),
+ CONSTRAINT `FKe6l5ee7f207958mm3anpsmqom` FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE OR REPLACE VIEW `management_view`
+AS SELECT
+ `role`.`uuid` AS `uuid`,
+ `role`.`name` AS `role_name`,
+ `privilege`.`name` AS `privilege_name`
+ FROM
+ ((`role` JOIN `role_privilege`) JOIN `privilege`)
+ WHERE
+ ((`role`.`uuid` = `role_privilege`.`role_id`)
+ AND
+ (`privilege`.`uuid` = `role_privilege`.`privilege_id`));
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2018-10-16 19:48:56
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V2__MODIFY_USER_TABLE_COLUMNS.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V2__MODIFY_USER_TABLE_COLUMNS.sql
new file mode 100644
index 000000000..de6b13ed0
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V2__MODIFY_USER_TABLE_COLUMNS.sql
@@ -0,0 +1,4 @@
+USE `auth`;
+
+ALTER TABLE `user` MODIFY auth0_metadata LONGTEXT;
+ALTER TABLE `user` MODIFY general_metadata LONGTEXT;
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V3__ADD_COLUMNS_PRIVILEGE_TABLE.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V3__ADD_COLUMNS_PRIVILEGE_TABLE.sql
new file mode 100644
index 000000000..f815752a0
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V3__ADD_COLUMNS_PRIVILEGE_TABLE.sql
@@ -0,0 +1,4 @@
+USE `auth`;
+
+alter table `privilege` ADD COLUMN (queryScope VARCHAR(8192));
+alter table `privilege` ADD COLUMN (queryTemplate VARCHAR(8192));
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V4__ADD_CREATE_USER_STORED_PROCEDURE.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V4__ADD_CREATE_USER_STORED_PROCEDURE.sql
new file mode 100644
index 000000000..af57999c5
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V4__ADD_CREATE_USER_STORED_PROCEDURE.sql
@@ -0,0 +1,43 @@
+USE `auth`;
+
+DROP PROCEDURE IF EXISTS CreateUserWithRole;
+DELIMITER //
+CREATE PROCEDURE CreateUserWithRole(
+ IN user_email VARCHAR(255),
+ IN connection_id VARCHAR(255),
+ IN role_name VARCHAR(255),
+ IN user_general_metadata varchar(255)
+)
+BEGIN
+ -- Attempt to retrieve the UUIDs for the user and role based on the provided information
+ SELECT @userUUID := uuid FROM auth.user WHERE email = user_email AND connectionId = connection_id;
+ SELECT @roleUUID := uuid FROM auth.role WHERE name = role_name;
+ SELECT @picsureUserRoleId := uuid FROM auth.role WHERE name = 'PIC-SURE User';
+
+-- If the user does not exist, create a new user entry
+ IF @userUUID IS NULL THEN
+ set @baseUUID = UUID();
+ -- Generate a new UUID for the user
+ SET @userUUID = UNHEX(REPLACE(@baseUUID, '-', ''));
+ -- Retrieve the UUID for the connection
+ SELECT @connectionUUID := uuid FROM auth.connection WHERE id = connection_id;
+ SELECT @connectionSubPrefix := subPrefix FROM auth.connection WHERE id = connection_id;
+-- Insert the new user record into the user table
+ INSERT INTO auth.user (uuid, general_metadata, acceptedTOS, connectionId, email, matched, subject, is_active,
+ long_term_token)
+ VALUES (@userUUID, user_general_metadata, CURRENT_TIMESTAMP, @connectionUUID, user_email, 0,
+ concat(@connectionSubPrefix, REPLACE(@baseUUID, '-', '')), 1, NULL);
+ END IF;
+
+ -- If the role exists, associate the user with the role
+ IF @roleUUID IS NOT NULL THEN
+ INSERT INTO auth.user_role (user_id, role_id) VALUES (@userUUID, @roleUUID);
+ END IF;
+
+ -- If the role is not PIC-SURE User, associate the user with the PIC-SURE User role as well
+ -- All users must have the PIC-SURE User role
+ IF @roleUUID IS NOT NULL AND @roleUUID != @picsureUserRoleId THEN
+ INSERT INTO auth.user_role (user_id, role_id) VALUES (@userUUID, @picsureUserRoleId);
+ END IF;
+END//
+DELIMITER ;
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V5__MIGRATE_TO_ACCESSRULE_JOINTABLE.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V5__MIGRATE_TO_ACCESSRULE_JOINTABLE.sql
new file mode 100644
index 000000000..9c1c67c92
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V5__MIGRATE_TO_ACCESSRULE_JOINTABLE.sql
@@ -0,0 +1,31 @@
+# When merging the FENCE (Also consider the BDC specific) specific pic-sure-auth-micro-app and the more general
+# pic-sure-auth-micro-app, we need to remove the circular dependency between the access_rule table and itself.
+# We could have supported both, but the same functionality is already supported by the accessRule_subRule join table.
+# This script will remove the circular dependency and replace it with a reference to the join table.
+
+-- Step 1: Create the join table
+--
+-- Table structure for table `accessRule_subRule`
+--
+CREATE TABLE `accessRule_subRule`
+(
+ `accessRule_id` binary(16) NOT NULL,
+ `subRule_id` binary(16) NOT NULL,
+ PRIMARY KEY (`accessRule_id`, `subRule_id`),
+ KEY (`subRule_id`),
+ CONSTRAINT FOREIGN KEY (`subRule_id`) REFERENCES `access_rule` (`uuid`),
+ CONSTRAINT FOREIGN KEY (`accessRule_id`) REFERENCES `access_rule` (`uuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+-- Step 2: Insert data from the circular dependency into the join table
+INSERT INTO accessRule_subRule (accessRule_id, subRule_id)
+SELECT ar.uuid, ar.subAccessRuleParent_uuid
+FROM access_rule ar
+WHERE ar.subAccessRuleParent_uuid IS NOT NULL;
+
+-- Step 3: Update references in the original table to point to the join table
+UPDATE access_rule ar
+ JOIN accessRule_subRule ars ON ars.accessRule_id = ar.uuid
+ SET ar.subAccessRuleParent_uuid = NULL; -- Remove circular dependency reference so it can be dropped
+
+-- Step 4: Drop the column from the original table
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V6__UPDATE_EXISTING_ROLE_PRIVILEGE_RULE_NAMES.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V6__UPDATE_EXISTING_ROLE_PRIVILEGE_RULE_NAMES.sql
new file mode 100644
index 000000000..e32a94fb0
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V6__UPDATE_EXISTING_ROLE_PRIVILEGE_RULE_NAMES.sql
@@ -0,0 +1,28 @@
+# We have migrated our naming convention away from "FENCE_" to a more generalized "MANAGED_".
+
+-- Update roles table
+UPDATE role
+SET name = REPLACE(name, 'FENCE', 'MANAGED')
+WHERE name LIKE '%FENCE%';
+
+UPDATE role
+SET description = REPLACE(description, 'FENCE', 'MANAGED')
+WHERE description LIKE '%FENCE%';
+
+-- Update privileges table
+UPDATE privilege
+SET name = REPLACE(name, 'FENCE', 'MANAGED')
+WHERE name LIKE '%FENCE%';
+
+UPDATE privilege
+SET description = REPLACE(description, 'FENCE', 'MANAGED')
+WHERE description LIKE '%FENCE%';
+
+-- Update access rules table
+UPDATE access_rule
+SET name = REPLACE(name, 'FENCE', 'MANAGED')
+WHERE name LIKE '%FENCE%';
+
+UPDATE access_rule
+SET description = REPLACE(description, 'FENCE', 'MANAGED')
+WHERE description LIKE '%FENCE%';
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V7__Add_Passport_User_Col.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V7__Add_Passport_User_Col.sql
new file mode 100644
index 000000000..1fd4e2d65
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V7__Add_Passport_User_Col.sql
@@ -0,0 +1 @@
+ALTER TABLE user ADD COLUMN passport TEXT;
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V8__ADD_USER_EMAIL_UNIQUE_CONSTRAINT.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V8__ADD_USER_EMAIL_UNIQUE_CONSTRAINT.sql
new file mode 100644
index 000000000..f845b89d6
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V8__ADD_USER_EMAIL_UNIQUE_CONSTRAINT.sql
@@ -0,0 +1,3 @@
+USE `auth`;
+
+ALTER TABLE `user` ADD CONSTRAINT `email_UNIQUE` UNIQUE (`email`, `connectionId`);
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V9__ADD_USER_CONSENT_TABLE.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V9__ADD_USER_CONSENT_TABLE.sql
new file mode 100644
index 000000000..498569368
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/sql/V9__ADD_USER_CONSENT_TABLE.sql
@@ -0,0 +1,7 @@
+CREATE TABLE user_consents (
+ `uuid` binary(16) NOT NULL UNIQUE,
+ `user_id` binary(16) NOT NULL UNIQUE,
+ `consents` JSON,
+ FOREIGN KEY (`user_id`) REFERENCES user(`uuid`)
+ ON DELETE CASCADE
+);
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/first_time_run_the_system_and_insert_admin_user.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/first_time_run_the_system_and_insert_admin_user.sql
new file mode 100644
index 000000000..ee946a32f
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/first_time_run_the_system_and_insert_admin_user.sql
@@ -0,0 +1,45 @@
+#configuration for user table
+#for quick usage, please use a google user
+#otherwise you need to modify connection configuration as well
+
+#if you choose to use a google user for login, this user_email is the only place to change
+set @user_email='change_me_to_your_email';
+
+set @user_uuid=replace(uuid(),'-','');
+set @matched=false;
+
+#configuration for connection table
+set @connection_uuid=unhex(replace(uuid(),'-',''));
+set @label='Google';
+set @id='google-oauth2';
+set @subprefix='google-oauth2|';
+set @requiredFields='[{\"label\":\"Email\", \"id\":\"email\"}]';
+
+#configuration for userMetadataMapping table
+set @userMetadataMapping_uuid=unhex(replace(uuid(),'-',''));
+set @authMetadata='$.email';
+set @generalMetadata='$.email';
+
+begin;
+#### insert into connection table
+insert into `connection` values (@connection_uuid, @label, @id, @subprefix, @requiredFields);
+
+#### insert into user table
+create or replace view management_view as
+select
+role.uuid, role.name as role_name, privilege.name as privilege_name
+from
+role, role_privilege, privilege
+where
+
+role.uuid = role_privilege.role_id
+and privilege.uuid = role_privilege.privilege_id;
+
+insert into user (`uuid`,`general_metadata`,`connectionId`,`email`,`matched`) values (unhex(@user_uuid), CONCAT("{\"email\":\"", @user_email, "\"}"), @connection_uuid, @user_email, @matched);
+insert into user_role (`user_id`,`role_id`) values (unhex(@user_uuid),
+(select min(uuid) from management_view where privilege_name like 'ADMIN')) ;
+
+#### insert into userMetadataMapping
+insert into `userMetadataMapping` values (@userMetadataMapping_uuid, @authMetadata, @connection_uuid, @generalMetadata);
+commit;
+
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/for_dev/grant_access.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/for_dev/grant_access.sql
new file mode 100644
index 000000000..3205b02ef
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/for_dev/grant_access.sql
@@ -0,0 +1,4 @@
+GRANT ALL PRIVILEGES
+ON *.*
+TO 'root'@'%'
+IDENTIFIED BY 'password';
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/for_dev/init_mysql.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/for_dev/init_mysql.sql
new file mode 100644
index 000000000..7a146a036
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/for_dev/init_mysql.sql
@@ -0,0 +1,2 @@
+
+ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_admin_user.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_admin_user.sql
new file mode 100644
index 000000000..cb08506ac
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_admin_user.sql
@@ -0,0 +1,19 @@
+set @user_uuid='91124ef7df204412b4f399565c547bd9';
+set @user_subject='{{change_me}}';
+set @connection_uuid='{{change_me}}';
+set @matched=true;
+
+create or replace view management_view as
+select
+role.uuid, role.name as role_name, privilege.name as privilege_name
+from
+role, role_privilege, privilege
+where
+role.uuid = role_privilege.role_id
+and privilege.uuid = role_privilege.privilege_id;
+
+begin;
+insert into user (`uuid`,`subject`,`connectionId`,`matched`) values (unhex(@user_uuid), @user_subject, @connection_uuid, true);
+insert into user_role (`user_id`,`role_id`) values (unhex(@user_uuid),
+(select min(uuid) from management_view where privilege_name like 'ADMIN')) ;
+commit;
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_connection.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_connection.sql
new file mode 100644
index 000000000..3f7bce7bb
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_connection.sql
@@ -0,0 +1,9 @@
+set @uuid=0x2a3966ea7d024041975d784322b48342;
+set @label='Google';
+set @id='google-oauth2';
+set @subprefix='google-oauth2|';
+set @requiredFields='[{\"label\":\"Email\", \"id\":\"email\"}]';
+
+begin;
+insert into `connection` values (@uuid, @label, @id, @subprefix, @requiredFields);
+commit;
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_privileges_for_transmart.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_privileges_for_transmart.sql
new file mode 100644
index 000000000..a99a6cee2
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_privileges_for_transmart.sql
@@ -0,0 +1,67 @@
+#
+# Create the privileges used for i2b2/tranSmart application
+#
+START TRANSACTION;
+
+SET @uuidPrivilege = REPLACE(uuid(),'-','');
+
+INSERT INTO `privilege` (
+ `uuid`,
+ `name`,
+ `description`,
+ `application_id`
+)
+VALUES (
+ unhex(@uuidPrivilege),
+ 'TM_ADMIN',
+ 'Administrator privilege for i2b2/tranSmart application',
+ (SELECT `uuid` FROM `application` WHERE `name` = 'TRANSMART')
+);
+
+SET @uuidPrivilege = REPLACE(uuid(),'-','');
+
+INSERT INTO `privilege` (
+ `uuid`,
+ `name`,
+ `description`,
+ `application_id`
+)
+VALUES (
+ unhex(@uuidPrivilege),
+ 'TM_STUDY_OWNER',
+ 'Level1 priveilege for i2b2/tranSmart user, allowing download functionality, in addition to Level1 privileges.',
+ (SELECT `uuid` FROM `application` WHERE `name` = 'TRANSMART')
+);
+
+SET @uuidPrivilege = REPLACE(uuid(),'-','');
+
+INSERT INTO `privilege` (
+ `uuid`,
+ `name`,
+ `description`,
+ `application_id`
+)
+VALUES (
+ unhex(@uuidPrivilege),
+ 'TM_DATASET_EXPLORER',
+ 'Level2 privilege for i2b2/tranSmart user, allowing to run advanced statistics, but no download or grid view.',
+ (SELECT `uuid` FROM `application` WHERE `name` = 'TRANSMART')
+);
+
+SET @uuidPrivilege = REPLACE(uuid(),'-','');
+
+INSERT INTO `privilege` (
+ `uuid`,
+ `name`,
+ `description`,
+ `application_id`
+)
+VALUES (
+ unhex(@uuidPrivilege),
+ 'TM_PUBLIC_USER',
+ 'Base level privilege, for i2b2/tranSmart, allowing the user to log in, and see counts.',
+ (SELECT `uuid` FROM `application` WHERE `name` = 'TRANSMART')
+);
+
+
+COMMIT;
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_role_for_transmart.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_role_for_transmart.sql
new file mode 100644
index 000000000..565a1b3c9
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_role_for_transmart.sql
@@ -0,0 +1,60 @@
+#
+# Create a role, which is a collection of privileges
+#
+START TRANSACTION;
+
+SET @uuidRole = REPLACE(uuid(),'-','');
+
+# This is an example, where the SUPERUSER role is added.
+INSERT INTO `role` (
+ `uuid`,
+ `name`,
+ `description`
+)
+VALUES (
+ unhex(@uuidRole),
+ 'TM_ADMIN',
+ 'i2b2/tranSmart administrator role.'
+);
+
+# The i2b2/tranSmart administrator role has ADMIN and PUBLIC_USER privileges
+INSERT INTO `role_privilege` (
+ `role_id`,
+ `privilege_id`
+)
+VALUES (
+ unhex(@uuidRole),
+ (SELECT uuid FROM `privilege` WHERE `name` = 'TM_ADMIN')
+);
+
+# The i2b2/tranSmart level1 role has STUDY_OWNER and PUBLIC_USER privileges
+INSERT INTO `role_privilege` (
+ `role_id`,
+ `privilege_id`
+)
+VALUES (
+ unhex(@uuidRole),
+ (SELECT uuid FROM `privilege` WHERE `name` = 'TM_STUDY_OWNER')
+);
+
+# The i2b2/tranSmart level2 role has DATASET_EXPLORER and PUBLIC_USER privileges
+INSERT INTO `role_privilege` (
+ `role_id`,
+ `privilege_id`
+)
+VALUES (
+ unhex(@uuidRole),
+ (SELECT uuid FROM `privilege` WHERE `name` = 'TM_DATASET_EXPLORER')
+);
+
+# The i2b2/tranSmart level0 (authenticated, but not authorized for data access) role has only PUBLIC_USER privileges
+INSERT INTO `role_privilege` (
+ `role_id`,
+ `privilege_id`
+)
+VALUES (
+ unhex(@uuidRole),
+ (SELECT uuid FROM `privilege` WHERE `name` = 'TM_PUBLIC_USER')
+);
+
+COMMIT;
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_userMetadataMapping.sql b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_userMetadataMapping.sql
new file mode 100644
index 000000000..6b472d648
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-db/db/tools/insert_userMetadataMapping.sql
@@ -0,0 +1,18 @@
+
+START TRANSACTION;
+
+INSERT INTO `userMetadataMapping` (
+ `uuid`,
+ `auth0MetadataJsonPath`,
+ `connectionId`,
+ `generalMetadataJsonPath`
+)
+VALUES (
+ (SELECT uuid FROM user WHERE email = '__SUPERUSER_GMAIL__'),
+ '$.email',
+ (SELECT uuid FROM connection WHERE label = 'Google'),
+ '$.email'
+);
+
+COMMIT;
+
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/Dockerfile b/services/pic-sure-auth-microapp/pic-sure-auth-services/Dockerfile
new file mode 100644
index 000000000..a678255d5
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/Dockerfile
@@ -0,0 +1,12 @@
+FROM amazoncorretto:25-alpine
+
+# Copy jar and access token from maven build
+COPY pic-sure-auth-services/target/pic-sure-auth-services-*.jar /pic-sure-auth-service.jar
+
+# Copy the AWS certificate
+COPY pic-sure-auth-services/aws_certs/certificate.der /certificate.der
+
+# Import the certificate into the Java trust store
+RUN keytool -noprompt -import -alias aws_cert -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -file /certificate.der
+
+ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /pic-sure-auth-service.jar"]
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/README.md b/services/pic-sure-auth-microapp/pic-sure-auth-services/README.md
new file mode 100644
index 000000000..4ddfa9ca5
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/README.md
@@ -0,0 +1,2 @@
+# pic-sure-auth-services
+
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/WebContent/META-INF/MANIFEST.MF b/services/pic-sure-auth-microapp/pic-sure-auth-services/WebContent/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..5e9495128
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/aws_certs/certificate.der b/services/pic-sure-auth-microapp/pic-sure-auth-services/aws_certs/certificate.der
new file mode 100644
index 000000000..dab9aedbc
Binary files /dev/null and b/services/pic-sure-auth-microapp/pic-sure-auth-services/aws_certs/certificate.der differ
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/bdc.Dockerfile b/services/pic-sure-auth-microapp/pic-sure-auth-services/bdc.Dockerfile
new file mode 100644
index 000000000..7668eb208
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/bdc.Dockerfile
@@ -0,0 +1,26 @@
+FROM amazoncorretto:25-alpine
+
+ARG DATASOURCE_URL
+ARG DATASOURCE_USERNAME
+ARG STACK_SPECIFIC_APPLICATION_ID
+
+ENV DATASOURCE_URL=${DATASOURCE_URL}
+ENV DATASOURCE_USERNAME=${DATASOURCE_USERNAME}
+ENV STACK_SPECIFIC_APPLICATION_ID=${STACK_SPECIFIC_APPLICATION_ID}
+
+# Copy jar from pre-built workspace
+COPY pic-sure-auth-services/target/pic-sure-auth-services-*.jar /pic-sure-auth-service.jar
+
+# Copy additional bdc configuration files. Root of the project
+COPY config/psama/bdc/psama-db-config.properties /config/psama-db-config.properties
+
+# Set SPRING_CONFIG_ADDITIONAL_LOCATION
+ENV SPRING_CONFIG_ADDITIONAL_LOCATION=file:/config/psama-db-config.properties
+
+# Copy the AWS certificate
+COPY pic-sure-auth-services/aws_certs/certificate.der /certificate.der
+
+# Import the certificate into the Java trust store
+RUN keytool -noprompt -import -alias aws_cert -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -file /certificate.der
+
+ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /pic-sure-auth-service.jar"]
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/dev.Dockerfile b/services/pic-sure-auth-microapp/pic-sure-auth-services/dev.Dockerfile
new file mode 100644
index 000000000..cd33af84d
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/dev.Dockerfile
@@ -0,0 +1,20 @@
+FROM maven:3.9-amazoncorretto-25 AS build
+
+# Copy the source code into the container
+COPY ../ /app
+
+# Change the working directory
+WORKDIR /app
+
+# Build the jar
+RUN mvn clean install -DskipTests
+
+FROM amazoncorretto:25-alpine
+
+# Copy jar and access token from maven build
+#COPY target/pic-sure-auth-services.jar /pic-sure-auth-service.jar
+COPY --from=build /app/pic-sure-auth-services/target/pic-sure-auth-services-*.jar /pic-sure-auth-service.jar
+
+EXPOSE 8090
+
+ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /pic-sure-auth-service.jar"]
\ No newline at end of file
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/pom.xml b/services/pic-sure-auth-microapp/pic-sure-auth-services/pom.xml
new file mode 100644
index 000000000..ae95ccb8a
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/pom.xml
@@ -0,0 +1,277 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.5.9
+
+
+ edu.harvard.hms.dbmi.avillach
+ pic-sure-auth-services
+ 2.0-SNAPSHOT
+ pic-sure-auth-services
+ jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ github
+ https://maven.pkg.github.com/hms-dbmi/pic-sure
+
+ true
+
+
+
+
+ 25
+ 2.41.1
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ 3.5.3
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ 3.2.4
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ 3.2.4
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+ 3.3.1
+
+
+ org.springframework
+ spring-context
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ com.github.spullara.mustache.java
+ compiler
+ 0.9.5
+
+
+
+ com.sun.mail
+ jakarta.mail
+ 2.0.2
+
+
+
+ jakarta.mail
+ jakarta.mail-api
+ 2.1.3
+
+
+
+ io.swagger.core.v3
+ swagger-jaxrs2-jakarta
+ 2.2.21
+
+
+
+ io.swagger.core.v3
+ swagger-jaxrs2-servlet-initializer-jakarta
+ 2.2.21
+
+
+
+ io.swagger.core.v3
+ swagger-annotations-jakarta
+ 2.2.21
+
+
+
+ jakarta.xml.bind
+ jakarta.xml.bind-api
+ 4.0.2
+
+
+
+ org.glassfish.jaxb
+ jaxb-runtime
+ 4.0.5
+
+
+ org.glassfish.jaxb
+ jaxb-core
+ 4.0.5
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.17.0
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.18.6
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ 2.17.0
+
+
+
+ net.bytebuddy
+ byte-buddy
+ 1.14.13
+
+
+
+ com.mysql
+ mysql-connector-j
+ 8.2.0
+
+
+ com.amazonaws.secretsmanager
+ aws-secretsmanager-jdbc
+ 2.0.2
+
+
+ com.jayway.jsonpath
+ json-path
+ 2.9.0
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.12.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.12.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.12.5
+ runtime
+
+
+ com.auth0
+ auth0
+ 2.10.1
+
+
+ org.apache.httpcomponents.client5
+ httpclient5
+ 5.6.1
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+
+ org.apache.httpcomponents.core5
+ httpcore5
+ 5.4
+
+
+ junit
+ junit
+ 4.13.1
+ test
+
+
+ org.mockito
+ mockito-core
+ 5.21.0
+ test
+
+
+ org.mockito
+ mockito-subclass
+ 5.21.0
+ test
+
+
+ edu.harvard.hms.dbmi.avillach.hpds
+ pic-sure-hpds-model
+ 1.0.0-SNAPSHOT
+
+
+ edu.harvard.dbmi.avillach
+ pic-sure-logging-client
+ 1.0.0
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ com.diffplug.spotless
+ spotless-maven-plugin
+ ${spotless.version}
+
+
+
+ 4.29
+ code-formatting/eclipse-formatter.xml
+
+
+
+
+
+
+
+
+
+ github
+ GitHub HMS-DBMI Apache Maven Packages
+ https://maven.pkg.github.com/hms-dbmi/pic-sure
+
+
+
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/Application.java b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/Application.java
new file mode 100644
index 000000000..4e84ce903
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/Application.java
@@ -0,0 +1,17 @@
+package edu.harvard.hms.dbmi.avillach.auth;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class})
+@EnableJpaRepositories
+@EnableScheduling
+public class Application {
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class);
+ }
+}
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/ApplicationConfig.java b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/ApplicationConfig.java
new file mode 100644
index 000000000..a15047140
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/ApplicationConfig.java
@@ -0,0 +1,47 @@
+package edu.harvard.hms.dbmi.avillach.auth.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import edu.harvard.hms.dbmi.avillach.auth.service.impl.CustomUserDetailService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
+
+@Configuration
+@EnableCaching
+public class ApplicationConfig {
+
+ private final CustomUserDetailService customUserDetailService;
+
+ @Autowired
+ public ApplicationConfig(CustomUserDetailService customUserDetailService) {
+ this.customUserDetailService = customUserDetailService;
+ }
+
+ @Bean
+ public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
+ return authenticationConfiguration.getAuthenticationManager();
+ }
+
+ @Bean
+ public AuthenticationProvider authenticationProvider() {
+ DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setUserDetailsService(customUserDetailService);
+ return provider;
+ }
+
+ @Bean("customKeyGenerator")
+ public KeyGenerator generator() {
+ return new CustomKeyGenerator();
+ }
+
+ @Bean
+ public ObjectMapper objectMapper() {
+ return new ObjectMapper();
+ }
+}
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/CustomKeyGenerator.java b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/CustomKeyGenerator.java
new file mode 100644
index 000000000..75485f4ac
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/CustomKeyGenerator.java
@@ -0,0 +1,20 @@
+package edu.harvard.hms.dbmi.avillach.auth.config;
+
+import edu.harvard.hms.dbmi.avillach.auth.entity.User;
+import org.springframework.cache.interceptor.KeyGenerator;
+
+import java.lang.reflect.Method;
+
+public class CustomKeyGenerator implements KeyGenerator {
+
+ @Override
+ public Object generate(Object target, Method method, Object... params) {
+ for (Object param : params) {
+ if (param instanceof User user) {
+ return user.getSubject();
+ }
+ }
+
+ throw new IllegalArgumentException("No valid params found. Cannot generate cache key");
+ }
+}
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/CustomLogoutHandler.java b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/CustomLogoutHandler.java
new file mode 100644
index 000000000..9d11961cd
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/CustomLogoutHandler.java
@@ -0,0 +1,55 @@
+package edu.harvard.hms.dbmi.avillach.auth.config;
+
+import edu.harvard.hms.dbmi.avillach.auth.service.impl.CacheEvictionService;
+import edu.harvard.hms.dbmi.avillach.auth.service.impl.UserService;
+import edu.harvard.hms.dbmi.avillach.auth.utils.AuditAttributes;
+import edu.harvard.hms.dbmi.avillach.auth.utils.JWTUtil;
+import io.jsonwebtoken.Claims;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.logout.LogoutHandler;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CustomLogoutHandler implements LogoutHandler {
+
+ private final Logger logger = LoggerFactory.getLogger(CustomLogoutHandler.class);
+ private final UserService userService;
+ private final CacheEvictionService cacheEvictionService;
+ private final JWTUtil jwtUtil;
+
+ public CustomLogoutHandler(UserService userService, CacheEvictionService cacheEvictionService, JWTUtil jwtUtil) {
+ this.userService = userService;
+ this.cacheEvictionService = cacheEvictionService;
+ this.jwtUtil = jwtUtil;
+ }
+
+ @Override
+ public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
+ String bearer = request.getHeader("Authorization");
+ if (!bearer.startsWith("Bearer ")) {
+ return;
+ }
+
+ String token = bearer.substring(7);
+ if (StringUtils.isBlank(token)) {
+ return;
+ }
+
+ Claims payload = jwtUtil.parseToken(token).getPayload();
+ String subject = payload.getSubject();
+
+ if (StringUtils.isNotBlank(subject)) {
+ logger.info("logout() Logging out User: {}", subject);
+ this.cacheEvictionService.evictCache(subject);
+ this.userService.removeUserPassport(subject);
+
+ // Populate AuditAttributes for the AuditLoggingFilter to include in its event
+ AuditAttributes.putMetadata(request, "user_subject", subject);
+ }
+ }
+}
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/LoggingConfig.java b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/LoggingConfig.java
new file mode 100644
index 000000000..84edcf49d
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/LoggingConfig.java
@@ -0,0 +1,28 @@
+package edu.harvard.hms.dbmi.avillach.auth.config;
+
+import edu.harvard.dbmi.avillach.logging.LoggingClient;
+import edu.harvard.dbmi.avillach.logging.LoggingClientFactory;
+import edu.harvard.hms.dbmi.avillach.auth.utils.AuditInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class LoggingConfig implements WebMvcConfigurer {
+
+ @Bean
+ public LoggingClient loggingClient() {
+ return LoggingClientFactory.create("pic-sure-auth-microapp");
+ }
+
+ @Bean
+ public AuditInterceptor auditInterceptor() {
+ return new AuditInterceptor();
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(auditInterceptor());
+ }
+}
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/SecurityConfig.java b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/SecurityConfig.java
new file mode 100644
index 000000000..db5c24e79
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/config/SecurityConfig.java
@@ -0,0 +1,87 @@
+package edu.harvard.hms.dbmi.avillach.auth.config;
+
+import edu.harvard.hms.dbmi.avillach.auth.filter.AuditLoggingFilter;
+import edu.harvard.hms.dbmi.avillach.auth.filter.JWTFilter;
+import edu.harvard.hms.dbmi.avillach.auth.service.impl.CacheEvictionService;
+import edu.harvard.hms.dbmi.avillach.auth.service.impl.UserService;
+import edu.harvard.hms.dbmi.avillach.auth.utils.JWTUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.core.GrantedAuthorityDefaults;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.security.web.authentication.logout.LogoutFilter;
+
+import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;
+
+@Configuration
+@EnableMethodSecurity(prePostEnabled = false, jsr250Enabled = true)
+@EnableWebSecurity
+public class SecurityConfig {
+
+ private final JWTFilter jwtFilter;
+ private final AuditLoggingFilter auditLoggingFilter;
+ private final CacheEvictionService cacheEvictionService;
+ private final AuthenticationProvider authenticationProvider;
+ private final UserService userService;
+ private final JWTUtil jwtUtil;
+
+ @Autowired
+ public SecurityConfig(
+ JWTFilter jwtFilter, AuditLoggingFilter auditLoggingFilter, AuthenticationProvider authenticationProvider, UserService userService,
+ CacheEvictionService cacheEvictionService, JWTUtil jwtUtil
+ ) {
+ this.jwtFilter = jwtFilter;
+ this.auditLoggingFilter = auditLoggingFilter;
+ this.authenticationProvider = authenticationProvider;
+ this.userService = userService;
+ this.jwtUtil = jwtUtil;
+ this.cacheEvictionService = cacheEvictionService;
+ }
+
+ @Bean
+ public CustomLogoutHandler customLogoutHandler() {
+ return new CustomLogoutHandler(userService, cacheEvictionService, jwtUtil);
+ }
+
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+ http.csrf(AbstractHttpConfigurer::disable).sessionManagement((session) -> session.sessionCreationPolicy(STATELESS))
+ .authenticationProvider(authenticationProvider)
+ .authorizeHttpRequests(
+ (authorizeRequests) -> authorizeRequests.requestMatchers(
+ "/actuator/health", "/actuator/info", "/authentication", "/authentication/**", "/swagger.yaml", "/swagger.json",
+ "/user/me/queryTemplate", "/user/me/queryTemplate/**", "/tos/latest", "/open/validate", "/logout", "/cache/**"
+ ).permitAll().anyRequest().authenticated()
+ ).httpBasic(AbstractHttpConfigurer::disable).formLogin(AbstractHttpConfigurer::disable)
+ // AuditLoggingFilter must wrap the entire chain (including LogoutFilter and JWTFilter)
+ // so its try/finally captures events even when JWTFilter short-circuits or LogoutFilter handles /logout
+ .addFilterBefore(auditLoggingFilter, LogoutFilter.class)
+ .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
+ .logout(
+ (logout) -> logout.logoutUrl("/logout").addLogoutHandler(customLogoutHandler())
+ .logoutSuccessHandler((request, response, authentication) -> {
+ // We don't want to redirect to a login page, we just want to return a 200
+ // We leave it to the client to handle the redirect
+ response.setStatus(200);
+ })
+ );
+
+ return http.build();
+ }
+
+ /**
+ * Remove the default "ROLE_" prefix so that hasRole("ADMIN") and @RolesAllowed("ADMIN") match a GrantedAuthority("ADMIN").
+ */
+ @Bean
+ public GrantedAuthorityDefaults grantedAuthorityDefaults() {
+ return new GrantedAuthorityDefaults("");
+ }
+
+}
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/entity/AccessRule.java b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/entity/AccessRule.java
new file mode 100644
index 000000000..5c5034340
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/entity/AccessRule.java
@@ -0,0 +1,288 @@
+package edu.harvard.hms.dbmi.avillach.auth.entity;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.JoinTable;
+import jakarta.persistence.ManyToMany;
+import jakarta.persistence.Transient;
+
+import java.lang.reflect.Field;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ *
Thoughts on design:
the AccessRule is designed to fulfilled the requirements
+ * of complicated scenarios that includes AND/OR or nested AND/OR cases of jsonPath authorization
+ *
+ *
+ *
+ * Attribute Explanations:
+ *
checkMapNode - after retrieving the value by jsonPath rule, if the value is a map,
+ * this flag will let the evaluation go through all the map nodes and their children nodes
+ *
checkMapKeyOnly - only take effective when checkMapNode flag is turned on. This flag will
+ * let the evaluation only check the key of current map node, it will stop the evaluation to go into
+ * the children nodes
+ *
gateAnyRelation - true: gates are evaluated as ANY relationship, false: gates are evaluated as AND relationship
+ *
evaluateOnlyByGates - this flag means no matter what rules and values are set,
+ * the evaluation will based on whether the gates are passed or not, which means if gates are passed,
+ * then evaluation result is true, not passed, return false. The use case for this flag is sometimes, we
+ * need to meet the requirements of some nested AND/OR gates like gateA && gateB && (gateC || gateD),
+ * in this example, (gateC || gateD) has to be together in a gate and not evaluate by the values and rules
+ *
+ */
+@Entity(name = "access_rule")
+public class AccessRule extends BaseEntity {
+ /**
+ * please do not modify the existing values, in case the value has
+ * already saved in the database. But you can add more constant values, or
+ * update the keys.
+ */
+ public static class TypeNaming {
+// public static final int CONTAINS = 0;
+ public static final int NOT_CONTAINS = 1;
+ public static final int NOT_CONTAINS_IGNORE_CASE = 2;
+ public static final int NOT_EQUALS = 3;
+ public static final int ALL_EQUALS = 4;
+ public static final int ALL_CONTAINS = 5;
+ public static final int ALL_CONTAINS_IGNORE_CASE = 6;
+ public static final int ANY_CONTAINS = 7;
+ public static final int NOT_EQUALS_IGNORE_CASE = 8;
+ public static final int ALL_EQUALS_IGNORE_CASE = 9;
+ public static final int ANY_EQUALS = 10;
+ public static final int ALL_REG_MATCH = 11;
+ public static final int ANY_REG_MATCH = 12;
+ public static final int IS_EMPTY = 13;
+ public static final int IS_NOT_EMPTY = 14;
+ public static final int ALL_CONTAINS_OR_EMPTY = 15;
+ public static final int ALL_CONTAINS_OR_EMPTY_IGNORE_CASE = 16;
+ public static final int USER_CONSENT_ACCESS = 17;
+
+ public static Map getTypeNameMap(){
+ Map map = new LinkedHashMap<>();
+ for (Field f : AccessRule.TypeNaming.class.getDeclaredFields()){
+ f.setAccessible(true);
+ try {
+ map.put(f.getName(), (Integer)f.get(null));
+ } catch (IllegalAccessException e){
+ continue;
+ }
+ }
+ return map;
+ }
+ }
+
+ private String name;
+
+ private String description;
+
+ /**
+ * for check how to do with the retrieved value
+ *
+ *
+ * NOTICE: please don't change this back to int
+ * we need to support a null input,
+ * otherwise, the update mechanism will be broken
+ *
+ *
+ * @see TypeNaming
+ */
+ private Integer type;
+
+ /**
+ * The jsonpath rule to retrieve values, kind of the route to the data.
+ * The possible value will be String, JSONObject, JSONArray, etc.
+ */
+ private String rule;
+
+ /**
+ * The value for checking
+ */
+ private String value;
+
+ /**
+ * only inner use for merge accessRule
+ * This field should neither be saved to database
+ * nor seen by a user
+ */
+ @Transient
+ private Set mergedValues = new HashSet<>();
+
+ /**
+ * This attribute will not be seen by either endpoint users or database.
+ * It is a intermediate product that generated on the fly for supporting
+ * auto-merging functionality of accessRules when doing authorization.
+ */
+ @Transient
+ private String mergedName = "";
+
+ /**
+ * Guideline of using gates: if null or empty, will skip checking gate
+ * to pass gate settings, every gate in the set needs to be passed,
+ * which means if only part of the gate set is passed, the gate still
+ * not passed
+ */
+ @ManyToMany(fetch = FetchType.EAGER)
+ @JoinTable(name = "accessRule_gate",
+ joinColumns = {@JoinColumn(name = "accessRule_id", nullable = false)},
+ inverseJoinColumns = {@JoinColumn(name = "gate_id", nullable = false)})
+ private Set gates;
+
+ /**
+ * this attribute is for determining the relationship between gates
+ * the default value is false, means gates are AND relationship,
+ * meaning all gates need to be passed to check the actual rules
+ *
+ * NOTICE: please don't change this back to boolean
+ * we need to support a null input,
+ * otherwise, the update mechanism will be broken
+ */
+ @Column(name = "isGateAnyRelation")
+ private Boolean gateAnyRelation;
+
+ /**
+ * this attribute is to tell if the accessRule passes only based on
+ * the gates passes or not
+ *
+ * NOTICE: please don't change this back to boolean
+ * we need to support a null input,
+ * otherwise, the update mechanism will be broken
+ */
+ @Column(name = "isEvaluateOnlyByGates")
+ private Boolean evaluateOnlyByGates;
+
+ /**
+ * introduce sub-accessRule to enable the ability of more complex problem, essentially it is an AND relationship.
+ */
+ @ManyToMany(fetch = FetchType.EAGER)
+ @JoinTable(name = "accessRule_subRule",
+ joinColumns = {@JoinColumn(name = "accessRule_id", nullable = false)},
+ inverseJoinColumns = {@JoinColumn(name = "subRule_id", nullable = false)})
+ private Set subAccessRule;
+
+ /**
+ * NOTICE: please don't change this back to boolean
+ * we need to support a null input,
+ * otherwise, the auto update mechanism will be broken
+ */
+ private Boolean checkMapNode;
+
+ /**
+ * NOTICE: please don't change this back to boolean
+ * we need to support a null input,
+ * otherwise, the auto update mechanism will be broken
+ */
+ private Boolean checkMapKeyOnly;
+
+ public Integer getType() {
+ return type;
+ }
+
+ public void setType(Integer type) {
+ this.type = type;
+ }
+
+ public String getRule() {
+ return rule;
+ }
+
+ public void setRule(String rule) {
+ this.rule = rule;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Set getGates() {
+ return gates;
+ }
+
+ public void setGates(Set gates) {
+ this.gates = gates;
+ }
+
+ public Boolean getEvaluateOnlyByGates() {
+ return evaluateOnlyByGates;
+ }
+
+ public void setEvaluateOnlyByGates(Boolean evaluateOnlyByGates) {
+ this.evaluateOnlyByGates = evaluateOnlyByGates;
+ }
+
+ public Set getSubAccessRule() {
+ return subAccessRule;
+ }
+
+ public void setSubAccessRule(Set subAccessRule) {
+ this.subAccessRule = subAccessRule;
+ }
+
+ public Boolean getCheckMapNode() {
+ return checkMapNode;
+ }
+
+ public void setCheckMapNode(Boolean checkMapNode) {
+ this.checkMapNode = checkMapNode;
+ }
+
+ public Boolean getCheckMapKeyOnly() {
+ return checkMapKeyOnly;
+ }
+
+ public void setCheckMapKeyOnly(Boolean checkMapKeyOnly) {
+ this.checkMapKeyOnly = checkMapKeyOnly;
+ }
+
+ public Set getMergedValues() {
+ return mergedValues;
+ }
+
+ public void setMergedValues(Set mergedValues) {
+ this.mergedValues = mergedValues;
+ }
+
+ public String getMergedName() {
+ return mergedName;
+ }
+
+ public void setMergedName(String mergedName) {
+ this.mergedName = mergedName;
+ }
+
+ public Boolean getGateAnyRelation() {
+ return gateAnyRelation;
+ }
+
+ public void setGateAnyRelation(Boolean gateAnyRelation) {
+ this.gateAnyRelation = gateAnyRelation;
+ }
+
+ public String toString() {
+ return uuid.toString() + " ___ " + name + " ___ " + description + " ___ " + rule + " ___ " + type + " ___ " + value;
+ }
+}
diff --git a/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/entity/Application.java b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/entity/Application.java
new file mode 100644
index 000000000..a58856dee
--- /dev/null
+++ b/services/pic-sure-auth-microapp/pic-sure-auth-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/entity/Application.java
@@ -0,0 +1,143 @@
+package edu.harvard.hms.dbmi.avillach.auth.entity;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import jakarta.persistence.*;
+
+import java.security.Principal;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ *
Defines a model for a registered application's behavior and provides application-level privilege management.