diff --git a/containers/biometric-authenticator/.gitignore b/containers/biometric-authenticator/.gitignore new file mode 100644 index 0000000..693002a --- /dev/null +++ b/containers/biometric-authenticator/.gitignore @@ -0,0 +1,40 @@ +#Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +release.properties +.flattened-pom.xml + +# Eclipse +.project +.classpath +.settings/ +bin/ + +# IntelliJ +.idea +*.ipr +*.iml +*.iws + +# NetBeans +nb-configuration.xml + +# Visual Studio Code +.vscode +.factorypath + +# OSX +.DS_Store + +# Vim +*.swp +*.swo + +# patch +*.orig +*.rej + +# Local environment +.env diff --git a/containers/biometric-authenticator/.mvn/wrapper/.gitignore b/containers/biometric-authenticator/.mvn/wrapper/.gitignore new file mode 100644 index 0000000..e72f5e8 --- /dev/null +++ b/containers/biometric-authenticator/.mvn/wrapper/.gitignore @@ -0,0 +1 @@ +maven-wrapper.jar diff --git a/containers/biometric-authenticator/.mvn/wrapper/MavenWrapperDownloader.java b/containers/biometric-authenticator/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000..1708393 --- /dev/null +++ b/containers/biometric-authenticator/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader +{ + private static final String WRAPPER_VERSION = "3.1.1"; + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/" + WRAPPER_VERSION + + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to use instead of the + * default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main( String args[] ) + { + System.out.println( "- Downloader started" ); + File baseDirectory = new File( args[0] ); + System.out.println( "- Using base directory: " + baseDirectory.getAbsolutePath() ); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File( baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH ); + String url = DEFAULT_DOWNLOAD_URL; + if ( mavenWrapperPropertyFile.exists() ) + { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try + { + mavenWrapperPropertyFileInputStream = new FileInputStream( mavenWrapperPropertyFile ); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load( mavenWrapperPropertyFileInputStream ); + url = mavenWrapperProperties.getProperty( PROPERTY_NAME_WRAPPER_URL, url ); + } + catch ( IOException e ) + { + System.out.println( "- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'" ); + } + finally + { + try + { + if ( mavenWrapperPropertyFileInputStream != null ) + { + mavenWrapperPropertyFileInputStream.close(); + } + } + catch ( IOException e ) + { + // Ignore ... + } + } + } + System.out.println( "- Downloading from: " + url ); + + File outputFile = new File( baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH ); + if ( !outputFile.getParentFile().exists() ) + { + if ( !outputFile.getParentFile().mkdirs() ) + { + System.out.println( "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + + "'" ); + } + } + System.out.println( "- Downloading to: " + outputFile.getAbsolutePath() ); + try + { + downloadFileFromURL( url, outputFile ); + System.out.println( "Done" ); + System.exit( 0 ); + } + catch ( Throwable e ) + { + System.out.println( "- Error downloading" ); + e.printStackTrace(); + System.exit( 1 ); + } + } + + private static void downloadFileFromURL( String urlString, File destination ) + throws Exception + { + if ( System.getenv( "MVNW_USERNAME" ) != null && System.getenv( "MVNW_PASSWORD" ) != null ) + { + String username = System.getenv( "MVNW_USERNAME" ); + char[] password = System.getenv( "MVNW_PASSWORD" ).toCharArray(); + Authenticator.setDefault( new Authenticator() + { + @Override + protected PasswordAuthentication getPasswordAuthentication() + { + return new PasswordAuthentication( username, password ); + } + } ); + } + URL website = new URL( urlString ); + ReadableByteChannel rbc; + rbc = Channels.newChannel( website.openStream() ); + FileOutputStream fos = new FileOutputStream( destination ); + fos.getChannel().transferFrom( rbc, 0, Long.MAX_VALUE ); + fos.close(); + rbc.close(); + } + +} diff --git a/containers/biometric-authenticator/.mvn/wrapper/maven-wrapper.properties b/containers/biometric-authenticator/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..61a2ef1 --- /dev/null +++ b/containers/biometric-authenticator/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar diff --git a/containers/biometric-authenticator/README.md b/containers/biometric-authenticator/README.md new file mode 100644 index 0000000..ea94d69 --- /dev/null +++ b/containers/biometric-authenticator/README.md @@ -0,0 +1,9 @@ +# Auth + +A example template of a conversational service (chatbot) that requests identity document presentation, and then perform a remote biometric face verification with liveness detection, by comparing the credential embed subject photo with handset user face. + +## How it works + +- A User scans the QR code of the service. Service will request presentation of an Identity credential. +- Service will receive the credential, extract embed photo +- User will \ No newline at end of file diff --git a/containers/biometric-authenticator/docker/.gitignore b/containers/biometric-authenticator/docker/.gitignore new file mode 100644 index 0000000..45c7ed6 --- /dev/null +++ b/containers/biometric-authenticator/docker/.gitignore @@ -0,0 +1 @@ +/afj/ diff --git a/containers/biometric-authenticator/docker/docker-compose.yml b/containers/biometric-authenticator/docker/docker-compose.yml new file mode 100644 index 0000000..037fef5 --- /dev/null +++ b/containers/biometric-authenticator/docker/docker-compose.yml @@ -0,0 +1,78 @@ +version: '3.3' + +services: + + artemis: + image: joylife/apache-artemis:2.20.0 + ports: + - "8161:8161" + - "61616:61616" + - "5672:5672" + restart: unless-stopped + environment: + - ARTEMIS_USER=quarkus + - ARTEMIS_PASSWORD=Quar2060enbPi26 +# volumes: +# - /tmp/artemis/artemis-instance:/var/lib/artemis-instance +# - ./artemis/etc-override:/var/lib/artemis-instance/etc-override + networks: + - chatbot + + service-agent: + + image: gitlab.mobiera.com:4567/2060/2060-service-agent:dev + + networks: + - chatbot + ports: + - 2600:3000 + - 2601:3001 + environment: + - AGENT_PUBLIC_DID=did:web:p2601.ovpndev.2060.io + - AGENT_ENDPOINT=wss://p2601.ovpndev.2060.io + - ANONCREDS_SERVICE_BASE_URL=https://p2601.ovpndev.2060.io + - AGENT_INVITATION_IMAGE_URL=https://p2603.ovpndev.2060.io/avatar.png + - AGENT_NAME=Auth Demo (mj) + - USE_CORS=true + - EVENTS_BASE_URL=https://p2603.ovpndev.2060.io + volumes: + - /tmp/afj:/root/.afj + + postgres: + image: postgres:15.2 + networks: + - chatbot + ports: + - 5432:5432 + environment: + - POSTGRES_PASSWORD=2060demo + - POSTGRES_USER=gaia + - PGDATA=/var/lib/postgresql/data/pgdata + volumes: + - /tmp/postgresql:/var/lib/postgresql/data + + datastore: + image: gitlab.mobiera.com:4567/2060/2060-data-store:dev + ports: + - "2604:2604" + restart: unless-stopped + environment: + - DEBUG=1 + - QUARKUS_HTTP_PORT=2604 + - IO_TWENTYSIXTY_DATASTORE_TMP_DIR=/tmp/data/tmp + - IO_TWENTYSIXTY_DATASTORE_TMP_LIFETIMEDAYS=5 + - IO_TWENTYSIXTY_DATASTORE_REPO_LIFETIMEDAYS=43800 + - IO_TWENTYSIXTY_DATASTORE_REPO_FS_DIR=/tmp/data/repo + - IO_TWENTYSIXTY_DATASTORE_MEDIA_MAXCHUNKS=128 + volumes: + - /tmp/data:/tmp/data + networks: + - "chatbot" + + +networks: + chatbot: + ipam: + driver: default + config: + - subnet: 172.28.0.0/27 diff --git a/containers/biometric-authenticator/mvnw b/containers/biometric-authenticator/mvnw new file mode 100755 index 0000000..eaa3d30 --- /dev/null +++ b/containers/biometric-authenticator/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/containers/biometric-authenticator/mvnw.cmd b/containers/biometric-authenticator/mvnw.cmd new file mode 100644 index 0000000..abb7c32 --- /dev/null +++ b/containers/biometric-authenticator/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/containers/biometric-authenticator/pom.xml b/containers/biometric-authenticator/pom.xml new file mode 100644 index 0000000..efe20eb --- /dev/null +++ b/containers/biometric-authenticator/pom.xml @@ -0,0 +1,228 @@ + + + 4.0.0 + io.2060.demos + biometric-authenticator + 1.0.0 + Biometric Authenticator + How to authenticate a user by comparing her/his face with the photo embeded in her/his ID Verificable Credential + https://github.com/2060-io/2060-demos + + + The Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + Fabrice Rochette + f@2060.io + 2060 OÜ + https://2060.io + + + + scm:git:git://github.com/2060-io/2060-demos.git + scm:git:ssh://github.com/2060-io/2060-demos.git + https://github.com/2060-io/2060-demos/tree/main + + + + 3.10.1 + 17 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 3.6.4 + true + 3.0.0-M7 + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + + + io.twentysixty + 2060-service-agent-java-client + 2.0-quarkus3 + + + com.sun.mail + javax.mail + 1.6.2 + + + + io.quarkus + quarkus-arc + + + io.quarkus + quarkus-resteasy + + + org.jboss.resteasy + resteasy-multipart-provider + + + io.quarkus + quarkus-resteasy-jackson + + + io.quarkus + quarkus-smallrye-openapi + + + io.quarkus + quarkus-hibernate-orm + + + io.quarkus + quarkus-jdbc-postgresql + + + io.quarkus + quarkus-rest-client + + + io.quarkiverse.artemis + quarkus-artemis-core + 3.1.3 + + + io.quarkiverse.artemis + quarkus-artemis-jms + 3.1.3 + + + org.graalvm.sdk + graal-sdk + + + io.quarkus + quarkus-container-image-jib + + + commons-codec + commons-codec + + +io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + + + + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + true + + + + build + generate-code + generate-code-tests + + + + + + maven-compiler-plugin + ${compiler-plugin.version} + + + -parameters + + + + + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + + + native + + + native + + + + false + native + + + + + + + + gitlab-maven-2060-group + ${CI_API_V4_URL}/groups/80/-/packages/maven + + + + + sa-java-client-unauth + https://gitlab.mobiera.com/api/v4/projects/298/packages/maven + + + + + + diff --git a/containers/biometric-authenticator/src/main/docker/Dockerfile.jvm b/containers/biometric-authenticator/src/main/docker/Dockerfile.jvm new file mode 100644 index 0000000..6a6c9cc --- /dev/null +++ b/containers/biometric-authenticator/src/main/docker/Dockerfile.jvm @@ -0,0 +1,93 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./mvnw package +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/chatbot-demo-jvm . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/chatbot-demo-jvm +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005 +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/chatbot-demo-jvm +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-17:1.14 + +ENV LANGUAGE='en_US:en' + + +# We make four distinct layers so if there are application changes the library layers can be re-used +COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/ +COPY --chown=185 target/quarkus-app/*.jar /deployments/ +COPY --chown=185 target/quarkus-app/app/ /deployments/app/ +COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/ + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + diff --git a/containers/biometric-authenticator/src/main/docker/Dockerfile.legacy-jar b/containers/biometric-authenticator/src/main/docker/Dockerfile.legacy-jar new file mode 100644 index 0000000..16f10a6 --- /dev/null +++ b/containers/biometric-authenticator/src/main/docker/Dockerfile.legacy-jar @@ -0,0 +1,89 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./mvnw package -Dquarkus.package.type=legacy-jar +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/chatbot-demo-legacy-jar . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/chatbot-demo-legacy-jar +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005 +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/chatbot-demo-legacy-jar +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-17:1.14 + +ENV LANGUAGE='en_US:en' + + +COPY target/lib/* /deployments/lib/ +COPY target/*-runner.jar /deployments/quarkus-run.jar + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" diff --git a/containers/biometric-authenticator/src/main/docker/Dockerfile.native b/containers/biometric-authenticator/src/main/docker/Dockerfile.native new file mode 100644 index 0000000..4301d2c --- /dev/null +++ b/containers/biometric-authenticator/src/main/docker/Dockerfile.native @@ -0,0 +1,27 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# +# Before building the container image run: +# +# ./mvnw package -Pnative +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native -t quarkus/chatbot-demo . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/chatbot-demo +# +### +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root target/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/containers/biometric-authenticator/src/main/docker/Dockerfile.native-micro b/containers/biometric-authenticator/src/main/docker/Dockerfile.native-micro new file mode 100644 index 0000000..5faebfc --- /dev/null +++ b/containers/biometric-authenticator/src/main/docker/Dockerfile.native-micro @@ -0,0 +1,30 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# It uses a micro base image, tuned for Quarkus native executables. +# It reduces the size of the resulting container image. +# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. +# +# Before building the container image run: +# +# ./mvnw package -Pnative +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/chatbot-demo . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/chatbot-demo +# +### +FROM quay.io/quarkus/quarkus-micro-image:2.0 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root target/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/ex/MediaAlreadyLinkedException.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/ex/MediaAlreadyLinkedException.java new file mode 100644 index 0000000..a328883 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/ex/MediaAlreadyLinkedException.java @@ -0,0 +1,7 @@ +package io.twentysixty.demos.auth.ex; + +public class MediaAlreadyLinkedException extends Exception { + + private static final long serialVersionUID = -3472533317786392124L; + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/ex/NoMediaException.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/ex/NoMediaException.java new file mode 100644 index 0000000..72c3d32 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/ex/NoMediaException.java @@ -0,0 +1,7 @@ +package io.twentysixty.demos.auth.ex; + +public class NoMediaException extends Exception { + + private static final long serialVersionUID = -3472533317786392124L; + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/ex/TokenException.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/ex/TokenException.java new file mode 100644 index 0000000..0356cb8 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/ex/TokenException.java @@ -0,0 +1,7 @@ +package io.twentysixty.demos.auth.ex; + +public class TokenException extends Exception { + + private static final long serialVersionUID = -3472533317786392124L; + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/model/Session.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/model/Session.java new file mode 100644 index 0000000..8b37601 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/model/Session.java @@ -0,0 +1,136 @@ +package io.twentysixty.demos.auth.model; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.util.UUID; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.NamedQueries; +import jakarta.persistence.NamedQuery; +import jakarta.persistence.Table; + +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; + + + +/** + * The persistent class for the session database table. + * + */ +@Entity +@Table(name="session") +@DynamicUpdate +@DynamicInsert +@NamedQueries({ + @NamedQuery(name="Session.findWithToken", query="SELECT s FROM Session s where s.token=:token"), + +}) +public class Session implements Serializable { + private static final long serialVersionUID = 1L; + + + @Id + private UUID connectionId; + + + + @Column(columnDefinition="text") + private String citizenId; + @Column(columnDefinition="text") + private String firstname; + @Column(columnDefinition="text") + private String lastname; + + @Column(columnDefinition="date") + private LocalDate birthdate; + @Column(columnDefinition="text") + private String placeOfBirth; + + private UUID photo; + + private UUID token; + + @Column(columnDefinition="timestamptz") + private Instant authTs; + + + public UUID getConnectionId() { + return connectionId; + } + + public void setConnectionId(UUID connectionId) { + this.connectionId = connectionId; + } + + public String getCitizenId() { + return citizenId; + } + + public void setCitizenId(String citizenId) { + this.citizenId = citizenId; + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public LocalDate getBirthdate() { + return birthdate; + } + + public void setBirthdate(LocalDate birthdate) { + this.birthdate = birthdate; + } + + public String getPlaceOfBirth() { + return placeOfBirth; + } + + public void setPlaceOfBirth(String placeOfBirth) { + this.placeOfBirth = placeOfBirth; + } + + public UUID getPhoto() { + return photo; + } + + public void setPhoto(UUID photo) { + this.photo = photo; + } + + public UUID getToken() { + return token; + } + + public void setToken(UUID token) { + this.token = token; + } + + public Instant getAuthTs() { + return authTs; + } + + public void setAuthTs(Instant authTs) { + this.authTs = authTs; + } + + + +} \ No newline at end of file diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MoConsumer.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MoConsumer.java new file mode 100644 index 0000000..abbacfe --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MoConsumer.java @@ -0,0 +1,72 @@ +package io.twentysixty.demos.auth.registry.jms; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; +import jakarta.jms.ConnectionFactory; + +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.jboss.logging.Logger; + +import io.quarkus.runtime.ShutdownEvent; +import io.quarkus.runtime.StartupEvent; +import io.twentysixty.demos.auth.svc.Service; +import io.twentysixty.sa.client.jms.AbstractConsumer; +import io.twentysixty.sa.client.jms.ConsumerInterface; +import io.twentysixty.sa.client.model.message.BaseMessage; + +@ApplicationScoped +public class MoConsumer extends AbstractConsumer implements ConsumerInterface { + + @Inject Service gaiaService; + + @Inject + ConnectionFactory _connectionFactory; + + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.ex.delay") + Long _exDelay; + + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.mo.queue.name") + String _queueName; + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.mo.consumer.threads") + Integer _threads; + + @ConfigProperty(name = "io.twentysixty.demos.auth.debug") + Boolean _debug; + + private static final Logger logger = Logger.getLogger(MoConsumer.class); + + + void onStart(@Observes StartupEvent ev) { + + logger.info("onStart: SaConsumer queueName: " + _queueName); + + this.setExDelay(_exDelay); + this.setDebug(_debug); + this.setQueueName(_queueName); + this.setThreads(_threads); + this.setConnectionFactory(_connectionFactory); + super._onStart(); + + } + + void onStop(@Observes ShutdownEvent ev) { + + logger.info("onStop: SaConsumer"); + + super._onStop(); + + } + + @Override + public void receiveMessage(BaseMessage message) throws Exception { + + gaiaService.userInput(message); + + } + + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MoProducer.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MoProducer.java new file mode 100644 index 0000000..8f737e8 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MoProducer.java @@ -0,0 +1,71 @@ +package io.twentysixty.demos.auth.registry.jms; + + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; +import jakarta.jms.ConnectionFactory; + +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.jboss.logging.Logger; + +import io.quarkus.runtime.ShutdownEvent; +import io.quarkus.runtime.StartupEvent; +import io.twentysixty.sa.client.jms.AbstractProducer; +import io.twentysixty.sa.client.jms.ProducerInterface; +import io.twentysixty.sa.client.model.message.BaseMessage; + + +@ApplicationScoped +public class MoProducer extends AbstractProducer implements ProducerInterface { + + @Inject + ConnectionFactory _connectionFactory; + + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.ex.delay") + Long _exDelay; + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.mo.queue.name") + String _queueName; + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.mo.producer.threads") + Integer _threads; + + @ConfigProperty(name = "io.twentysixty.demos.auth.debug") + Boolean _debug; + + + + private static final Logger logger = Logger.getLogger(MoProducer.class); + + + void onStart(@Observes StartupEvent ev) { + logger.info("onStart: SaProducer"); + + this.setExDelay(_exDelay); + this.setDebug(_debug); + this.setQueueName(_queueName); + this.setThreads(_threads); + this.setConnectionFactory(_connectionFactory); + this.setProducerCount(_threads); + + } + + void onStop(@Observes ShutdownEvent ev) { + logger.info("onStop: SaProducer"); + } + + + @Override + public void sendMessage(BaseMessage message) throws Exception { + this.spool(message, 0); + } + + + + + + + +} \ No newline at end of file diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MtConsumer.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MtConsumer.java new file mode 100644 index 0000000..454dbe1 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MtConsumer.java @@ -0,0 +1,79 @@ +package io.twentysixty.demos.auth.registry.jms; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; +import jakarta.jms.ConnectionFactory; + +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.eclipse.microprofile.rest.client.inject.RestClient; +import org.jboss.logging.Logger; + +import io.quarkus.runtime.ShutdownEvent; +import io.quarkus.runtime.StartupEvent; +import io.twentysixty.sa.client.jms.AbstractConsumer; +import io.twentysixty.sa.client.jms.ConsumerInterface; +import io.twentysixty.sa.client.model.message.BaseMessage; +import io.twentysixty.sa.res.c.MessageResource; + +@ApplicationScoped +public class MtConsumer extends AbstractConsumer implements ConsumerInterface { + + @RestClient + @Inject + MessageResource messageResource; + + + @Inject + ConnectionFactory _connectionFactory; + + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.ex.delay") + Long _exDelay; + + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.mt.queue.name") + String _queueName; + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.mt.consumer.threads") + Integer _threads; + + @ConfigProperty(name = "io.twentysixty.demos.auth.debug") + Boolean _debug; + + + private static final Logger logger = Logger.getLogger(MtConsumer.class); + + + + void onStart(@Observes StartupEvent ev) { + + logger.info("onStart: BeConsumer queueName: " + _queueName); + + this.setExDelay(_exDelay); + this.setDebug(_debug); + this.setQueueName(_queueName); + this.setThreads(_threads); + this.setConnectionFactory(_connectionFactory); + super._onStart(); + + } + + void onStop(@Observes ShutdownEvent ev) { + + logger.info("onStop: BeConsumer"); + + + super._onStop(); + + } + + @Override + public void receiveMessage(BaseMessage message) throws Exception { + + messageResource.sendMessage(message); + + } + + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MtProducer.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MtProducer.java new file mode 100644 index 0000000..2bcfd0a --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/registry/jms/MtProducer.java @@ -0,0 +1,73 @@ +package io.twentysixty.demos.auth.registry.jms; + + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; +import jakarta.jms.ConnectionFactory; + +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.jboss.logging.Logger; + +import io.quarkus.runtime.ShutdownEvent; +import io.quarkus.runtime.StartupEvent; +import io.twentysixty.sa.client.jms.AbstractProducer; +import io.twentysixty.sa.client.model.message.BaseMessage; +import io.twentysixty.sa.client.util.JsonUtil; + + +@ApplicationScoped +public class MtProducer extends AbstractProducer { + + @Inject + ConnectionFactory _connectionFactory; + + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.ex.delay") + Long _exDelay; + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.mt.queue.name") + String _queueName; + + @ConfigProperty(name = "io.twentysixty.demos.auth.jms.mt.producer.threads") + Integer _threads; + + @ConfigProperty(name = "io.twentysixty.demos.auth.debug") + Boolean _debug; + + + + private static final Logger logger = Logger.getLogger(MtProducer.class); + + + void onStart(@Observes StartupEvent ev) { + logger.info("onStart: BeProducer"); + + this.setExDelay(_exDelay); + this.setDebug(_debug); + this.setQueueName(_queueName); + this.setThreads(_threads); + this.setConnectionFactory(_connectionFactory); + + this.setProducerCount(_threads); + + } + + void onStop(@Observes ShutdownEvent ev) { + + logger.info("onStop: BeProducer"); + } + + + @Override + public void sendMessage(BaseMessage message) throws Exception { + if(_debug) { + logger.info("sendMessage: " + JsonUtil.serialize(message, false)); + } + this.spool(message, 0); + } + + + + +} \ No newline at end of file diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/c/MediaResource.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/c/MediaResource.java new file mode 100644 index 0000000..003ffe5 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/c/MediaResource.java @@ -0,0 +1,51 @@ +package io.twentysixty.demos.auth.res.c; + +import java.util.UUID; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.MediaType; + +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; +import org.jboss.resteasy.annotations.providers.multipart.MultipartForm; + + +@RegisterRestClient +@Path("") +public interface MediaResource { + + + @GET + @Path("/r/{uuid}") + public byte[] render(@PathParam(value = "uuid") UUID uuid); + + + @PUT + @Path("/c/{uuid}/{noc}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public void createOrUpdate(@PathParam(value = "uuid") UUID uuid, + @PathParam(value = "noc") Integer numberOfChunks, + @QueryParam(value = "token") String token); + + + @PUT + @Path("/u/{uuid}/{c}") + @Consumes(MediaType.MULTIPART_FORM_DATA) + public void uploadChunk( @PathParam(value = "uuid") UUID uuid, + @PathParam(value = "c") Integer partNumber, + @QueryParam(value = "token") String token, + @MultipartForm Resource data); + + @DELETE + @Path("/d/{uuid}") + public void delete( @PathParam(value = "uuid") UUID uuid, + @QueryParam(value = "token") String token); + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/c/Resource.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/c/Resource.java new file mode 100644 index 0000000..fc9427c --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/c/Resource.java @@ -0,0 +1,15 @@ +package io.twentysixty.demos.auth.res.c; + +import java.io.InputStream; + +import jakarta.ws.rs.FormParam; +import jakarta.ws.rs.core.MediaType; + +import org.jboss.resteasy.annotations.providers.multipart.PartType; + +public class Resource { + + @FormParam("chunk") + @PartType(MediaType.APPLICATION_OCTET_STREAM) + public InputStream chunk; +} \ No newline at end of file diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/s/ConnectionEventResource.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/s/ConnectionEventResource.java new file mode 100644 index 0000000..81dc153 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/s/ConnectionEventResource.java @@ -0,0 +1,58 @@ +package io.twentysixty.demos.auth.res.s; + +import jakarta.inject.Inject; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.jboss.logging.Logger; + +import com.fasterxml.jackson.core.JsonProcessingException; + +import io.twentysixty.demos.auth.svc.Service; +import io.twentysixty.sa.client.model.event.ConnectionStateUpdated; +import io.twentysixty.sa.client.model.event.DidExchangeState; +import io.twentysixty.sa.client.res.s.ConnectionEventInterface; +import io.twentysixty.sa.client.util.JsonUtil; + +@Path("") +public class ConnectionEventResource implements ConnectionEventInterface { + + + private static Logger logger = Logger.getLogger(ConnectionEventResource.class); + + @Inject Service service; + @ConfigProperty(name = "io.twentysixty.demos.auth.debug") + Boolean debug; + + + @Override + @POST + @Path("/connection-state-updated") + @Produces("application/json") + public Response connectionStateUpdated(ConnectionStateUpdated event) { + if (debug) { + try { + logger.info("connectionStateUpdated: " + JsonUtil.serialize(event, false)); + } catch (JsonProcessingException e) { + logger.error("", e); + } + } + if (event.getState().equals(DidExchangeState.COMPLETED)) { + try { + service.newConnection(event.getConnectionId()); + } catch (Exception e) { + + logger.error("", e); + return Response.status(Status.INTERNAL_SERVER_ERROR).build(); + } + } + + return Response.status(Status.OK).build(); + + } + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/s/MessageEventResource.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/s/MessageEventResource.java new file mode 100644 index 0000000..2102211 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/s/MessageEventResource.java @@ -0,0 +1,128 @@ +package io.twentysixty.demos.auth.res.s; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import jakarta.inject.Inject; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.jboss.logging.Logger; + +import com.fasterxml.jackson.core.JsonProcessingException; + +import io.twentysixty.demos.auth.registry.jms.MoProducer; +import io.twentysixty.demos.auth.registry.jms.MtProducer; +import io.twentysixty.sa.client.model.event.MessageReceived; +import io.twentysixty.sa.client.model.event.MessageState; +import io.twentysixty.sa.client.model.event.MessageStateUpdated; +import io.twentysixty.sa.client.model.message.MessageReceiptOptions; +import io.twentysixty.sa.client.model.message.ReceiptsMessage; +import io.twentysixty.sa.client.res.s.MessageEventInterface; +import io.twentysixty.sa.client.util.JsonUtil; + + + + +@Path("") +public class MessageEventResource implements MessageEventInterface { + + private static Logger logger = Logger.getLogger(MessageEventResource.class); + + + + @Inject MoProducer moProducer; + @Inject MtProducer mtProducer; + + @ConfigProperty(name = "io.twentysixty.demos.auth.debug") + Boolean debug; + + @Override + @POST + @Path("/message-received") + @Produces("application/json") + public Response messageReceived(MessageReceived event) { + + if (debug) { + try { + logger.info("messageReceived: " + JsonUtil.serialize(event, false)); + } catch (JsonProcessingException e) { + logger.error("", e); + } + } + + + List receipts = new ArrayList(); + + /*MessageReceiptOptions received = new MessageReceiptOptions(); + received.setMessageId(event.getMessage().getId()); + received.setTimestamp(Instant.now()); + received.setState(MessageState.RECEIVED); + receipts.add(received); + */ + + MessageReceiptOptions viewed = new MessageReceiptOptions(); + viewed.setMessageId(event.getMessage().getId()); + viewed.setTimestamp(Instant.now()); + viewed.setState(MessageState.VIEWED); + receipts.add(viewed); + + ReceiptsMessage r = new ReceiptsMessage(); + r.setConnectionId(event.getMessage().getConnectionId()); + r.setReceipts(receipts); + + try { + mtProducer.sendMessage(r); + + + //messageResource.sendMessage(r); + } catch (Exception e) { + logger.error("", e); + } + + + if (debug) { + try { + logger.info("messageReceived: sent receipts:" + JsonUtil.serialize(r, false)); + } catch (JsonProcessingException e) { + logger.error("", e); + } + } + + try { + moProducer.sendMessage(event.getMessage()); + } catch (Exception e) { + logger.error("", e); + return Response.status(Status.INTERNAL_SERVER_ERROR).build(); + } + + return Response.status(Status.OK).build(); + + + + } + + @Override + @POST + @Path("/message-state-updated") + @Produces("application/json") + public Response messageStateUpdated(MessageStateUpdated event) { + + if (debug) { + try { + logger.info("messageStateUpdated: " + JsonUtil.serialize(event, false)); + } catch (JsonProcessingException e) { + logger.error("", e); + } + } + return Response.status(Status.OK).build(); + } + + + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/s/VisionResource.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/s/VisionResource.java new file mode 100644 index 0000000..76ec150 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/res/s/VisionResource.java @@ -0,0 +1,140 @@ +package io.twentysixty.demos.auth.res.s; + +import java.util.List; +import java.util.UUID; + +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; +import org.jboss.logging.Logger; + +import io.twentysixty.demos.auth.ex.TokenException; +import io.twentysixty.demos.auth.svc.VisionService; + +@Path("") +public class VisionResource { + + + private static Logger logger = Logger.getLogger(VisionResource.class); + + @Inject VisionService service; + @ConfigProperty(name = "io.twentysixty.demos.auth.debug") + Boolean debug; + + + + + + + @GET + @Path("/list/{token}") + @Produces("application/json") + @Operation(summary = "List ids (UUID) of medias", + description = "List of mediaIds (UUID) of type {type} linked to identity represented by token {token}") + @APIResponses({ + @APIResponse(responseCode = "400", description = "Check arguments or expired token"), + @APIResponse(responseCode = "403", description = "Permission Denied."), + @APIResponse(responseCode = "500", description = "Server error, please retry."), + + @APIResponse(responseCode = "200", description = "OK") } + ) + public Response listMedias(@PathParam(value = "token") UUID token) { + + if (token == null) { + return Response.status(Status.BAD_REQUEST).build(); + } + + try { + List medias = service.listMedias(token); + return Response.status(Status.OK).entity(medias).build(); + } catch (TokenException e) { + logger.error("", e); + return Response.status(Status.BAD_REQUEST).build(); + } catch (Exception e) { + logger.error("", e); + return Response.status(Status.INTERNAL_SERVER_ERROR).build(); + } + + + + } + + + @PUT + @Path("/success/{token}") + @Operation(summary = "Notify a successful verification or capture", + description = "Notify a successful verification or capture for identity represented by token {token}.") + @APIResponses({ + @APIResponse(responseCode = "400", description = "Check arguments or expired token."), + @APIResponse(responseCode = "403", description = "Permission Denied."), + @APIResponse(responseCode = "500", description = "Server error, please retry."), + + @APIResponse(responseCode = "200", description = "OK") } + ) + public Response success(@PathParam(value = "token") UUID token) { + + if (token == null) { + return Response.status(Status.BAD_REQUEST).build(); + } + + try { + service.success(token); + + return Response.status(Status.OK).build(); + } catch (TokenException e) { + logger.error("", e); + return Response.status(Status.BAD_REQUEST).build(); + } catch (Exception e) { + logger.error("", e); + return Response.status(Status.INTERNAL_SERVER_ERROR).build(); + } + + + } + + @PUT + @Path("/failure/{token}") + @Operation(summary = "Notify a failed verification or capture", + description = "Notify a failed verification or capture for Identity represented by token {token}.") + @APIResponses({ + @APIResponse(responseCode = "400", description = "Check arguments or expired token."), + @APIResponse(responseCode = "403", description = "Permission Denied."), + @APIResponse(responseCode = "500", description = "Server error, please retry."), + + @APIResponse(responseCode = "200", description = "OK") } + ) + public Response failure(@PathParam(value = "token") UUID token) { + + if (token == null ) { + return Response.status(Status.BAD_REQUEST).build(); + } + + try { + service.failure(token); + + return Response.status(Status.OK).build(); + } catch (TokenException e) { + logger.error("", e); + return Response.status(Status.BAD_REQUEST).build(); + } catch (Exception e) { + logger.error("", e); + return Response.status(Status.INTERNAL_SERVER_ERROR).build(); + } + + + } + + +} + + diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/svc/Service.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/svc/Service.java new file mode 100644 index 0000000..2087f42 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/svc/Service.java @@ -0,0 +1,504 @@ +package io.twentysixty.demos.auth.svc; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.ResourceBundle; +import java.util.UUID; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.persistence.EntityManager; +import jakarta.transaction.Transactional; + +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.eclipse.microprofile.rest.client.inject.RestClient; +import org.graalvm.collections.Pair; +import org.jboss.logging.Logger; +import org.jgroups.util.Base64; + +import com.fasterxml.jackson.core.JsonProcessingException; + +import io.twentysixty.demos.auth.model.Session; +import io.twentysixty.demos.auth.registry.jms.MtProducer; +import io.twentysixty.demos.auth.res.c.MediaResource; +import io.twentysixty.demos.auth.res.c.Resource; +import io.twentysixty.sa.client.model.credential.CredentialType; +import io.twentysixty.sa.client.model.message.BaseMessage; +import io.twentysixty.sa.client.model.message.Claim; +import io.twentysixty.sa.client.model.message.ContextualMenuItem; +import io.twentysixty.sa.client.model.message.ContextualMenuSelect; +import io.twentysixty.sa.client.model.message.ContextualMenuUpdate; +import io.twentysixty.sa.client.model.message.IdentityProofRequestMessage; +import io.twentysixty.sa.client.model.message.IdentityProofSubmitMessage; +import io.twentysixty.sa.client.model.message.InvitationMessage; +import io.twentysixty.sa.client.model.message.MediaItem; +import io.twentysixty.sa.client.model.message.MediaMessage; +import io.twentysixty.sa.client.model.message.MenuSelectMessage; +import io.twentysixty.sa.client.model.message.RequestedProofItem; +import io.twentysixty.sa.client.model.message.SubmitProofItem; +import io.twentysixty.sa.client.model.message.TextMessage; +import io.twentysixty.sa.client.util.JsonUtil; +import io.twentysixty.sa.res.c.CredentialTypeResource; + + + +@ApplicationScoped +public class Service { + + private static Logger logger = Logger.getLogger(Service.class); + + @Inject EntityManager em; + + @RestClient + @Inject MediaResource mediaResource; + + + @Inject MtProducer mtProducer; + + @RestClient + @Inject CredentialTypeResource credentialTypeResource; + + @ConfigProperty(name = "io.twentysixty.demos.auth.debug") + Boolean debug; + + + @ConfigProperty(name = "io.twentysixty.demos.auth.credential_issuer") + String credentialIssuer; + + @ConfigProperty(name = "io.twentysixty.demos.auth.credential_issuer.avatar") + String invitationImageUrl; + + + + @ConfigProperty(name = "io.twentysixty.demos.auth.id_credential_def") + String credDef; + + @ConfigProperty(name = "io.twentysixty.demos.auth.messages.welcome") + String WELCOME; + + @ConfigProperty(name = "io.twentysixty.demos.auth.messages.welcome2") + Optional WELCOME2; + + @ConfigProperty(name = "io.twentysixty.demos.auth.messages.welcome3") + Optional WELCOME3; + + + @ConfigProperty(name = "io.twentysixty.demos.auth.messages.nocred") + String NO_CRED_MSG; + + + + @ConfigProperty(name = "io.twentysixty.demos.auth.language") + Optional language; + + @ConfigProperty(name = "io.twentysixty.demos.auth.vision.face.verification.url") + String faceVerificationUrl; + + @ConfigProperty(name = "io.twentysixty.demos.auth.vision.redirdomain") + Optional redirDomain; + + @ConfigProperty(name = "io.twentysixty.demos.auth.vision.redirdomain.q") + Optional qRedirDomain; + + @ConfigProperty(name = "io.twentysixty.demos.auth.vision.redirdomain.d") + Optional dRedirDomain; + + private static String CMD_ROOT_MENU_AUTHENTICATE = "/auth"; + private static String CMD_ROOT_MENU_NO_CRED = "/nocred"; + private static String CMD_ROOT_MENU_OPTION1 = "/option1"; + private static String CMD_ROOT_MENU_LOGOUT = "/logout"; + + + + + @ConfigProperty(name = "io.twentysixty.demos.auth.messages.root.menu.title") + String ROOT_MENU_TITLE; + + + @ConfigProperty(name = "io.twentysixty.demos.auth.messages.root.menu.option1") + String ROOT_MENU_OPTION1; + + @ConfigProperty(name = "io.twentysixty.demos.auth.messages.option1") + String OPTION1_MSG; + + + + + + + //private static HashMap sessions = new HashMap(); + private static CredentialType type = null; + private static Object lockObj = new Object(); + + + + public void newConnection(UUID connectionId) throws Exception { + UUID threadId = UUID.randomUUID(); + mtProducer.sendMessage(TextMessage.build(connectionId,threadId , WELCOME)); + if (WELCOME2.isPresent()) { + mtProducer.sendMessage(TextMessage.build(connectionId, threadId, WELCOME2.get())); + } + if (WELCOME3.isPresent()) { + mtProducer.sendMessage(TextMessage.build(connectionId, threadId, WELCOME3.get())); + } + + + mtProducer.sendMessage(this.getRootMenu(connectionId, null)); + + //entryPointCreate(connectionId, null, null); + } + + private BaseMessage getIdentityCredentialRequest(UUID connectionId, UUID threadId) { + IdentityProofRequestMessage ip = new IdentityProofRequestMessage(); + ip.setConnectionId(connectionId); + ip.setThreadId(threadId); + + RequestedProofItem id = new RequestedProofItem(); + id.setCredentialDefinitionId(credDef); + id.setType("verifiable-credential"); + List attributes = new ArrayList(); + attributes.add("firstname"); + attributes.add("lastname"); + attributes.add("photo"); + id.setAttributes(attributes); + + List rpi = new ArrayList(); + rpi.add(id); + + ip.setRequestedProofItems(rpi); + + + try { + logger.info("getCredentialRequest: claim: " + JsonUtil.serialize(ip, false)); + } catch (Exception e) { + + } + return ip; + } + + private Session getSession(UUID connectionId) { + Session session = em.find(Session.class, connectionId); + if (session == null) { + session = new Session(); + session.setConnectionId(connectionId); + em.persist(session); + + } + + return session; + } + + + + Pair getImage(String image) { + String mimeType = null; + byte[] imageBytes = null; + + String[] separated = image.split(";"); + if (separated.length>1) { + String[] mimeTypeData = separated[0].split(":"); + String[] imageData = separated[1].split(","); + + if (mimeTypeData.length>1) { + mimeType = mimeTypeData[1]; + } + if (imageData.length>1) { + String base64Image = imageData[1]; + if (base64Image != null) { + try { + imageBytes = Base64.decode(base64Image); + } catch (IOException e) { + logger.error("", e); + } + } + } + + } + + if (mimeType == null) return null; + if (imageBytes == null) return null; + + return Pair.create(mimeType, imageBytes); + + } + ResourceBundle bundle = null; + + private String getMessage(String messageName) { + String retval = messageName; + if (bundle == null) { + if (language.isPresent()) { + try { + bundle = ResourceBundle.getBundle("META-INF/resources/Messages", new Locale(language.get())); + } catch (Exception e) { + bundle = ResourceBundle.getBundle("META-INF/resources/Messages", new Locale("en")); + } + } else { + bundle = ResourceBundle.getBundle("META-INF/resources/Messages", new Locale("en")); + } + + } + try { + retval = bundle.getString(messageName); + } catch (Exception e) { + + } + + + return retval; + } + + private String buildVisionUrl(String url) { + + if(redirDomain.isPresent()) { + url = url + "&rd=" + redirDomain.get(); + } + if(qRedirDomain.isPresent()) { + url = url + "&q=" + qRedirDomain.get(); + } + if(dRedirDomain.isPresent()) { + url = url + "&d=" + dRedirDomain.get(); + } + if (language.isPresent()) { + url = url + "&lang=" + language.get(); + } + + return url; + } + private BaseMessage generateFaceVerificationMediaMessage(UUID connectionId, UUID threadId, String token) { + String url = faceVerificationUrl.replaceFirst("TOKEN", token); + url = this.buildVisionUrl(url); + + MediaItem mi = new MediaItem(); + mi.setMimeType("text/html"); + mi.setUri(url); + mi.setTitle(getMessage("FACE_VERIFICATION_HEADER")); + mi.setDescription(getMessage("FACE_VERIFICATION_DESC")); + mi.setOpeningMode("normal"); + List mis = new ArrayList(); + mis.add(mi); + MediaMessage mm = new MediaMessage(); + mm.setConnectionId(connectionId); + mm.setThreadId(threadId); + mm.setDescription(getMessage("FACE_VERIFICATION_DESC")); + mm.setItems(mis); + return mm; + } + + + @Transactional + public void userInput(BaseMessage message) throws Exception { + + Session session = this.getSession(message.getConnectionId()); + + + String content = null; + + MediaMessage mm = null; + + if (message instanceof TextMessage) { + + TextMessage textMessage = (TextMessage) message; + content = textMessage.getContent(); + + } else if ((message instanceof ContextualMenuSelect) ) { + + ContextualMenuSelect menuSelect = (ContextualMenuSelect) message; + content = menuSelect.getSelectionId(); + + } else if ((message instanceof MenuSelectMessage)) { + + MenuSelectMessage menuSelect = (MenuSelectMessage) message; + content = menuSelect.getMenuItems().iterator().next().getId(); + } else if ((message instanceof MediaMessage)) { + mm = (MediaMessage) message; + content = "media"; + } else if ((message instanceof IdentityProofSubmitMessage)) { + if (session.getAuthTs() == null) { + try { + logger.info("userInput: claim: " + JsonUtil.serialize(message, false)); + } catch (JsonProcessingException e) { + + } + boolean sentVerifLink = false; + IdentityProofSubmitMessage ipm = (IdentityProofSubmitMessage) message; + if (ipm.getSubmittedProofItems().size()>0) { + + SubmitProofItem sp = ipm.getSubmittedProofItems().iterator().next(); + if (sp.getClaims().size()>0) { + + UUID identityId = null; + String firstname = null; + String lastname = null; + String photo = null; + + for (Claim c: sp.getClaims()) { + if (c.getName().equals("id")) { + identityId = UUID.fromString(c.getValue()); + } else if (c.getName().equals("firstname")) { + firstname = c.getValue(); + } else if (c.getName().equals("lastname")) { + lastname = c.getValue(); + } else if (c.getName().equals("photo")) { + photo = c.getValue(); + logger.info("userInput: photo: " + photo); + } + } + session.setFirstname(firstname); + session.setLastname(lastname); + + if (photo != null) { + Pair imageData = getImage(photo); + if (imageData != null) { + UUID mediaUUID = UUID.randomUUID(); + mediaResource.createOrUpdate(mediaUUID, 1, mediaUUID.toString()); + + + File file = new File(System.getProperty("java.io.tmpdir") + "/" + mediaUUID); + + FileOutputStream fos = new FileOutputStream(file); + fos.write(imageData.getRight()); + fos.flush(); + fos.close(); + + Resource r = new Resource(); + r.chunk = new FileInputStream(file); + mediaResource.uploadChunk(mediaUUID, 0, mediaUUID.toString(), r); + + file.delete(); + session.setPhoto(mediaUUID); + session.setToken(UUID.randomUUID()); + em.merge(session); + + mtProducer.sendMessage(generateFaceVerificationMediaMessage(message.getConnectionId(), message.getThreadId(), session.getToken().toString())); + + sentVerifLink = true; + } + } + + + } + } + if (!sentVerifLink) { + mtProducer.sendMessage(TextMessage.build(message.getConnectionId(), message.getThreadId() , this.getMessage("CREDENTIAL_ERROR"))); + + } + } + + } + if (content != null) { + if (content.equals(CMD_ROOT_MENU_AUTHENTICATE.toString())) { + mtProducer.sendMessage(this.getIdentityCredentialRequest(message.getConnectionId(), message.getThreadId())); + } else if (content.equals(CMD_ROOT_MENU_OPTION1.toString())) { + mtProducer.sendMessage(TextMessage.build(message.getConnectionId(), message.getThreadId() , OPTION1_MSG)); + + } else if (content.equals(CMD_ROOT_MENU_NO_CRED.toString())) { + + mtProducer.sendMessage(TextMessage.build(message.getConnectionId(), message.getThreadId() , NO_CRED_MSG)); + + + InvitationMessage invitation = new InvitationMessage(); + invitation.setConnectionId(message.getConnectionId()); + invitation.setThreadId(message.getThreadId()); + invitation.setImageUrl(invitationImageUrl); + invitation.setDid(credentialIssuer); + + mtProducer.sendMessage(invitation); + + } else if (content.equals(CMD_ROOT_MENU_LOGOUT.toString())) { + if (session != null) { + session.setAuthTs(null); + session = em.merge(session); + } + mtProducer.sendMessage(TextMessage.build(message.getConnectionId(), message.getThreadId() , this.getMessage("UNAUTHENTICATED"))); + + } else { + mtProducer.sendMessage(TextMessage.build(message.getConnectionId(), message.getThreadId() , this.getMessage("ERROR"))); + } + } + mtProducer.sendMessage(this.getRootMenu(message.getConnectionId(), session)); + } + + @Transactional + public void notifySuccess(UUID connectionId) { + Session session = em.find(Session.class, connectionId); + if (session != null) { + try { + session.setAuthTs(Instant.now()); + session = em.merge(session); + mtProducer.sendMessage(TextMessage.build(connectionId, null , this.getMessage("AUTHENTICATION_SUCCESS"))); + } catch (Exception e) { + logger.error("", e); + } + } + try { + mtProducer.sendMessage(this.getRootMenu(connectionId, session)); + } catch (Exception e) { + logger.error("", e); + } + } + + public void notifyFailure(UUID connectionId) { + Session session = em.find(Session.class, connectionId); + if (session != null) { + try { + mtProducer.sendMessage(TextMessage.build(connectionId, null , this.getMessage("AUTHENTICATION_ERROR"))); + + mtProducer.sendMessage(generateFaceVerificationMediaMessage(connectionId, null, session.getToken().toString())); + } catch (Exception e) { + logger.error("", e); + } + } + } + + + + public BaseMessage getRootMenu(UUID connectionId, Session session) { + + ContextualMenuUpdate menu = new ContextualMenuUpdate(); + menu.setTitle(ROOT_MENU_TITLE); + + + List options = new ArrayList(); + + + if ((session == null) || (session.getAuthTs() == null) ){ + menu.setDescription(getMessage("ROOT_MENU_DEFAULT_DESCRIPTION")); + options.add(ContextualMenuItem.build(CMD_ROOT_MENU_AUTHENTICATE, getMessage("ROOT_MENU_AUTHENTICATE"), null)); + options.add(ContextualMenuItem.build(CMD_ROOT_MENU_NO_CRED, getMessage("ROOT_MENU_NO_CRED"), null)); + + } else { + menu.setDescription(getMessage("ROOT_MENU_AUTHENTICATED_DESCRIPTION").replaceAll("NAME", session.getFirstname() + " " + session.getLastname())); + + options.add(ContextualMenuItem.build(CMD_ROOT_MENU_OPTION1, ROOT_MENU_OPTION1, null)); + options.add(ContextualMenuItem.build(CMD_ROOT_MENU_LOGOUT, this.getMessage("ROOT_MENU_LOGOUT"), null)); + + } + + + + menu.setOptions(options); + + + + if (debug) { + try { + logger.info("getRootMenu: " + JsonUtil.serialize(menu, false)); + } catch (JsonProcessingException e) { + } + } + menu.setConnectionId(connectionId); + menu.setId(UUID.randomUUID()); + menu.setTimestamp(Instant.now()); + + return menu; + + + } +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/svc/SessionData.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/svc/SessionData.java new file mode 100644 index 0000000..1c05c23 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/svc/SessionData.java @@ -0,0 +1,60 @@ +package io.twentysixty.demos.auth.svc; + +import java.time.LocalDate; +import java.util.UUID; + + +public class SessionData { + + + private String firstname; + private String lastname; + private LocalDate birthdate; + private String placeOfBirth; + + private UUID identityId; + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public LocalDate getBirthdate() { + return birthdate; + } + + public void setBirthdate(LocalDate birthdate) { + this.birthdate = birthdate; + } + + + + public String getPlaceOfBirth() { + return placeOfBirth; + } + + public void setPlaceOfBirth(String placeOfBirth) { + this.placeOfBirth = placeOfBirth; + } + + public UUID getIdentityId() { + return identityId; + } + + public void setIdentityId(UUID identityId) { + this.identityId = identityId; + } + + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/svc/VisionService.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/svc/VisionService.java new file mode 100644 index 0000000..642f630 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/svc/VisionService.java @@ -0,0 +1,83 @@ +package io.twentysixty.demos.auth.svc; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.persistence.EntityManager; +import jakarta.persistence.Query; + +import org.eclipse.microprofile.config.inject.ConfigProperty; + +import io.twentysixty.demos.auth.ex.TokenException; +import io.twentysixty.demos.auth.model.Session; + + +@ApplicationScoped +public class VisionService { + + + @Inject Service service; + + @Inject EntityManager em; + + + + private Session getSession(UUID token) throws TokenException { + + Session session = null; + + Query q = em.createNamedQuery("Session.findWithToken"); + q.setParameter("token", token); + + session = (Session) q.getResultList().stream().findFirst().orElse(null); + if (session == null) { + throw new TokenException(); + } + + return session; + } + + public List listMedias(UUID token) throws Exception { + + + Session session = this.getSession(token); + + + List response = new ArrayList(1); + response.add(session.getPhoto()); + + return response; + + + + } + + + + public void success(UUID token) throws Exception { + + Session session = this.getSession(token); + + service.notifySuccess(session.getConnectionId()); + + + } + + + public void failure(UUID token) throws Exception { + + Session session = this.getSession(token); + + service.notifyFailure(session.getConnectionId()); + + + + + } + + + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/testing/Test.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/testing/Test.java new file mode 100644 index 0000000..5c0b52d --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/testing/Test.java @@ -0,0 +1,16 @@ +package io.twentysixty.demos.auth.testing; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class Test { + private static DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + public static void main(String[] args) { + // TODO Auto-generated method stub + + LocalDate birthDate = LocalDate.from(df.parse("2020-01-01")); + System.out.println(birthDate); + } + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/testing/TestRB.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/testing/TestRB.java new file mode 100644 index 0000000..c21ff69 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/demos/auth/testing/TestRB.java @@ -0,0 +1,22 @@ +package io.twentysixty.demos.auth.testing; + +import java.util.Locale; +import java.util.ResourceBundle; + +public class TestRB { + + public static void main(String[] args) { + + + ResourceBundle bundle = ResourceBundle.getBundle("META-INF/resources/Messages", Locale.US); + System.out.println("Message in "+Locale.US +":"+bundle.getString("ROOT_MENU_TITLE")); + + + Locale es = new Locale("ES"); + bundle = ResourceBundle.getBundle("META-INF/resources/Messages", es); + System.out.println("Message in "+es +":"+bundle.getString("ROOT_MENU_TITLE")); + + + } + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/sa/res/c/CredentialTypeResource.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/sa/res/c/CredentialTypeResource.java new file mode 100644 index 0000000..0b87f20 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/sa/res/c/CredentialTypeResource.java @@ -0,0 +1,12 @@ +package io.twentysixty.sa.res.c; + +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; + +import io.twentysixty.sa.client.res.c.CredentialTypeInterface; + + +@RegisterRestClient +public interface CredentialTypeResource extends CredentialTypeInterface { + + +} diff --git a/containers/biometric-authenticator/src/main/java/io/twentysixty/sa/res/c/MessageResource.java b/containers/biometric-authenticator/src/main/java/io/twentysixty/sa/res/c/MessageResource.java new file mode 100644 index 0000000..007d120 --- /dev/null +++ b/containers/biometric-authenticator/src/main/java/io/twentysixty/sa/res/c/MessageResource.java @@ -0,0 +1,12 @@ +package io.twentysixty.sa.res.c; + +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; + +import io.twentysixty.sa.client.res.c.MessageInterface; + + +@RegisterRestClient +public interface MessageResource extends MessageInterface { + + +} diff --git a/containers/biometric-authenticator/src/main/resources/META-INF/resources/Messages_en.properties b/containers/biometric-authenticator/src/main/resources/META-INF/resources/Messages_en.properties new file mode 100644 index 0000000..e8f4bca --- /dev/null +++ b/containers/biometric-authenticator/src/main/resources/META-INF/resources/Messages_en.properties @@ -0,0 +1,12 @@ +CREDENTIAL_ERROR=Credential is not compatible. +AUTHENTICATION_SUCCESS=Authentication successful. +AUTHENTICATION_ERROR=Authentication error. +ROOT_MENU_AUTHENTICATE=Authenticate +ROOT_MENU_NO_CRED=Get an Identity Card +ROOT_MENU_LOGOUT=Logout +ROOT_MENU_DEFAULT_DESCRIPTION=You are not authenticated +ROOT_MENU_AUTHENTICATED_DESCRIPTION=Welcome NAME! +ERROR=We couldn't understand your message. Please check the contextual menu for available options. +FACE_VERIFICATION_HEADER=Face Verification +FACE_VERIFICATION_DESC=Start Face Verification to Authenticate yourself +UNAUTHENTICATED=You are now unauthenticated. \ No newline at end of file diff --git a/containers/biometric-authenticator/src/main/resources/META-INF/resources/Messages_es.properties b/containers/biometric-authenticator/src/main/resources/META-INF/resources/Messages_es.properties new file mode 100644 index 0000000..a1be65c --- /dev/null +++ b/containers/biometric-authenticator/src/main/resources/META-INF/resources/Messages_es.properties @@ -0,0 +1,12 @@ +CREDENTIAL_ERROR=La Credencial no es compatible. +AUTHENTICATION_SUCCESS=Ya estás autenticado. +AUTHENTICATION_ERROR=Error de autenticación. +ROOT_MENU_AUTHENTICATE=Autenticate +ROOT_MENU_NO_CRED=Obtiene tu documento de Identidad +ROOT_MENU_LOGOUT=Desconectarse +ROOT_MENU_DEFAULT_DESCRIPTION=No estas autenticado +ROOT_MENU_AUTHENTICATED_DESCRIPTION=¡Bienvenido NAME! +ERROR=No hemos podido entender tu mensaje. Accede al menú contextual para ver las opciones disponibles. +FACE_VERIFICATION_HEADER=Verificación biométrica +FACE_VERIFICATION_DESC=Autentícate con tu rostro +UNAUTHENTICATED=Estas desconectado. \ No newline at end of file diff --git a/containers/biometric-authenticator/src/main/resources/META-INF/resources/Messages_fr.properties b/containers/biometric-authenticator/src/main/resources/META-INF/resources/Messages_fr.properties new file mode 100644 index 0000000..edf1b2c --- /dev/null +++ b/containers/biometric-authenticator/src/main/resources/META-INF/resources/Messages_fr.properties @@ -0,0 +1,12 @@ +CREDENTIAL_ERROR=Attestation incompatible. +AUTHENTICATION_SUCCESS=Authentification réussie. +AUTHENTICATION_ERROR=Erreur lors de l'authentification. +ROOT_MENU_AUTHENTICATE=S'authentifier +ROOT_MENU_NO_CRED=Obtenir une Attestation d'Identité +ROOT_MENU_LOGOUT=Se Deconnecter +ROOT_MENU_DEFAULT_DESCRIPTION=Vous n'êtes pas authentifié +ROOT_MENU_AUTHENTICATED_DESCRIPTION=Bienvenue NAME! +ERROR=Nous n'avons pas compris votre messages. Accedez au menu contextuel pour les options disponibles. +FACE_VERIFICATION_HEADER=Vérification biométrique +FACE_VERIFICATION_DESC=Authentifiez-vous avec votre visage +UNAUTHENTICATED=Vous êtes déconnecté. \ No newline at end of file diff --git a/containers/biometric-authenticator/src/main/resources/META-INF/resources/avatar.old.png b/containers/biometric-authenticator/src/main/resources/META-INF/resources/avatar.old.png new file mode 100644 index 0000000..2623fa1 Binary files /dev/null and b/containers/biometric-authenticator/src/main/resources/META-INF/resources/avatar.old.png differ diff --git a/containers/biometric-authenticator/src/main/resources/META-INF/resources/avatar.old2.png b/containers/biometric-authenticator/src/main/resources/META-INF/resources/avatar.old2.png new file mode 100644 index 0000000..8fef2d9 Binary files /dev/null and b/containers/biometric-authenticator/src/main/resources/META-INF/resources/avatar.old2.png differ diff --git a/containers/biometric-authenticator/src/main/resources/META-INF/resources/avatar.png b/containers/biometric-authenticator/src/main/resources/META-INF/resources/avatar.png new file mode 100644 index 0000000..1129a82 Binary files /dev/null and b/containers/biometric-authenticator/src/main/resources/META-INF/resources/avatar.png differ diff --git a/containers/biometric-authenticator/src/main/resources/META-INF/resources/gaia.png b/containers/biometric-authenticator/src/main/resources/META-INF/resources/gaia.png new file mode 100644 index 0000000..1129a82 Binary files /dev/null and b/containers/biometric-authenticator/src/main/resources/META-INF/resources/gaia.png differ diff --git a/containers/biometric-authenticator/src/main/resources/application.properties b/containers/biometric-authenticator/src/main/resources/application.properties new file mode 100644 index 0000000..0f56069 --- /dev/null +++ b/containers/biometric-authenticator/src/main/resources/application.properties @@ -0,0 +1,80 @@ + + +io.twentysixty.demos.auth.token.lifetimeseconds=900 +io.twentysixty.demos.auth.token.lifetimeseconds=900 + + +io.twentysixty.demos.auth.language=en +io.twentysixty.demos.auth.messages.welcome=Welcome to the Auth demo service! By using this demo service you'll understand how to authenticate a user by requesting an identity credential, and by demonstrating that the mobile phone user is the same person that the one in the presented credential. +io.twentysixty.demos.auth.messages.root.menu.title=Auth demo service +io.twentysixty.demos.auth.messages.root.menu.option1=Request Support +io.twentysixty.demos.auth.messages.option1=You selected option1 in contextual menu +io.twentysixty.demos.auth.messages.nocred=If you do not have a GaiaID Identity Card (required to authenticate yourself), get one by connecting to below service. + +%dev.io.twentysixty.demos.auth.vision.redirdomain=p2604.ovpndev.2060.io +%dev.io.twentysixty.demos.auth.vision.redirdomain.q=p2603.ovpndev.2060.io +%dev.io.twentysixty.demos.auth.vision.redirdomain.d=p2604.ovpndev.2060.io + +io.twentysixty.demos.auth.vision.face.verification.url=https://vision-t.gaiaid.io/face/verification/?token=TOKEN + + +io.twentysixty.demos.auth.credential_issuer=did:web:registry.demos.dev.2060.io +io.twentysixty.demos.auth.credential_issuer.avatar=https://q.registry.demos.dev.2060.io/gaia.png +io.twentysixty.demos.auth.id_credential_def=did:web:registry.demos.dev.2060.io?service=anoncreds&relativeRef=/credDef/7QxmjvXdW2Z4tg1cZ5aSwtvBukasoH5MGn5Dx73wpmeh + + +io.twentysixty.demos.auth.jms.mo.consumer.threads=1 +io.twentysixty.demos.auth.jms.mo.producer.threads=1 +io.twentysixty.demos.auth.jms.mo.queue.name=gaia-mo +io.twentysixty.demos.auth.jms.mt.consumer.threads=1 +io.twentysixty.demos.auth.jms.mt.producer.threads=1 +io.twentysixty.demos.auth.jms.mt.queue.name=gaia-mt +io.twentysixty.demos.auth.jms.ex.delay=10000 + + +io.twentysixty.demos.auth.debug=true + +io.twentysixty.sa.res.c.CredentialTypeResource/mp-rest/url=http://sa:3000/ +io.twentysixty.sa.res.c.MessageResource/mp-rest/url=http://sa:3000/ + + +%dev.io.twentysixty.sa.res.c.CredentialTypeResource/mp-rest/url=http://localhost:2600/ +%dev.io.twentysixty.sa.res.c.MessageResource/mp-rest/url=http://localhost:2600/ + +io.twentysixty.demos.auth.res.c.MediaResource/mp-rest/url=http://ds:2904/ +%dev.io.twentysixty.demos.auth.res.c.MediaResource/mp-rest/url=http://localhost:2604/ + + +quarkus.http.host=0.0.0.0 +quarkus.http.port=2903 + +%dev.quarkus.http.port=2603 + + + +quarkus.datasource.db-kind=postgresql +quarkus.datasource.username=gaia +quarkus.datasource.password=**** +quarkus.datasource.jdbc.url=jdbc:postgresql://localhost/gaia +%dev.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost/gaia +quarkus.datasource.jdbc.max-size=8 +quarkus.datasource.jdbc.min-size=2 + +quarkus.hibernate-orm.database.generation=update + +quarkus.artemis.url=tcp://127.0.0.1:61616 +quarkus.artemis.username=quarkus +quarkus.artemis.password=**** + +quarkus.swagger-ui.always-include=true + + +quarkus.container-image.build=true +quarkus.container-image.push=true +quarkus.container-image.group=io2060 +quarkus.container-image.registry=registry.hub.docker.com +quarkus.container-image.name=2060-demos-biometric-authenticator +quarkus.jib.ports=8080 + + + diff --git a/containers/citizen-registry/pom.xml b/containers/citizen-registry/pom.xml index 6d15294..8da1393 100644 --- a/containers/citizen-registry/pom.xml +++ b/containers/citizen-registry/pom.xml @@ -7,7 +7,7 @@ 1.0.0 Citizen Registry A real DIDcomm citizen registry - https://github.com/2060-io/didcomm-service-demos + https://github.com/2060-io/2060-demos The Apache License, Version 2.0 @@ -23,9 +23,9 @@ - scm:git:git://github.com/2060-io/didcomm-service-demos.git - scm:git:ssh://github.com/2060-io/didcomm-service-demos.git - https://github.com/2060-io/didcomm-service-demos/tree/main + scm:git:git://github.com/2060-io/2060-demos.git + scm:git:ssh://github.com/2060-io/2060-demos.git + https://github.com/2060-io/2060-demos/tree/main diff --git a/containers/citizen-registry/src/main/resources/application.properties b/containers/citizen-registry/src/main/resources/application.properties index b41dc7f..a0fdb22 100644 --- a/containers/citizen-registry/src/main/resources/application.properties +++ b/containers/citizen-registry/src/main/resources/application.properties @@ -110,7 +110,6 @@ quarkus.container-image.push=true quarkus.container-image.group=io2060 quarkus.container-image.registry=registry.hub.docker.com quarkus.container-image.name=2060-demos-citizen-registry -quarkus.container-image.tag=main quarkus.jib.ports=8080 diff --git a/containers/hello-world/pom.xml b/containers/hello-world/pom.xml index cbd5f49..51b0b58 100644 --- a/containers/hello-world/pom.xml +++ b/containers/hello-world/pom.xml @@ -7,7 +7,7 @@ 1.0.0 hello World Demo Container A simple DIDComm demo conversational service - https://github.com/2060-io/didcomm-service-demos + https://github.com/2060-io/2060-demos The Apache License, Version 2.0 @@ -23,9 +23,9 @@ - scm:git:git://github.com/2060-io/didcomm-service-demos.git - scm:git:ssh://github.com/2060-io/didcomm-service-demos.git - https://github.com/2060-io/didcomm-service-demos/tree/main + scm:git:git://github.com/2060-io/2060-demos.git + scm:git:ssh://github.com/2060-io/2060-demos.git + https://github.com/2060-io/2060-demos/tree/main 3.10.1 diff --git a/containers/hello-world/src/main/resources/application.properties b/containers/hello-world/src/main/resources/application.properties index 31814ff..a126aad 100644 --- a/containers/hello-world/src/main/resources/application.properties +++ b/containers/hello-world/src/main/resources/application.properties @@ -14,5 +14,4 @@ quarkus.container-image.push=true quarkus.container-image.group=io2060 quarkus.container-image.registry=registry.hub.docker.com quarkus.container-image.name=2060-demos-hello-world -quarkus.container-image.tag=main quarkus.jib.ports=8080