From 6d26672194a55963e5f4b9e1c981f6cfc88fa386 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Thu, 16 Jun 2022 21:24:06 +0200 Subject: [PATCH 01/58] Fix #733: Use updated version of audit library --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1075fa58a..9af4d42f3 100644 --- a/pom.xml +++ b/pom.xml @@ -95,8 +95,8 @@ 1.3.0 - 1.5.1 - 1.5.1 + 1.5.2 + 1.5.2 1.70 From e5e5dc1613f3eab087b2f0124bbe569f4c2067cf Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Thu, 16 Jun 2022 21:27:06 +0200 Subject: [PATCH 02/58] Fix #732: Improve serialization of CallbackUrlAuthenticationEntity --- .../model/entity/CallbackUrlAuthenticationEntity.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/CallbackUrlAuthenticationEntity.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/CallbackUrlAuthenticationEntity.java index 5bb7769c9..2586efdb0 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/CallbackUrlAuthenticationEntity.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/CallbackUrlAuthenticationEntity.java @@ -67,7 +67,9 @@ public void setHttpBasic(HttpBasic httpBasic) { /** * Inner-class with certificate authentication credentials. */ - public static class Certificate { + public static class Certificate implements Serializable { + + private static final long serialVersionUID = -3123397103510377094L; protected boolean enabled; protected boolean useCustomKeyStore; @@ -155,7 +157,9 @@ public void setTrustStorePassword(String trustStorePassword) { /** * Inner-class with Basic HTTP authentication credentials. */ - public static class HttpBasic { + public static class HttpBasic implements Serializable { + + private static final long serialVersionUID = 4449327538548490513L; protected boolean enabled; protected String username; From bc5d12fce7a1062865871420fbdff17e4565c035 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Fri, 17 Jun 2022 09:53:02 +0200 Subject: [PATCH 03/58] Bump version to 1.3.1 --- pom.xml | 2 +- powerauth-admin/pom.xml | 6 +++--- powerauth-client-model/pom.xml | 4 ++-- powerauth-java-server/pom.xml | 6 +++--- powerauth-rest-client-spring/pom.xml | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 9af4d42f3..7d650d897 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ io.getlime.security powerauth-server-parent - 1.3.0 + 1.3.1 pom diff --git a/powerauth-admin/pom.xml b/powerauth-admin/pom.xml index a4ea382ef..8025dda01 100644 --- a/powerauth-admin/pom.xml +++ b/powerauth-admin/pom.xml @@ -6,13 +6,13 @@ powerauth-admin PowerAuth Server Admin Console powerauth-admin - 1.3.0 + 1.3.1 war io.getlime.security powerauth-server-parent - 1.3.0 + 1.3.1 ../pom.xml @@ -56,7 +56,7 @@ io.getlime.security powerauth-rest-client-spring - 1.3.0 + 1.3.1 diff --git a/powerauth-client-model/pom.xml b/powerauth-client-model/pom.xml index 3b17cc303..96aa68da4 100644 --- a/powerauth-client-model/pom.xml +++ b/powerauth-client-model/pom.xml @@ -22,14 +22,14 @@ 4.0.0 powerauth-client-model - 1.3.0 + 1.3.1 powerauth-client-model PowerAuth Server Client Model io.getlime.security powerauth-server-parent - 1.3.0 + 1.3.1 ../pom.xml diff --git a/powerauth-java-server/pom.xml b/powerauth-java-server/pom.xml index 15f1f6514..a06dee229 100644 --- a/powerauth-java-server/pom.xml +++ b/powerauth-java-server/pom.xml @@ -24,13 +24,13 @@ powerauth-java-server PowerAuth Server powerauth-java-server - 1.3.0 + 1.3.1 war io.getlime.security powerauth-server-parent - 1.3.0 + 1.3.1 ../pom.xml @@ -112,7 +112,7 @@ io.getlime.security powerauth-client-model - 1.3.0 + 1.3.1 io.getlime.security diff --git a/powerauth-rest-client-spring/pom.xml b/powerauth-rest-client-spring/pom.xml index 6c5c2aef1..b21f9d202 100644 --- a/powerauth-rest-client-spring/pom.xml +++ b/powerauth-rest-client-spring/pom.xml @@ -22,14 +22,14 @@ 4.0.0 powerauth-rest-client-spring - 1.3.0 + 1.3.1 powerauth-rest-client-spring PowerAuth Server REST Service Client io.getlime.security powerauth-server-parent - 1.3.0 + 1.3.1 ../pom.xml @@ -38,7 +38,7 @@ io.getlime.security powerauth-client-model - 1.3.0 + 1.3.1 io.getlime.core From a9d1f20c561f4ccf2809833232596cd1e8f945d1 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 20 Jun 2022 17:32:09 +0200 Subject: [PATCH 04/58] Fix #711: Add information about database dialect configuration into migration guide --- docs/powerauth-server/PowerAuth-Server-1.3.0.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/powerauth-server/PowerAuth-Server-1.3.0.md b/docs/powerauth-server/PowerAuth-Server-1.3.0.md index e3deda44b..91f8d4783 100644 --- a/docs/powerauth-server/PowerAuth-Server-1.3.0.md +++ b/docs/powerauth-server/PowerAuth-Server-1.3.0.md @@ -260,3 +260,18 @@ We consider the 5-minute interval to still be safe, since the relatively high ac ``` powerauth.service.crypto.activationValidityInMilliseconds=120000 ``` + +## Database Dialect Configuration + +The latest release of PowerAuth requires configuration of database dialect. + +The dialect is specified using following configuration property: +```properties +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +``` + +Use the most specific dialect, if possible, such as: +- `org.hibernate.dialect.Oracle12cDialect` for Oracle 12c or higher +- `org.hibernate.dialect.PostgreSQL95Dialect` for PostgreSQL 9.5 or higher + +You can find additional database dialects in Hibernate documentation. From 2520fc0bc8d9ab152d6f7ca247b4e6821db3be16 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Tue, 21 Jun 2022 08:12:09 +0200 Subject: [PATCH 05/58] Use non-deprecated dialect value in example --- docs/powerauth-server/PowerAuth-Server-1.3.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/powerauth-server/PowerAuth-Server-1.3.0.md b/docs/powerauth-server/PowerAuth-Server-1.3.0.md index 91f8d4783..1eff1b298 100644 --- a/docs/powerauth-server/PowerAuth-Server-1.3.0.md +++ b/docs/powerauth-server/PowerAuth-Server-1.3.0.md @@ -267,7 +267,7 @@ The latest release of PowerAuth requires configuration of database dialect. The dialect is specified using following configuration property: ```properties -spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL95Dialect ``` Use the most specific dialect, if possible, such as: From 705c7e770d028732dc487b6c8c5a1f3356fb4bbe Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 20 Jun 2022 17:32:09 +0200 Subject: [PATCH 06/58] Fix #711: Add information about database dialect configuration into migration guide --- docs/powerauth-server/PowerAuth-Server-1.3.0.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/powerauth-server/PowerAuth-Server-1.3.0.md b/docs/powerauth-server/PowerAuth-Server-1.3.0.md index e3deda44b..91f8d4783 100644 --- a/docs/powerauth-server/PowerAuth-Server-1.3.0.md +++ b/docs/powerauth-server/PowerAuth-Server-1.3.0.md @@ -260,3 +260,18 @@ We consider the 5-minute interval to still be safe, since the relatively high ac ``` powerauth.service.crypto.activationValidityInMilliseconds=120000 ``` + +## Database Dialect Configuration + +The latest release of PowerAuth requires configuration of database dialect. + +The dialect is specified using following configuration property: +```properties +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +``` + +Use the most specific dialect, if possible, such as: +- `org.hibernate.dialect.Oracle12cDialect` for Oracle 12c or higher +- `org.hibernate.dialect.PostgreSQL95Dialect` for PostgreSQL 9.5 or higher + +You can find additional database dialects in Hibernate documentation. From 1a1d05229728e8ff9dfdb2aab4a97cb72b738932 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Tue, 21 Jun 2022 08:12:09 +0200 Subject: [PATCH 07/58] Use non-deprecated dialect value in example --- docs/powerauth-server/PowerAuth-Server-1.3.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/powerauth-server/PowerAuth-Server-1.3.0.md b/docs/powerauth-server/PowerAuth-Server-1.3.0.md index 91f8d4783..1eff1b298 100644 --- a/docs/powerauth-server/PowerAuth-Server-1.3.0.md +++ b/docs/powerauth-server/PowerAuth-Server-1.3.0.md @@ -267,7 +267,7 @@ The latest release of PowerAuth requires configuration of database dialect. The dialect is specified using following configuration property: ```properties -spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL95Dialect ``` Use the most specific dialect, if possible, such as: From 411a59b665357a6cc8473f7b071455063eeec317 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Wed, 22 Jun 2022 17:40:42 +0200 Subject: [PATCH 08/58] Fix documentation structure --- .../Activation-Recovery.md | 0 .../Admin-Deploying-Wildfly.md | 0 ...es.md => Configuration-Properties-Admin.md} | 0 .../Configuration-Properties.md | 0 .../Configuring-REST-Client-for-Spring.md | 0 docs/{powerauth-server => }/Database-Sizing.md | 0 .../Database-Structure.md | 0 .../Deploying-PowerAuth-Admin.md | 15 +++++++++++---- .../Deploying-PowerAuth-Server.md | 0 .../Deploying-Wildfly.md | 0 .../Encrypting-Records-in-Database.md | 0 .../Installing-Bouncy-Castle.md | 0 .../Migration-Instructions.md | 0 .../Offline-Signatures.md | 0 .../PowerAuth-Server-0.18.0.md | 0 .../PowerAuth-Server-0.19.0.md | 0 .../PowerAuth-Server-0.21.0.md | 0 .../PowerAuth-Server-0.22.0.md | 0 .../PowerAuth-Server-0.23.0.md | 0 .../PowerAuth-Server-0.24.0.md | 0 .../PowerAuth-Server-1.0.0.md | 0 .../PowerAuth-Server-1.1.0.md | 0 .../PowerAuth-Server-1.2.0.md | 0 .../PowerAuth-Server-1.2.5.md | 0 .../PowerAuth-Server-1.3.0.md | 0 docs/{powerauth-server => }/Readme.md | 0 .../Server-Error-Codes.md | 0 .../Setting-Up-LDAP-Authentication.md | 0 .../System-Requirements.md | 0 .../Using-HashiCorp-Vault.md | 0 .../WebServices-Client.md | 0 .../WebServices-Method-Compatibility.md | 0 .../WebServices-Methods.md | 0 docs/{powerauth-server => }/_Footer.md | 0 docs/{powerauth-server => }/_Sidebar.md | 10 +++++++++- .../images/arch_db_structure.png | Bin docs/powerauth-admin/Readme.md | 17 ----------------- docs/powerauth-admin/_Sidebar.md | 11 ----------- .../sql/mysql/create_schema.sql | 0 .../sql/mysql/delete_schema.sql | 0 .../sql/mysql/schema_boot.sql | 0 .../sql/oracle/create_schema.sql | 0 .../sql/oracle/delete_schema.sql | 0 .../sql/postgresql/create_schema.sql | 0 .../sql/postgresql/delete_schema.sql | 0 docs/{powerauth-server => }/util/check-bc.jar | Bin 46 files changed, 20 insertions(+), 33 deletions(-) rename docs/{powerauth-admin => }/Activation-Recovery.md (100%) rename docs/{powerauth-admin => }/Admin-Deploying-Wildfly.md (100%) rename docs/{powerauth-admin/Configuration-Properties.md => Configuration-Properties-Admin.md} (100%) rename docs/{powerauth-server => }/Configuration-Properties.md (100%) rename docs/{powerauth-server => }/Configuring-REST-Client-for-Spring.md (100%) rename docs/{powerauth-server => }/Database-Sizing.md (100%) rename docs/{powerauth-server => }/Database-Structure.md (100%) rename docs/{powerauth-admin => }/Deploying-PowerAuth-Admin.md (75%) rename docs/{powerauth-server => }/Deploying-PowerAuth-Server.md (100%) rename docs/{powerauth-server => }/Deploying-Wildfly.md (100%) rename docs/{powerauth-server => }/Encrypting-Records-in-Database.md (100%) rename docs/{powerauth-server => }/Installing-Bouncy-Castle.md (100%) rename docs/{powerauth-server => }/Migration-Instructions.md (100%) rename docs/{powerauth-server => }/Offline-Signatures.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-0.18.0.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-0.19.0.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-0.21.0.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-0.22.0.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-0.23.0.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-0.24.0.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-1.0.0.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-1.1.0.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-1.2.0.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-1.2.5.md (100%) rename docs/{powerauth-server => }/PowerAuth-Server-1.3.0.md (100%) rename docs/{powerauth-server => }/Readme.md (100%) rename docs/{powerauth-server => }/Server-Error-Codes.md (100%) rename docs/{powerauth-admin => }/Setting-Up-LDAP-Authentication.md (100%) rename docs/{powerauth-server => }/System-Requirements.md (100%) rename docs/{powerauth-server => }/Using-HashiCorp-Vault.md (100%) rename docs/{powerauth-server => }/WebServices-Client.md (100%) rename docs/{powerauth-server => }/WebServices-Method-Compatibility.md (100%) rename docs/{powerauth-server => }/WebServices-Methods.md (100%) rename docs/{powerauth-server => }/_Footer.md (100%) rename docs/{powerauth-server => }/_Sidebar.md (73%) rename docs/{powerauth-server => }/images/arch_db_structure.png (100%) delete mode 100644 docs/powerauth-admin/Readme.md delete mode 100644 docs/powerauth-admin/_Sidebar.md rename docs/{powerauth-server => }/sql/mysql/create_schema.sql (100%) rename docs/{powerauth-server => }/sql/mysql/delete_schema.sql (100%) rename docs/{powerauth-server => }/sql/mysql/schema_boot.sql (100%) rename docs/{powerauth-server => }/sql/oracle/create_schema.sql (100%) rename docs/{powerauth-server => }/sql/oracle/delete_schema.sql (100%) rename docs/{powerauth-server => }/sql/postgresql/create_schema.sql (100%) rename docs/{powerauth-server => }/sql/postgresql/delete_schema.sql (100%) rename docs/{powerauth-server => }/util/check-bc.jar (100%) diff --git a/docs/powerauth-admin/Activation-Recovery.md b/docs/Activation-Recovery.md similarity index 100% rename from docs/powerauth-admin/Activation-Recovery.md rename to docs/Activation-Recovery.md diff --git a/docs/powerauth-admin/Admin-Deploying-Wildfly.md b/docs/Admin-Deploying-Wildfly.md similarity index 100% rename from docs/powerauth-admin/Admin-Deploying-Wildfly.md rename to docs/Admin-Deploying-Wildfly.md diff --git a/docs/powerauth-admin/Configuration-Properties.md b/docs/Configuration-Properties-Admin.md similarity index 100% rename from docs/powerauth-admin/Configuration-Properties.md rename to docs/Configuration-Properties-Admin.md diff --git a/docs/powerauth-server/Configuration-Properties.md b/docs/Configuration-Properties.md similarity index 100% rename from docs/powerauth-server/Configuration-Properties.md rename to docs/Configuration-Properties.md diff --git a/docs/powerauth-server/Configuring-REST-Client-for-Spring.md b/docs/Configuring-REST-Client-for-Spring.md similarity index 100% rename from docs/powerauth-server/Configuring-REST-Client-for-Spring.md rename to docs/Configuring-REST-Client-for-Spring.md diff --git a/docs/powerauth-server/Database-Sizing.md b/docs/Database-Sizing.md similarity index 100% rename from docs/powerauth-server/Database-Sizing.md rename to docs/Database-Sizing.md diff --git a/docs/powerauth-server/Database-Structure.md b/docs/Database-Structure.md similarity index 100% rename from docs/powerauth-server/Database-Structure.md rename to docs/Database-Structure.md diff --git a/docs/powerauth-admin/Deploying-PowerAuth-Admin.md b/docs/Deploying-PowerAuth-Admin.md similarity index 75% rename from docs/powerauth-admin/Deploying-PowerAuth-Admin.md rename to docs/Deploying-PowerAuth-Admin.md index a36d0968d..3603acf39 100644 --- a/docs/powerauth-admin/Deploying-PowerAuth-Admin.md +++ b/docs/Deploying-PowerAuth-Admin.md @@ -2,9 +2,12 @@ This chapter explains how to deploy PowerAuth Admin. -PowerAuth Admin is a Java EE application (packaged as an executable WAR file) that you can use to work with the PowerAuth Server services in a easy to use visual way. Also, PowerAuth Admin project may serve as a simple example application for the Internet banking integrators, since in essence, it performs the very same tasks. +PowerAuth Admin is a web administration console for the [PowerAuth Server](https://github.com/wultra/powerauth-server). +It allows an easy application setup, an activation management and integration configurations. -*__Important note: Since PowerAuth Admin is a very simple application with direct access to the PowerAuth Server REST services, it must not be under any circumstances published publicly and must be constrained to the in-house closed infrastructure.__* + +Important note: Since PowerAuth Admin is a very simple application with direct access to the PowerAuth Server REST services, it must not be under any circumstances published publicly and must be constrained to the in-house closed infrastructure. + ## Downloading PowerAuth Admin @@ -29,7 +32,9 @@ powerauth.service.security.clientSecret= The credentials are stored in the `pa_integration` table. -_Note: The RESTful interface is secured using Basic HTTP Authentication (pre-emptive)._ + +Note: The RESTful interface is secured using Basic HTTP Authentication (pre-emptive). + ## Disabling SSL Validation During Development @@ -55,7 +60,9 @@ To deploy PowerAuth Admin to Apache Tomcat, simply copy the WAR file in your `we Running PowerAuth Admin application from console using the `java -jar` command is not supported. -*__Important note: Since PowerAuth Admin is a very simple application with direct access to the PowerAuth Server REST services, it must not be under any circumstances published publicly and must be constrained to the in-house closed infrastructure.__* + +Important note: Since PowerAuth Admin is a very simple application with direct access to the PowerAuth Server REST services, it must not be under any circumstances published publicly and must be constrained to the in-house closed infrastructure. + ## Deploying PowerAuth Admin On JBoss / Wildfly diff --git a/docs/powerauth-server/Deploying-PowerAuth-Server.md b/docs/Deploying-PowerAuth-Server.md similarity index 100% rename from docs/powerauth-server/Deploying-PowerAuth-Server.md rename to docs/Deploying-PowerAuth-Server.md diff --git a/docs/powerauth-server/Deploying-Wildfly.md b/docs/Deploying-Wildfly.md similarity index 100% rename from docs/powerauth-server/Deploying-Wildfly.md rename to docs/Deploying-Wildfly.md diff --git a/docs/powerauth-server/Encrypting-Records-in-Database.md b/docs/Encrypting-Records-in-Database.md similarity index 100% rename from docs/powerauth-server/Encrypting-Records-in-Database.md rename to docs/Encrypting-Records-in-Database.md diff --git a/docs/powerauth-server/Installing-Bouncy-Castle.md b/docs/Installing-Bouncy-Castle.md similarity index 100% rename from docs/powerauth-server/Installing-Bouncy-Castle.md rename to docs/Installing-Bouncy-Castle.md diff --git a/docs/powerauth-server/Migration-Instructions.md b/docs/Migration-Instructions.md similarity index 100% rename from docs/powerauth-server/Migration-Instructions.md rename to docs/Migration-Instructions.md diff --git a/docs/powerauth-server/Offline-Signatures.md b/docs/Offline-Signatures.md similarity index 100% rename from docs/powerauth-server/Offline-Signatures.md rename to docs/Offline-Signatures.md diff --git a/docs/powerauth-server/PowerAuth-Server-0.18.0.md b/docs/PowerAuth-Server-0.18.0.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-0.18.0.md rename to docs/PowerAuth-Server-0.18.0.md diff --git a/docs/powerauth-server/PowerAuth-Server-0.19.0.md b/docs/PowerAuth-Server-0.19.0.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-0.19.0.md rename to docs/PowerAuth-Server-0.19.0.md diff --git a/docs/powerauth-server/PowerAuth-Server-0.21.0.md b/docs/PowerAuth-Server-0.21.0.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-0.21.0.md rename to docs/PowerAuth-Server-0.21.0.md diff --git a/docs/powerauth-server/PowerAuth-Server-0.22.0.md b/docs/PowerAuth-Server-0.22.0.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-0.22.0.md rename to docs/PowerAuth-Server-0.22.0.md diff --git a/docs/powerauth-server/PowerAuth-Server-0.23.0.md b/docs/PowerAuth-Server-0.23.0.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-0.23.0.md rename to docs/PowerAuth-Server-0.23.0.md diff --git a/docs/powerauth-server/PowerAuth-Server-0.24.0.md b/docs/PowerAuth-Server-0.24.0.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-0.24.0.md rename to docs/PowerAuth-Server-0.24.0.md diff --git a/docs/powerauth-server/PowerAuth-Server-1.0.0.md b/docs/PowerAuth-Server-1.0.0.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-1.0.0.md rename to docs/PowerAuth-Server-1.0.0.md diff --git a/docs/powerauth-server/PowerAuth-Server-1.1.0.md b/docs/PowerAuth-Server-1.1.0.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-1.1.0.md rename to docs/PowerAuth-Server-1.1.0.md diff --git a/docs/powerauth-server/PowerAuth-Server-1.2.0.md b/docs/PowerAuth-Server-1.2.0.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-1.2.0.md rename to docs/PowerAuth-Server-1.2.0.md diff --git a/docs/powerauth-server/PowerAuth-Server-1.2.5.md b/docs/PowerAuth-Server-1.2.5.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-1.2.5.md rename to docs/PowerAuth-Server-1.2.5.md diff --git a/docs/powerauth-server/PowerAuth-Server-1.3.0.md b/docs/PowerAuth-Server-1.3.0.md similarity index 100% rename from docs/powerauth-server/PowerAuth-Server-1.3.0.md rename to docs/PowerAuth-Server-1.3.0.md diff --git a/docs/powerauth-server/Readme.md b/docs/Readme.md similarity index 100% rename from docs/powerauth-server/Readme.md rename to docs/Readme.md diff --git a/docs/powerauth-server/Server-Error-Codes.md b/docs/Server-Error-Codes.md similarity index 100% rename from docs/powerauth-server/Server-Error-Codes.md rename to docs/Server-Error-Codes.md diff --git a/docs/powerauth-admin/Setting-Up-LDAP-Authentication.md b/docs/Setting-Up-LDAP-Authentication.md similarity index 100% rename from docs/powerauth-admin/Setting-Up-LDAP-Authentication.md rename to docs/Setting-Up-LDAP-Authentication.md diff --git a/docs/powerauth-server/System-Requirements.md b/docs/System-Requirements.md similarity index 100% rename from docs/powerauth-server/System-Requirements.md rename to docs/System-Requirements.md diff --git a/docs/powerauth-server/Using-HashiCorp-Vault.md b/docs/Using-HashiCorp-Vault.md similarity index 100% rename from docs/powerauth-server/Using-HashiCorp-Vault.md rename to docs/Using-HashiCorp-Vault.md diff --git a/docs/powerauth-server/WebServices-Client.md b/docs/WebServices-Client.md similarity index 100% rename from docs/powerauth-server/WebServices-Client.md rename to docs/WebServices-Client.md diff --git a/docs/powerauth-server/WebServices-Method-Compatibility.md b/docs/WebServices-Method-Compatibility.md similarity index 100% rename from docs/powerauth-server/WebServices-Method-Compatibility.md rename to docs/WebServices-Method-Compatibility.md diff --git a/docs/powerauth-server/WebServices-Methods.md b/docs/WebServices-Methods.md similarity index 100% rename from docs/powerauth-server/WebServices-Methods.md rename to docs/WebServices-Methods.md diff --git a/docs/powerauth-server/_Footer.md b/docs/_Footer.md similarity index 100% rename from docs/powerauth-server/_Footer.md rename to docs/_Footer.md diff --git a/docs/powerauth-server/_Sidebar.md b/docs/_Sidebar.md similarity index 73% rename from docs/powerauth-server/_Sidebar.md rename to docs/_Sidebar.md index 1320a5db2..8ccca8d79 100644 --- a/docs/powerauth-server/_Sidebar.md +++ b/docs/_Sidebar.md @@ -21,9 +21,17 @@ - [Database Structure](./Database-Structure.md) - [Error Codes](./Server-Error-Codes.md) +**PowerAuth Admin** + +- [Deploying PowerAuth Admin](./Deploying-PowerAuth-Admin.md) +- [Deploying PowerAuth Admin on JBoss/Wildfly](./Admin-Deploying-Wildfly.md) +- [Setting Up LDAP Authentication](./Setting-Up-LDAP-Authentication.md) +- [Configuration of Activation Recovery](./Activation-Recovery.md) +- [Configuration Properties](./Configuration-Properties-Admin.md) + **Advanced Topics** - [Encrypting DB Records](./Encrypting-Records-in-Database.md) - [Offline Signatures](./Offline-Signatures.md) - [Integrating with HashiCorp Vault](./Using-HashiCorp-Vault.md) -- [Database Sizing](./Database-Sizing.md) \ No newline at end of file +- [Database Sizing](./Database-Sizing.md) diff --git a/docs/powerauth-server/images/arch_db_structure.png b/docs/images/arch_db_structure.png similarity index 100% rename from docs/powerauth-server/images/arch_db_structure.png rename to docs/images/arch_db_structure.png diff --git a/docs/powerauth-admin/Readme.md b/docs/powerauth-admin/Readme.md deleted file mode 100644 index d58f4b51e..000000000 --- a/docs/powerauth-admin/Readme.md +++ /dev/null @@ -1,17 +0,0 @@ -# PowerAuth Admin Documentation - -PowerAuth Admin is a web administration console for the [PowerAuth Server](https://github.com/wultra/powerauth-server). -It allows an easy application setup, an activation management and integration configurations. - - -## Deployment Tutorials - -- [Deploying PowerAuth Admin](./Deploying-PowerAuth-Admin.md) -- [Setting Up LDAP Authentication](./Setting-Up-LDAP-Authentication.md) -- [Deploying PowerAuth Admin on JBoss/Wildfly](./Admin-Deploying-Wildfly.md) -- [Configuration of Activation Recovery](./Activation-Recovery.md) - - -## License - -All sources are licensed using Apache 2.0 license, you can use them with no restriction. If you are using PowerAuth, please let us know. We will be happy to share and promote your project. diff --git a/docs/powerauth-admin/_Sidebar.md b/docs/powerauth-admin/_Sidebar.md deleted file mode 100644 index ff7623144..000000000 --- a/docs/powerauth-admin/_Sidebar.md +++ /dev/null @@ -1,11 +0,0 @@ -**Deployment Tutorials** - -- [Deploying PowerAuth Admin](./Deploying-PowerAuth-Admin.md) -- [Deploying PowerAuth Admin on JBoss/Wildfly](./Admin-Deploying-Wildfly.md) -- [Setting Up LDAP Authentication](./Setting-Up-LDAP-Authentication.md) -- [Configuration of Activation Recovery](./Activation-Recovery.md) -- [Configuration Properties](./Configuration-Properties.md) - -**Implementation Tutorials** - -- [Authentication in Mobile Banking Apps (SCA)](https://developers.wultra.com/products/mobile-security-suite/develop/tutorials/Authentication-in-Mobile-Apps) diff --git a/docs/powerauth-server/sql/mysql/create_schema.sql b/docs/sql/mysql/create_schema.sql similarity index 100% rename from docs/powerauth-server/sql/mysql/create_schema.sql rename to docs/sql/mysql/create_schema.sql diff --git a/docs/powerauth-server/sql/mysql/delete_schema.sql b/docs/sql/mysql/delete_schema.sql similarity index 100% rename from docs/powerauth-server/sql/mysql/delete_schema.sql rename to docs/sql/mysql/delete_schema.sql diff --git a/docs/powerauth-server/sql/mysql/schema_boot.sql b/docs/sql/mysql/schema_boot.sql similarity index 100% rename from docs/powerauth-server/sql/mysql/schema_boot.sql rename to docs/sql/mysql/schema_boot.sql diff --git a/docs/powerauth-server/sql/oracle/create_schema.sql b/docs/sql/oracle/create_schema.sql similarity index 100% rename from docs/powerauth-server/sql/oracle/create_schema.sql rename to docs/sql/oracle/create_schema.sql diff --git a/docs/powerauth-server/sql/oracle/delete_schema.sql b/docs/sql/oracle/delete_schema.sql similarity index 100% rename from docs/powerauth-server/sql/oracle/delete_schema.sql rename to docs/sql/oracle/delete_schema.sql diff --git a/docs/powerauth-server/sql/postgresql/create_schema.sql b/docs/sql/postgresql/create_schema.sql similarity index 100% rename from docs/powerauth-server/sql/postgresql/create_schema.sql rename to docs/sql/postgresql/create_schema.sql diff --git a/docs/powerauth-server/sql/postgresql/delete_schema.sql b/docs/sql/postgresql/delete_schema.sql similarity index 100% rename from docs/powerauth-server/sql/postgresql/delete_schema.sql rename to docs/sql/postgresql/delete_schema.sql diff --git a/docs/powerauth-server/util/check-bc.jar b/docs/util/check-bc.jar similarity index 100% rename from docs/powerauth-server/util/check-bc.jar rename to docs/util/check-bc.jar From bd690b5858fa6e30d921822e941bbcb4f02646fe Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Thu, 23 Jun 2022 18:21:25 +0200 Subject: [PATCH 09/58] Fix #742: Update version --- pom.xml | 4 ++-- powerauth-admin/pom.xml | 6 +++--- powerauth-client-model/pom.xml | 4 ++-- powerauth-java-server/pom.xml | 6 +++--- powerauth-rest-client-spring/pom.xml | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 7d650d897..a578c6452 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ io.getlime.security powerauth-server-parent - 1.3.1 + 1.4.0-SNAPSHOT pom @@ -94,7 +94,7 @@ 3.1.1 - 1.3.0 + 1.4.0-SNAPSHOT 1.5.2 1.5.2 1.70 diff --git a/powerauth-admin/pom.xml b/powerauth-admin/pom.xml index 8025dda01..dada86fb3 100644 --- a/powerauth-admin/pom.xml +++ b/powerauth-admin/pom.xml @@ -6,13 +6,13 @@ powerauth-admin PowerAuth Server Admin Console powerauth-admin - 1.3.1 + 1.4.0-SNAPSHOT war io.getlime.security powerauth-server-parent - 1.3.1 + 1.4.0-SNAPSHOT ../pom.xml @@ -56,7 +56,7 @@ io.getlime.security powerauth-rest-client-spring - 1.3.1 + 1.4.0-SNAPSHOT diff --git a/powerauth-client-model/pom.xml b/powerauth-client-model/pom.xml index 96aa68da4..b79ad87da 100644 --- a/powerauth-client-model/pom.xml +++ b/powerauth-client-model/pom.xml @@ -22,14 +22,14 @@ 4.0.0 powerauth-client-model - 1.3.1 + 1.4.0-SNAPSHOT powerauth-client-model PowerAuth Server Client Model io.getlime.security powerauth-server-parent - 1.3.1 + 1.4.0-SNAPSHOT ../pom.xml diff --git a/powerauth-java-server/pom.xml b/powerauth-java-server/pom.xml index a06dee229..8218722f2 100644 --- a/powerauth-java-server/pom.xml +++ b/powerauth-java-server/pom.xml @@ -24,13 +24,13 @@ powerauth-java-server PowerAuth Server powerauth-java-server - 1.3.1 + 1.4.0-SNAPSHOT war io.getlime.security powerauth-server-parent - 1.3.1 + 1.4.0-SNAPSHOT ../pom.xml @@ -112,7 +112,7 @@ io.getlime.security powerauth-client-model - 1.3.1 + 1.4.0-SNAPSHOT io.getlime.security diff --git a/powerauth-rest-client-spring/pom.xml b/powerauth-rest-client-spring/pom.xml index b21f9d202..dd13e3845 100644 --- a/powerauth-rest-client-spring/pom.xml +++ b/powerauth-rest-client-spring/pom.xml @@ -22,14 +22,14 @@ 4.0.0 powerauth-rest-client-spring - 1.3.1 + 1.4.0-SNAPSHOT powerauth-rest-client-spring PowerAuth Server REST Service Client io.getlime.security powerauth-server-parent - 1.3.1 + 1.4.0-SNAPSHOT ../pom.xml @@ -38,7 +38,7 @@ io.getlime.security powerauth-client-model - 1.3.1 + 1.4.0-SNAPSHOT io.getlime.core From a70e114391bf7a1710c36f47137030787bac757c Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 27 Jun 2022 16:55:45 +0200 Subject: [PATCH 10/58] Fix #745: Add auditing DB tables into DDL --- docs/sql/mysql/create_schema.sql | 41 ++++++++++++ docs/sql/oracle/create_schema.sql | 41 ++++++++++++ docs/sql/postgresql/create_schema.sql | 95 +++++++++++++++++++-------- 3 files changed, 150 insertions(+), 27 deletions(-) diff --git a/docs/sql/mysql/create_schema.sql b/docs/sql/mysql/create_schema.sql index 86679e8dd..0c36e03a8 100644 --- a/docs/sql/mysql/create_schema.sql +++ b/docs/sql/mysql/create_schema.sql @@ -265,6 +265,35 @@ CREATE TABLE shedlock ( PRIMARY KEY (name) ) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +-- +-- Create audit log table. +-- +CREATE TABLE audit_log ( + audit_log_id VARCHAR(36) PRIMARY KEY, + application_name VARCHAR(256) NOT NULL, + audit_level VARCHAR(32) NOT NULL, + audit_type VARCHAR(256), + timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + message TEXT NOT NULL, + exception_message TEXT, + stack_trace TEXT, + param TEXT, + calling_class VARCHAR(256) NOT NULL, + thread_name VARCHAR(256) NOT NULL, + version VARCHAR(256), + build_time TIMESTAMP NULL +) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- +-- Create audit parameters table. +-- +CREATE TABLE audit_param ( + audit_log_id VARCHAR(36), + timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + param_key VARCHAR(256), + param_value VARCHAR(3072) +) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + -- -- Indexes for better performance. InnoDB engine creates indexes on foreign keys automatically, so they are not included. -- @@ -298,3 +327,15 @@ CREATE INDEX `pa_operation_template_name_idx` ON `pa_operation_template` (`templ CREATE UNIQUE INDEX `pa_recovery_code_puk` ON `pa_recovery_puk`(`recovery_code_id`, `puk_index`); CREATE UNIQUE INDEX `pa_application_name` ON `pa_application`(`name`); + +-- +-- Auditing indexes. +-- +CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); +CREATE INDEX audit_log_application ON audit_log (application_name); +CREATE INDEX audit_log_level ON audit_log (audit_level); +CREATE INDEX audit_log_type ON audit_log (audit_type); +CREATE INDEX audit_param_log ON audit_param (audit_log_id); +CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); +CREATE INDEX audit_param_key ON audit_param (param_key); +CREATE FULLTEXT INDEX audit_param_value ON audit_param (param_value); \ No newline at end of file diff --git a/docs/sql/oracle/create_schema.sql b/docs/sql/oracle/create_schema.sql index 3a1fcb2e9..1f2aea6c4 100755 --- a/docs/sql/oracle/create_schema.sql +++ b/docs/sql/oracle/create_schema.sql @@ -257,6 +257,35 @@ CREATE TABLE shedlock ( locked_by VARCHAR(255) NOT NULL ); +-- +-- Create audit log table. +-- +CREATE TABLE audit_log ( + audit_log_id VARCHAR2(36 CHAR) PRIMARY KEY, + application_name VARCHAR2(256 CHAR) NOT NULL, + audit_level VARCHAR2(32 CHAR) NOT NULL, + audit_type VARCHAR2(256 CHAR), + timestamp_created TIMESTAMP, + message CLOB NOT NULL, + exception_message CLOB, + stack_trace CLOB, + param CLOB, + calling_class VARCHAR2(256 CHAR) NOT NULL, + thread_name VARCHAR2(256 CHAR) NOT NULL, + version VARCHAR2(256 CHAR), + build_time TIMESTAMP +); + +-- +-- Create audit parameters table. +-- +CREATE TABLE audit_param ( + audit_log_id VARCHAR2(36 CHAR), + timestamp_created TIMESTAMP, + param_key VARCHAR2(256 CHAR), + param_value VARCHAR2(4000 CHAR) +); + -- -- Ref Constraints for Table PA_ACTIVATION -- @@ -370,3 +399,15 @@ CREATE INDEX PA_OPERATION_TS_CREATED_IDX ON PA_OPERATION(TIMESTAMP_CREATED); CREATE INDEX PA_OPERATION_TS_EXPIRES_IDX ON PA_OPERATION(TIMESTAMP_EXPIRES); CREATE INDEX PA_OPERATION_TEMPLATE_NAME_IDX ON PA_OPERATION_TEMPLATE(TEMPLATE_NAME); + +-- +-- Auditing indexes. +-- +CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); +CREATE INDEX audit_log_application ON audit_log (application_name); +CREATE INDEX audit_log_level ON audit_log (audit_level); +CREATE INDEX audit_log_type ON audit_log (audit_type); +CREATE INDEX audit_param_log ON audit_param (audit_log_id); +CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); +CREATE INDEX audit_param_key ON audit_param (param_key); +CREATE INDEX audit_param_value ON audit_param (param_value); \ No newline at end of file diff --git a/docs/sql/postgresql/create_schema.sql b/docs/sql/postgresql/create_schema.sql index 724a7503c..e0ec88f86 100644 --- a/docs/sql/postgresql/create_schema.sql +++ b/docs/sql/postgresql/create_schema.sql @@ -258,6 +258,35 @@ CREATE TABLE shedlock ( locked_by VARCHAR(255) NOT NULL ); +-- +-- Create audit log table. +-- +CREATE TABLE IF NOT EXISTS audit_log ( + audit_log_id VARCHAR(36) PRIMARY KEY, + application_name VARCHAR(256) NOT NULL, + audit_level VARCHAR(32) NOT NULL, + audit_type VARCHAR(256), + timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + message TEXT NOT NULL, + exception_message TEXT, + stack_trace TEXT, + param TEXT, + calling_class VARCHAR(256) NOT NULL, + thread_name VARCHAR(256) NOT NULL, + version VARCHAR(256), + build_time TIMESTAMP +); + +-- +-- Create audit parameters table. +-- +CREATE TABLE IF NOT EXISTS audit_param ( + audit_log_id VARCHAR(36), + timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + param_key VARCHAR(256), + param_value VARCHAR(4000) +); + -- -- Ref Constraints for Table PA_ACTIVATION -- @@ -317,57 +346,69 @@ ALTER TABLE pa_operation ADD CONSTRAINT operation_application_fk FOREIGN KEY (ap --- ---- Indexes for better performance. PostgreSQL does not create indexes on foreign key automatically. +--- Indexes for better performance. PostgreSQL does not CREATE INDEXes ON foreign key automatically. --- -CREATE INDEX PA_ACTIVATION_APPLICATION ON PA_ACTIVATION(APPLICATION_ID); +CREATE INDEX pa_activation_application ON pa_activation(application_id); + +CREATE INDEX pa_activation_keypair ON pa_activation(master_keypair_id); -CREATE INDEX PA_ACTIVATION_KEYPAIR ON PA_ACTIVATION(MASTER_KEYPAIR_ID); +CREATE INDEX pa_activation_code ON pa_activation(activation_code); -CREATE INDEX PA_ACTIVATION_CODE ON PA_ACTIVATION(ACTIVATION_CODE); +CREATE INDEX pa_activation_user_id ON pa_activation(user_id); -CREATE INDEX PA_ACTIVATION_USER_ID ON PA_ACTIVATION(USER_ID); +CREATE INDEX pa_activation_history_act ON pa_activation_history(activation_id); -CREATE INDEX PA_ACTIVATION_HISTORY_ACT ON PA_ACTIVATION_HISTORY(ACTIVATION_ID); +CREATE INDEX pa_activation_history_created ON pa_activation_history(timestamp_created); -CREATE INDEX PA_ACTIVATION_HISTORY_CREATED ON PA_ACTIVATION_HISTORY(TIMESTAMP_CREATED); +CREATE INDEX pa_application_version_app ON pa_application_version(application_id); -CREATE INDEX PA_APPLICATION_VERSION_APP ON PA_APPLICATION_VERSION(APPLICATION_ID); +CREATE INDEX pa_master_keypair_application ON pa_master_keypair(application_id); -CREATE INDEX PA_MASTER_KEYPAIR_APPLICATION ON PA_MASTER_KEYPAIR(APPLICATION_ID); +CREATE UNIQUE INDEX pa_app_version_app_key ON pa_application_version(application_key); -CREATE UNIQUE INDEX PA_APP_VERSION_APP_KEY ON PA_APPLICATION_VERSION(APPLICATION_KEY); +CREATE INDEX pa_app_callback_app ON pa_application_callback(application_id); -CREATE INDEX PA_APP_CALLBACK_APP ON PA_APPLICATION_CALLBACK(APPLICATION_ID); +CREATE UNIQUE INDEX pa_integration_token ON pa_integration(client_token); -CREATE UNIQUE INDEX PA_INTEGRATION_TOKEN ON PA_INTEGRATION(CLIENT_TOKEN); +CREATE INDEX pa_signature_audit_activation ON pa_signature_audit(activation_id); -CREATE INDEX PA_SIGNATURE_AUDIT_ACTIVATION ON PA_SIGNATURE_AUDIT(ACTIVATION_ID); +CREATE INDEX pa_signature_audit_created ON pa_signature_audit(timestamp_created); -CREATE INDEX PA_SIGNATURE_AUDIT_CREATED ON PA_SIGNATURE_AUDIT(TIMESTAMP_CREATED); +CREATE INDEX pa_token_activation ON pa_token(activation_id); -CREATE INDEX PA_TOKEN_ACTIVATION ON PA_TOKEN(ACTIVATION_ID); +CREATE INDEX pa_recovery_code_code ON pa_recovery_code(recovery_code); -CREATE INDEX PA_RECOVERY_CODE_CODE ON PA_RECOVERY_CODE(RECOVERY_CODE); +CREATE INDEX pa_recovery_code_app ON pa_recovery_code(application_id); -CREATE INDEX PA_RECOVERY_CODE_APP ON PA_RECOVERY_CODE(APPLICATION_ID); +CREATE INDEX pa_recovery_code_user ON pa_recovery_code(user_id); -CREATE INDEX PA_RECOVERY_CODE_USER ON PA_RECOVERY_CODE(USER_ID); +CREATE INDEX pa_recovery_code_act ON pa_recovery_code(activation_id); -CREATE INDEX PA_RECOVERY_CODE_ACT ON PA_RECOVERY_CODE(ACTIVATION_ID); +CREATE UNIQUE INDEX pa_recovery_code_puk ON pa_recovery_puk(recovery_code_id, puk_index); -CREATE UNIQUE INDEX PA_RECOVERY_CODE_PUK ON PA_RECOVERY_PUK(RECOVERY_CODE_ID, PUK_INDEX); +CREATE INDEX pa_recovery_puk_code ON pa_recovery_puk(recovery_code_id); -CREATE INDEX PA_RECOVERY_PUK_CODE ON PA_RECOVERY_PUK(RECOVERY_CODE_ID); +CREATE UNIQUE INDEX pa_recovery_config_app ON pa_recovery_config(application_id); -CREATE UNIQUE INDEX PA_RECOVERY_CONFIG_APP ON PA_RECOVERY_CONFIG(APPLICATION_ID); +CREATE UNIQUE INDEX pa_application_name ON pa_application(name); -CREATE UNIQUE INDEX PA_APPLICATION_NAME ON PA_APPLICATION(NAME); +CREATE INDEX pa_operation_user ON pa_operation(user_id); -CREATE INDEX PA_OPERATION_USER ON PA_OPERATION(USER_ID); +CREATE INDEX pa_operation_ts_created_idx ON pa_operation(timestamp_created); -CREATE INDEX PA_OPERATION_TS_CREATED_IDX ON PA_OPERATION(TIMESTAMP_CREATED); +CREATE INDEX pa_operation_ts_expires_idx ON pa_operation(timestamp_expires); -CREATE INDEX PA_OPERATION_TS_EXPIRES_IDX ON PA_OPERATION(TIMESTAMP_EXPIRES); +CREATE INDEX pa_operation_template_name_idx ON pa_operation_template(template_name); -CREATE INDEX PA_OPERATION_TEMPLATE_NAME_IDX ON PA_OPERATION_TEMPLATE(TEMPLATE_NAME); +-- +-- Auditing indexes. +-- +CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); +CREATE INDEX audit_log_application ON audit_log (application_name); +CREATE INDEX audit_log_level ON audit_log (audit_level); +CREATE INDEX audit_log_type ON audit_log (audit_type); +CREATE INDEX audit_param_log ON audit_param (audit_log_id); +CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); +CREATE INDEX audit_param_key ON audit_param (param_key); +CREATE INDEX audit_param_value ON audit_param (param_value); From c5aec3102801d0896a5c697aaa65d994b49864fc Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 27 Jun 2022 16:58:18 +0200 Subject: [PATCH 11/58] Add missing IF NOT EXISTS --- docs/sql/mysql/create_schema.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sql/mysql/create_schema.sql b/docs/sql/mysql/create_schema.sql index 0c36e03a8..ed8dcb5e5 100644 --- a/docs/sql/mysql/create_schema.sql +++ b/docs/sql/mysql/create_schema.sql @@ -268,7 +268,7 @@ CREATE TABLE shedlock ( -- -- Create audit log table. -- -CREATE TABLE audit_log ( +CREATE TABLE IF NOT EXISTS audit_log ( audit_log_id VARCHAR(36) PRIMARY KEY, application_name VARCHAR(256) NOT NULL, audit_level VARCHAR(32) NOT NULL, @@ -287,7 +287,7 @@ CREATE TABLE audit_log ( -- -- Create audit parameters table. -- -CREATE TABLE audit_param ( +CREATE TABLE IF NOT EXISTS audit_param ( audit_log_id VARCHAR(36), timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, param_key VARCHAR(256), From 20fe91887df97cdeb3284d2d91888155fc02f4b6 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 27 Jun 2022 17:04:07 +0200 Subject: [PATCH 12/58] Fix #746: Remove obsolete constraint in DDL --- docs/sql/mysql/create_schema.sql | 3 +-- docs/sql/oracle/create_schema.sql | 5 ----- docs/sql/postgresql/create_schema.sql | 5 ----- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/docs/sql/mysql/create_schema.sql b/docs/sql/mysql/create_schema.sql index 86679e8dd..2887f3b4e 100644 --- a/docs/sql/mysql/create_schema.sql +++ b/docs/sql/mysql/create_schema.sql @@ -227,8 +227,7 @@ CREATE TABLE pa_operation ( timestamp_created datetime NOT NULL, timestamp_expires datetime NOT NULL, timestamp_finalized datetime NULL, - PRIMARY KEY (id), - CONSTRAINT `FK_OPERATION_APPLICATION` FOREIGN KEY (`application_id`) REFERENCES `pa_application` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION + PRIMARY KEY (id) ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- diff --git a/docs/sql/oracle/create_schema.sql b/docs/sql/oracle/create_schema.sql index 3a1fcb2e9..22b60a455 100755 --- a/docs/sql/oracle/create_schema.sql +++ b/docs/sql/oracle/create_schema.sql @@ -309,11 +309,6 @@ ALTER TABLE "PA_RECOVERY_PUK" ADD CONSTRAINT "RECOVERY_PUK_CODE_FK" FOREIGN KEY -- ALTER TABLE "PA_RECOVERY_CONFIG" ADD CONSTRAINT "RECOVERY_CONFIG_APP_FK" FOREIGN KEY ("APPLICATION_ID") REFERENCES "PA_APPLICATION" ("ID") ENABLE; --- --- Ref Constraints for Table PA_OPERATION --- -ALTER TABLE "PA_OPERATION" ADD CONSTRAINT "OPERATION_APPLICATION_FK" FOREIGN KEY ("APPLICATION_ID") REFERENCES "PA_APPLICATION" ("ID") ENABLE; - --- --- Indexes for better performance. Oracle does not create indexes on foreign key automatically. diff --git a/docs/sql/postgresql/create_schema.sql b/docs/sql/postgresql/create_schema.sql index 724a7503c..69c1287fb 100644 --- a/docs/sql/postgresql/create_schema.sql +++ b/docs/sql/postgresql/create_schema.sql @@ -310,11 +310,6 @@ ALTER TABLE pa_recovery_puk ADD CONSTRAINT recovery_puk_code_fk FOREIGN KEY (rec -- ALTER TABLE pa_recovery_config ADD CONSTRAINT recovery_config_app_fk FOREIGN KEY (application_id) REFERENCES pa_application (id); --- --- Ref Constraints for Table PA_OPERATION --- -ALTER TABLE pa_operation ADD CONSTRAINT operation_application_fk FOREIGN KEY (application_id) REFERENCES pa_application (id); - --- --- Indexes for better performance. PostgreSQL does not create indexes on foreign key automatically. From bc22dd4d8bea2a477f510412f7555efd995a2154 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Tue, 28 Jun 2022 00:56:26 +0200 Subject: [PATCH 13/58] Fix #744: Add scheduled activation cleanup --- .../PowerAuthServiceConfiguration.java | 25 +++++++++++++++++++ .../repository/ActivationRepository.java | 11 ++++++++ .../tasks/v3/ActivationServiceBehavior.java | 25 +++++++++++++++++++ .../src/main/resources/application.properties | 2 ++ 4 files changed, 63 insertions(+) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java index 96098c837..ee3bb4bb0 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java @@ -117,6 +117,13 @@ public class PowerAuthServiceConfiguration { @Min(0) private int activationValidityBeforeActive; + /** + * How many milliseconds should the activation cleanup job look to the past. + */ + @Value("${powerauth.service.scheduled.job.activationsCleanup.lookBackInMilliseconds}") + @Min(0) + private int activationsCleanupLookBackInMilliseconds; + /** * How many failed signatures cause activation record blocking. The maximum supported value is 64. */ @@ -400,6 +407,24 @@ public void setActivationValidityBeforeActive(int activationValidityBeforeActive this.activationValidityBeforeActive = activationValidityBeforeActive; } + /** + * Get look-back milliseconds for activation cleanup. + * @return How long the activation cleanup job should look back in time. + */ + public int getActivationsCleanupLookBackInMilliseconds() { + return activationsCleanupLookBackInMilliseconds; + } + + /** + * Set look-back milliseconds for activation cleanup. + * @param activationsCleanupLookBackInMilliseconds How long the activation cleanup job should look back in time. + */ + public void setActivationsCleanupLookBackInMilliseconds(int activationsCleanupLookBackInMilliseconds) { + this.activationsCleanupLookBackInMilliseconds = activationsCleanupLookBackInMilliseconds; + } + + + /** * Get the signature validation lookahead. * @return Signature validation lookahead. diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java index df7d2c67b..d1be0bf8b 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java @@ -28,6 +28,7 @@ import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.stream.Stream; /** * Database repository for activation entities. @@ -167,4 +168,14 @@ default Long getActivationCountByActivationCode(String applicationId, String act */ @Query("SELECT a FROM ActivationRecordEntity a WHERE a.userId IN :userIds AND ((:applicationIds) IS NULL OR a.application.id IN :applicationIds) AND a.timestampLastUsed < :timestampLastUsedBefore AND a.timestampLastUsed >= :timestampLastUsedAfter AND a.activationStatus IN :states") List lookupActivations(Collection userIds, Collection applicationIds, Date timestampLastUsedBefore, Date timestampLastUsedAfter, Collection states); + + /** + * Fetch all activations that are in a given state, were created after a specified timestamp, and are already expired according to provided current timestamp. + * @param states Activation states that are used for the lookup. + * @param startingTimestamp Timestamp of when the activation must have been created. + * @param currentTimestamp Current timestamp, to see expired operations. + * @return Stream of activations. + */ + @Query("SELECT a FROM ActivationRecordEntity a WHERE a.activationStatus IN :states AND a.timestampCreated >= :startingTimestamp AND a.timestampActivationExpire < :currentTimestamp") + Stream findAbandonedActivations(Collection states, Date startingTimestamp, Date currentTimestamp); } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index 1af02772b..da10cb938 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -56,10 +56,14 @@ import io.getlime.security.powerauth.crypto.lib.util.PasswordHash; import io.getlime.security.powerauth.crypto.server.activation.PowerAuthServerActivation; import io.getlime.security.powerauth.crypto.server.keyfactory.PowerAuthServerKeyFactory; +import net.javacrumbs.shedlock.core.LockAssert; +import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; import javax.crypto.SecretKey; import javax.validation.constraints.NotNull; @@ -75,6 +79,7 @@ import java.security.spec.InvalidKeySpecException; import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Behavior class implementing processes related with activations. Used to move the @@ -1957,4 +1962,24 @@ private ActivationRecovery createRecoveryCodeForActivation(ActivationRecordEntit } } + // Scheduled tasks + + @Scheduled(fixedRateString = "${powerauth.service.scheduled.job.activationsCleanup}") + @SchedulerLock(name = "expireActivationsTask") + @Transactional + public void expireOperations() { + LockAssert.assertLocked(); + final Date currentTimestamp = new Date(); + final Date lookBackTimestamp = new Date(currentTimestamp.getTime() - powerAuthServiceConfiguration.getActivationsCleanupLookBackInMilliseconds()); + logger.debug("Running scheduled task for expiring activations"); + final ActivationRepository activationRepository = repositoryCatalogue.getActivationRepository(); + final ImmutableSet activationStatuses = ImmutableSet.of(ActivationStatus.CREATED, ActivationStatus.PENDING_COMMIT); + try (final Stream abandonedActivations = activationRepository.findAbandonedActivations(activationStatuses, lookBackTimestamp, currentTimestamp)) { + abandonedActivations.forEach(activation -> { + logger.info("Removing abandoned activation with ID: {}, revoking recovery codes.", activation.getActivationId()); + removeActivation(activation, null, true); + }); + } + } + } diff --git a/powerauth-java-server/src/main/resources/application.properties b/powerauth-java-server/src/main/resources/application.properties index f5f16481f..974c11acf 100644 --- a/powerauth-java-server/src/main/resources/application.properties +++ b/powerauth-java-server/src/main/resources/application.properties @@ -87,6 +87,8 @@ powerauth.service.secureVault.enableBiometricAuthentication=false # PowerAuth Service Scheduled Jobs powerauth.service.scheduled.job.operationCleanup=5000 +powerauth.service.scheduled.job.activationsCleanup=5000 +powerauth.service.scheduled.job.activationsCleanup.lookBackInMilliseconds=3600000 # Database Lock Timeout Configuration spring.jpa.properties.lock.timeout=10000 From 8036adc3fd8ed689f93808fa74e56e7422b09617 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Tue, 28 Jun 2022 01:16:15 +0200 Subject: [PATCH 14/58] Use the correct method to remove pending activations --- .../service/behavior/tasks/v3/ActivationServiceBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index da10cb938..f348046c7 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -1977,7 +1977,7 @@ public void expireOperations() { try (final Stream abandonedActivations = activationRepository.findAbandonedActivations(activationStatuses, lookBackTimestamp, currentTimestamp)) { abandonedActivations.forEach(activation -> { logger.info("Removing abandoned activation with ID: {}, revoking recovery codes.", activation.getActivationId()); - removeActivation(activation, null, true); + deactivatePendingActivation(currentTimestamp, activation, false); }); } } From a15715f3e60335a4641268d758019945d43b9764 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 27 Jun 2022 17:04:07 +0200 Subject: [PATCH 15/58] Fix #746: Remove obsolete constraint in DDL --- docs/sql/mysql/create_schema.sql | 3 +-- docs/sql/oracle/create_schema.sql | 5 ----- docs/sql/postgresql/create_schema.sql | 5 ----- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/docs/sql/mysql/create_schema.sql b/docs/sql/mysql/create_schema.sql index 86679e8dd..2887f3b4e 100644 --- a/docs/sql/mysql/create_schema.sql +++ b/docs/sql/mysql/create_schema.sql @@ -227,8 +227,7 @@ CREATE TABLE pa_operation ( timestamp_created datetime NOT NULL, timestamp_expires datetime NOT NULL, timestamp_finalized datetime NULL, - PRIMARY KEY (id), - CONSTRAINT `FK_OPERATION_APPLICATION` FOREIGN KEY (`application_id`) REFERENCES `pa_application` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION + PRIMARY KEY (id) ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- diff --git a/docs/sql/oracle/create_schema.sql b/docs/sql/oracle/create_schema.sql index 3a1fcb2e9..22b60a455 100755 --- a/docs/sql/oracle/create_schema.sql +++ b/docs/sql/oracle/create_schema.sql @@ -309,11 +309,6 @@ ALTER TABLE "PA_RECOVERY_PUK" ADD CONSTRAINT "RECOVERY_PUK_CODE_FK" FOREIGN KEY -- ALTER TABLE "PA_RECOVERY_CONFIG" ADD CONSTRAINT "RECOVERY_CONFIG_APP_FK" FOREIGN KEY ("APPLICATION_ID") REFERENCES "PA_APPLICATION" ("ID") ENABLE; --- --- Ref Constraints for Table PA_OPERATION --- -ALTER TABLE "PA_OPERATION" ADD CONSTRAINT "OPERATION_APPLICATION_FK" FOREIGN KEY ("APPLICATION_ID") REFERENCES "PA_APPLICATION" ("ID") ENABLE; - --- --- Indexes for better performance. Oracle does not create indexes on foreign key automatically. diff --git a/docs/sql/postgresql/create_schema.sql b/docs/sql/postgresql/create_schema.sql index 724a7503c..69c1287fb 100644 --- a/docs/sql/postgresql/create_schema.sql +++ b/docs/sql/postgresql/create_schema.sql @@ -310,11 +310,6 @@ ALTER TABLE pa_recovery_puk ADD CONSTRAINT recovery_puk_code_fk FOREIGN KEY (rec -- ALTER TABLE pa_recovery_config ADD CONSTRAINT recovery_config_app_fk FOREIGN KEY (application_id) REFERENCES pa_application (id); --- --- Ref Constraints for Table PA_OPERATION --- -ALTER TABLE pa_operation ADD CONSTRAINT operation_application_fk FOREIGN KEY (application_id) REFERENCES pa_application (id); - --- --- Indexes for better performance. PostgreSQL does not create indexes on foreign key automatically. From 5b7e27bc53b26000880e866113c27ed35f80e3aa Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 27 Jun 2022 16:55:45 +0200 Subject: [PATCH 16/58] Fix #745: Add auditing DB tables into DDL --- docs/sql/mysql/create_schema.sql | 41 ++++++++++++ docs/sql/oracle/create_schema.sql | 41 ++++++++++++ docs/sql/postgresql/create_schema.sql | 95 +++++++++++++++++++-------- 3 files changed, 150 insertions(+), 27 deletions(-) diff --git a/docs/sql/mysql/create_schema.sql b/docs/sql/mysql/create_schema.sql index 2887f3b4e..a201683fb 100644 --- a/docs/sql/mysql/create_schema.sql +++ b/docs/sql/mysql/create_schema.sql @@ -264,6 +264,35 @@ CREATE TABLE shedlock ( PRIMARY KEY (name) ) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +-- +-- Create audit log table. +-- +CREATE TABLE audit_log ( + audit_log_id VARCHAR(36) PRIMARY KEY, + application_name VARCHAR(256) NOT NULL, + audit_level VARCHAR(32) NOT NULL, + audit_type VARCHAR(256), + timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + message TEXT NOT NULL, + exception_message TEXT, + stack_trace TEXT, + param TEXT, + calling_class VARCHAR(256) NOT NULL, + thread_name VARCHAR(256) NOT NULL, + version VARCHAR(256), + build_time TIMESTAMP NULL +) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- +-- Create audit parameters table. +-- +CREATE TABLE audit_param ( + audit_log_id VARCHAR(36), + timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + param_key VARCHAR(256), + param_value VARCHAR(3072) +) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + -- -- Indexes for better performance. InnoDB engine creates indexes on foreign keys automatically, so they are not included. -- @@ -297,3 +326,15 @@ CREATE INDEX `pa_operation_template_name_idx` ON `pa_operation_template` (`templ CREATE UNIQUE INDEX `pa_recovery_code_puk` ON `pa_recovery_puk`(`recovery_code_id`, `puk_index`); CREATE UNIQUE INDEX `pa_application_name` ON `pa_application`(`name`); + +-- +-- Auditing indexes. +-- +CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); +CREATE INDEX audit_log_application ON audit_log (application_name); +CREATE INDEX audit_log_level ON audit_log (audit_level); +CREATE INDEX audit_log_type ON audit_log (audit_type); +CREATE INDEX audit_param_log ON audit_param (audit_log_id); +CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); +CREATE INDEX audit_param_key ON audit_param (param_key); +CREATE FULLTEXT INDEX audit_param_value ON audit_param (param_value); \ No newline at end of file diff --git a/docs/sql/oracle/create_schema.sql b/docs/sql/oracle/create_schema.sql index 22b60a455..f0caa0e93 100755 --- a/docs/sql/oracle/create_schema.sql +++ b/docs/sql/oracle/create_schema.sql @@ -257,6 +257,35 @@ CREATE TABLE shedlock ( locked_by VARCHAR(255) NOT NULL ); +-- +-- Create audit log table. +-- +CREATE TABLE audit_log ( + audit_log_id VARCHAR2(36 CHAR) PRIMARY KEY, + application_name VARCHAR2(256 CHAR) NOT NULL, + audit_level VARCHAR2(32 CHAR) NOT NULL, + audit_type VARCHAR2(256 CHAR), + timestamp_created TIMESTAMP, + message CLOB NOT NULL, + exception_message CLOB, + stack_trace CLOB, + param CLOB, + calling_class VARCHAR2(256 CHAR) NOT NULL, + thread_name VARCHAR2(256 CHAR) NOT NULL, + version VARCHAR2(256 CHAR), + build_time TIMESTAMP +); + +-- +-- Create audit parameters table. +-- +CREATE TABLE audit_param ( + audit_log_id VARCHAR2(36 CHAR), + timestamp_created TIMESTAMP, + param_key VARCHAR2(256 CHAR), + param_value VARCHAR2(4000 CHAR) +); + -- -- Ref Constraints for Table PA_ACTIVATION -- @@ -365,3 +394,15 @@ CREATE INDEX PA_OPERATION_TS_CREATED_IDX ON PA_OPERATION(TIMESTAMP_CREATED); CREATE INDEX PA_OPERATION_TS_EXPIRES_IDX ON PA_OPERATION(TIMESTAMP_EXPIRES); CREATE INDEX PA_OPERATION_TEMPLATE_NAME_IDX ON PA_OPERATION_TEMPLATE(TEMPLATE_NAME); + +-- +-- Auditing indexes. +-- +CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); +CREATE INDEX audit_log_application ON audit_log (application_name); +CREATE INDEX audit_log_level ON audit_log (audit_level); +CREATE INDEX audit_log_type ON audit_log (audit_type); +CREATE INDEX audit_param_log ON audit_param (audit_log_id); +CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); +CREATE INDEX audit_param_key ON audit_param (param_key); +CREATE INDEX audit_param_value ON audit_param (param_value); \ No newline at end of file diff --git a/docs/sql/postgresql/create_schema.sql b/docs/sql/postgresql/create_schema.sql index 69c1287fb..32a6b1dcd 100644 --- a/docs/sql/postgresql/create_schema.sql +++ b/docs/sql/postgresql/create_schema.sql @@ -258,6 +258,35 @@ CREATE TABLE shedlock ( locked_by VARCHAR(255) NOT NULL ); +-- +-- Create audit log table. +-- +CREATE TABLE IF NOT EXISTS audit_log ( + audit_log_id VARCHAR(36) PRIMARY KEY, + application_name VARCHAR(256) NOT NULL, + audit_level VARCHAR(32) NOT NULL, + audit_type VARCHAR(256), + timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + message TEXT NOT NULL, + exception_message TEXT, + stack_trace TEXT, + param TEXT, + calling_class VARCHAR(256) NOT NULL, + thread_name VARCHAR(256) NOT NULL, + version VARCHAR(256), + build_time TIMESTAMP +); + +-- +-- Create audit parameters table. +-- +CREATE TABLE IF NOT EXISTS audit_param ( + audit_log_id VARCHAR(36), + timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + param_key VARCHAR(256), + param_value VARCHAR(4000) +); + -- -- Ref Constraints for Table PA_ACTIVATION -- @@ -312,57 +341,69 @@ ALTER TABLE pa_recovery_config ADD CONSTRAINT recovery_config_app_fk FOREIGN KEY --- ---- Indexes for better performance. PostgreSQL does not create indexes on foreign key automatically. +--- Indexes for better performance. PostgreSQL does not CREATE INDEXes ON foreign key automatically. --- -CREATE INDEX PA_ACTIVATION_APPLICATION ON PA_ACTIVATION(APPLICATION_ID); +CREATE INDEX pa_activation_application ON pa_activation(application_id); + +CREATE INDEX pa_activation_keypair ON pa_activation(master_keypair_id); -CREATE INDEX PA_ACTIVATION_KEYPAIR ON PA_ACTIVATION(MASTER_KEYPAIR_ID); +CREATE INDEX pa_activation_code ON pa_activation(activation_code); -CREATE INDEX PA_ACTIVATION_CODE ON PA_ACTIVATION(ACTIVATION_CODE); +CREATE INDEX pa_activation_user_id ON pa_activation(user_id); -CREATE INDEX PA_ACTIVATION_USER_ID ON PA_ACTIVATION(USER_ID); +CREATE INDEX pa_activation_history_act ON pa_activation_history(activation_id); -CREATE INDEX PA_ACTIVATION_HISTORY_ACT ON PA_ACTIVATION_HISTORY(ACTIVATION_ID); +CREATE INDEX pa_activation_history_created ON pa_activation_history(timestamp_created); -CREATE INDEX PA_ACTIVATION_HISTORY_CREATED ON PA_ACTIVATION_HISTORY(TIMESTAMP_CREATED); +CREATE INDEX pa_application_version_app ON pa_application_version(application_id); -CREATE INDEX PA_APPLICATION_VERSION_APP ON PA_APPLICATION_VERSION(APPLICATION_ID); +CREATE INDEX pa_master_keypair_application ON pa_master_keypair(application_id); -CREATE INDEX PA_MASTER_KEYPAIR_APPLICATION ON PA_MASTER_KEYPAIR(APPLICATION_ID); +CREATE UNIQUE INDEX pa_app_version_app_key ON pa_application_version(application_key); -CREATE UNIQUE INDEX PA_APP_VERSION_APP_KEY ON PA_APPLICATION_VERSION(APPLICATION_KEY); +CREATE INDEX pa_app_callback_app ON pa_application_callback(application_id); -CREATE INDEX PA_APP_CALLBACK_APP ON PA_APPLICATION_CALLBACK(APPLICATION_ID); +CREATE UNIQUE INDEX pa_integration_token ON pa_integration(client_token); -CREATE UNIQUE INDEX PA_INTEGRATION_TOKEN ON PA_INTEGRATION(CLIENT_TOKEN); +CREATE INDEX pa_signature_audit_activation ON pa_signature_audit(activation_id); -CREATE INDEX PA_SIGNATURE_AUDIT_ACTIVATION ON PA_SIGNATURE_AUDIT(ACTIVATION_ID); +CREATE INDEX pa_signature_audit_created ON pa_signature_audit(timestamp_created); -CREATE INDEX PA_SIGNATURE_AUDIT_CREATED ON PA_SIGNATURE_AUDIT(TIMESTAMP_CREATED); +CREATE INDEX pa_token_activation ON pa_token(activation_id); -CREATE INDEX PA_TOKEN_ACTIVATION ON PA_TOKEN(ACTIVATION_ID); +CREATE INDEX pa_recovery_code_code ON pa_recovery_code(recovery_code); -CREATE INDEX PA_RECOVERY_CODE_CODE ON PA_RECOVERY_CODE(RECOVERY_CODE); +CREATE INDEX pa_recovery_code_app ON pa_recovery_code(application_id); -CREATE INDEX PA_RECOVERY_CODE_APP ON PA_RECOVERY_CODE(APPLICATION_ID); +CREATE INDEX pa_recovery_code_user ON pa_recovery_code(user_id); -CREATE INDEX PA_RECOVERY_CODE_USER ON PA_RECOVERY_CODE(USER_ID); +CREATE INDEX pa_recovery_code_act ON pa_recovery_code(activation_id); -CREATE INDEX PA_RECOVERY_CODE_ACT ON PA_RECOVERY_CODE(ACTIVATION_ID); +CREATE UNIQUE INDEX pa_recovery_code_puk ON pa_recovery_puk(recovery_code_id, puk_index); -CREATE UNIQUE INDEX PA_RECOVERY_CODE_PUK ON PA_RECOVERY_PUK(RECOVERY_CODE_ID, PUK_INDEX); +CREATE INDEX pa_recovery_puk_code ON pa_recovery_puk(recovery_code_id); -CREATE INDEX PA_RECOVERY_PUK_CODE ON PA_RECOVERY_PUK(RECOVERY_CODE_ID); +CREATE UNIQUE INDEX pa_recovery_config_app ON pa_recovery_config(application_id); -CREATE UNIQUE INDEX PA_RECOVERY_CONFIG_APP ON PA_RECOVERY_CONFIG(APPLICATION_ID); +CREATE UNIQUE INDEX pa_application_name ON pa_application(name); -CREATE UNIQUE INDEX PA_APPLICATION_NAME ON PA_APPLICATION(NAME); +CREATE INDEX pa_operation_user ON pa_operation(user_id); -CREATE INDEX PA_OPERATION_USER ON PA_OPERATION(USER_ID); +CREATE INDEX pa_operation_ts_created_idx ON pa_operation(timestamp_created); -CREATE INDEX PA_OPERATION_TS_CREATED_IDX ON PA_OPERATION(TIMESTAMP_CREATED); +CREATE INDEX pa_operation_ts_expires_idx ON pa_operation(timestamp_expires); -CREATE INDEX PA_OPERATION_TS_EXPIRES_IDX ON PA_OPERATION(TIMESTAMP_EXPIRES); +CREATE INDEX pa_operation_template_name_idx ON pa_operation_template(template_name); -CREATE INDEX PA_OPERATION_TEMPLATE_NAME_IDX ON PA_OPERATION_TEMPLATE(TEMPLATE_NAME); +-- +-- Auditing indexes. +-- +CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); +CREATE INDEX audit_log_application ON audit_log (application_name); +CREATE INDEX audit_log_level ON audit_log (audit_level); +CREATE INDEX audit_log_type ON audit_log (audit_type); +CREATE INDEX audit_param_log ON audit_param (audit_log_id); +CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); +CREATE INDEX audit_param_key ON audit_param (param_key); +CREATE INDEX audit_param_value ON audit_param (param_value); From a6c7688b339681d4e3b33b60ed5963eb80b968be Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Tue, 28 Jun 2022 21:12:31 +0200 Subject: [PATCH 17/58] Use expiration timestam for interval queries --- .../server/database/repository/ActivationRepository.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java index d1be0bf8b..317062031 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java @@ -170,12 +170,12 @@ default Long getActivationCountByActivationCode(String applicationId, String act List lookupActivations(Collection userIds, Collection applicationIds, Date timestampLastUsedBefore, Date timestampLastUsedAfter, Collection states); /** - * Fetch all activations that are in a given state, were created after a specified timestamp, and are already expired according to provided current timestamp. + * Fetch all activations that are in a given state, were expired after a specified timestamp, and are already expired according to a provided current timestamp. * @param states Activation states that are used for the lookup. - * @param startingTimestamp Timestamp of when the activation must have been created. - * @param currentTimestamp Current timestamp, to see expired operations. + * @param startingTimestamp Timestamp after which the activation was expired. + * @param currentTimestamp Current timestamp, to identify already expired operations. * @return Stream of activations. */ - @Query("SELECT a FROM ActivationRecordEntity a WHERE a.activationStatus IN :states AND a.timestampCreated >= :startingTimestamp AND a.timestampActivationExpire < :currentTimestamp") + @Query("SELECT a FROM ActivationRecordEntity a WHERE a.activationStatus IN :states AND a.timestampActivationExpire >= :startingTimestamp AND a.timestampActivationExpire < :currentTimestamp") Stream findAbandonedActivations(Collection states, Date startingTimestamp, Date currentTimestamp); } From f28bcfbb9eee920944cc4463dccd5ca7af15d8ca Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Wed, 29 Jun 2022 15:49:33 +0200 Subject: [PATCH 18/58] Fix #747: Duplicate migration instructions for auditing tables --- docs/PowerAuth-Server-1.2.5.md | 142 --------------------------------- docs/PowerAuth-Server-1.3.0.md | 12 ++- 2 files changed, 8 insertions(+), 146 deletions(-) diff --git a/docs/PowerAuth-Server-1.2.5.md b/docs/PowerAuth-Server-1.2.5.md index fd5fee16a..8f3928e9c 100644 --- a/docs/PowerAuth-Server-1.2.5.md +++ b/docs/PowerAuth-Server-1.2.5.md @@ -42,148 +42,6 @@ ALTER TABLE pa_operation ADD activation_flag VARCHAR(255) NULL; ALTER TABLE pa_operation ADD additional_data TEXT NULL; ``` -## Create Auditing Tables - -Create tables for auditing: -- `audit_log` - table used to store audit logs -- `audit_param` - table used to store detailed parameters for audit logs - -### Oracle - -```sql --- --- Create audit log table. --- -CREATE TABLE audit_log ( - audit_log_id VARCHAR2(36 CHAR) PRIMARY KEY, - application_name VARCHAR2(256 CHAR) NOT NULL, - audit_level VARCHAR2(32 CHAR) NOT NULL, - audit_type VARCHAR2(256 CHAR), - timestamp_created TIMESTAMP, - message CLOB NOT NULL, - exception_message CLOB, - stack_trace CLOB, - param CLOB, - calling_class VARCHAR2(256 CHAR) NOT NULL, - thread_name VARCHAR2(256 CHAR) NOT NULL, - version VARCHAR2(256 CHAR), - build_time TIMESTAMP -); - --- --- Create audit parameters table. --- -CREATE TABLE audit_param ( - audit_log_id VARCHAR2(36 CHAR), - timestamp_created TIMESTAMP, - param_key VARCHAR2(256 CHAR), - param_value VARCHAR2(4000 CHAR) -); - --- --- Create indexes. --- -CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); -CREATE INDEX audit_log_application ON audit_log (application_name); -CREATE INDEX audit_log_level ON audit_log (audit_level); -CREATE INDEX audit_log_type ON audit_log (audit_type); -CREATE INDEX audit_param_log ON audit_param (audit_log_id); -CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); -CREATE INDEX audit_param_key ON audit_param (param_key); -CREATE INDEX audit_param_value ON audit_param (param_value); -``` - -### PostgreSQL - -```sql --- --- Create audit log table. --- -CREATE TABLE audit_log ( - audit_log_id VARCHAR(36) PRIMARY KEY, - application_name VARCHAR(256) NOT NULL, - audit_level VARCHAR(32) NOT NULL, - audit_type VARCHAR(256), - timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - message TEXT NOT NULL, - exception_message TEXT, - stack_trace TEXT, - param TEXT, - calling_class VARCHAR(256) NOT NULL, - thread_name VARCHAR(256) NOT NULL, - version VARCHAR(256), - build_time TIMESTAMP -); - --- --- Create audit parameters table. --- -CREATE TABLE audit_param ( - audit_log_id VARCHAR(36), - timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - param_key VARCHAR(256), - param_value VARCHAR(4000) -); - --- --- Create indexes. --- -CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); -CREATE INDEX audit_log_application ON audit_log (application_name); -CREATE INDEX audit_log_level ON audit_log (audit_level); -CREATE INDEX audit_log_type ON audit_log (audit_type); -CREATE INDEX audit_param_log ON audit_param (audit_log_id); -CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); -CREATE INDEX audit_param_key ON audit_param (param_key); -CREATE INDEX audit_param_value ON audit_param (param_value); -``` - -### MySQL - -```sql --- --- Create audit log table. --- -CREATE TABLE audit_log ( - audit_log_id VARCHAR(36) PRIMARY KEY, - application_name VARCHAR(256) NOT NULL, - audit_level VARCHAR(32) NOT NULL, - audit_type VARCHAR(256), - timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - message TEXT NOT NULL, - exception_message TEXT, - stack_trace TEXT, - param TEXT, - calling_class VARCHAR(256) NOT NULL, - thread_name VARCHAR(256) NOT NULL, - version VARCHAR(256), - build_time TIMESTAMP NULL -) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - --- --- Create audit parameters table. --- -CREATE TABLE audit_param ( - audit_log_id VARCHAR(36), - timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - param_key VARCHAR(256), - param_value VARCHAR(3072) -) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - --- --- Create indexes. --- -CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); -CREATE INDEX audit_log_application ON audit_log (application_name); -CREATE INDEX audit_log_level ON audit_log (audit_level); -CREATE INDEX audit_log_type ON audit_log (audit_type); -CREATE INDEX audit_param_log ON audit_param (audit_log_id); -CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); -CREATE INDEX audit_param_key ON audit_param (param_key); -CREATE FULLTEXT INDEX audit_param_value ON audit_param (param_value); -``` - - ## Create New Column in Activation History Table The `pa_activation_history` table was updated to include activation version. diff --git a/docs/PowerAuth-Server-1.3.0.md b/docs/PowerAuth-Server-1.3.0.md index 1eff1b298..7bd2be47b 100644 --- a/docs/PowerAuth-Server-1.3.0.md +++ b/docs/PowerAuth-Server-1.3.0.md @@ -112,6 +112,10 @@ Create tables for auditing: - `audit_log` - table used to store audit logs - `audit_param` - table used to store detailed parameters for audit logs + +The auditing tables may be already present in your database schema in case the database schema is not separated for different PowerAuth applications. You might have also added these tables as part of migration to release `1.2.5` before these duplicate migration instructions were removed. In case tables `audit_log` and `audit_param` are already present, you can safely skip this migration step. + + ### Oracle ```sql @@ -163,7 +167,7 @@ CREATE INDEX audit_param_value ON audit_param (param_value); -- -- Create audit log table. -- -CREATE TABLE audit_log ( +CREATE TABLE IF NOT EXISTS audit_log ( audit_log_id VARCHAR(36) PRIMARY KEY, application_name VARCHAR(256) NOT NULL, audit_level VARCHAR(32) NOT NULL, @@ -182,7 +186,7 @@ CREATE TABLE audit_log ( -- -- Create audit parameters table. -- -CREATE TABLE audit_param ( +CREATE TABLE IF NOT EXISTS audit_param ( audit_log_id VARCHAR(36), timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, param_key VARCHAR(256), @@ -208,7 +212,7 @@ CREATE INDEX audit_param_value ON audit_param (param_value); -- -- Create audit log table. -- -CREATE TABLE audit_log ( +CREATE TABLE IF NOT EXISTS audit_log ( audit_log_id VARCHAR(36) PRIMARY KEY, application_name VARCHAR(256) NOT NULL, audit_level VARCHAR(32) NOT NULL, @@ -227,7 +231,7 @@ CREATE TABLE audit_log ( -- -- Create audit parameters table. -- -CREATE TABLE audit_param ( +CREATE TABLE IF NOT EXISTS audit_param ( audit_log_id VARCHAR(36), timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, param_key VARCHAR(256), From 63d5647c05773d32a40772fb1c807ccc0c428138 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Wed, 29 Jun 2022 16:46:55 +0200 Subject: [PATCH 19/58] Fix #754: Failing build for PowerAuth server --- .../app/server/configuration/PowerAuthServiceConfiguration.java | 2 +- .../service/behavior/tasks/v3/ActivationServiceBehavior.java | 2 +- .../service/behavior/tasks/v3/OperationServiceBehavior.java | 2 +- powerauth-java-server/src/test/resources/application.properties | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java index ee3bb4bb0..f495aa13a 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java @@ -120,7 +120,7 @@ public class PowerAuthServiceConfiguration { /** * How many milliseconds should the activation cleanup job look to the past. */ - @Value("${powerauth.service.scheduled.job.activationsCleanup.lookBackInMilliseconds}") + @Value("${powerauth.service.scheduled.job.activationsCleanup.lookBackInMilliseconds:3600000}") @Min(0) private int activationsCleanupLookBackInMilliseconds; diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index f348046c7..93365610a 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -1964,7 +1964,7 @@ private ActivationRecovery createRecoveryCodeForActivation(ActivationRecordEntit // Scheduled tasks - @Scheduled(fixedRateString = "${powerauth.service.scheduled.job.activationsCleanup}") + @Scheduled(fixedRateString = "${powerauth.service.scheduled.job.activationsCleanup:5000}") @SchedulerLock(name = "expireActivationsTask") @Transactional public void expireOperations() { diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/OperationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/OperationServiceBehavior.java index bc716a721..2bb0e90a6 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/OperationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/OperationServiceBehavior.java @@ -716,7 +716,7 @@ private Map mapMerge(Map m1, Map // Scheduled tasks - @Scheduled(fixedRateString = "${powerauth.service.scheduled.job.operationCleanup}") + @Scheduled(fixedRateString = "${powerauth.service.scheduled.job.operationCleanup:5000}") @SchedulerLock(name = "expireOperationsTask") @Transactional public void expireOperations() { diff --git a/powerauth-java-server/src/test/resources/application.properties b/powerauth-java-server/src/test/resources/application.properties index 4738485c5..450a6caa3 100644 --- a/powerauth-java-server/src/test/resources/application.properties +++ b/powerauth-java-server/src/test/resources/application.properties @@ -66,6 +66,8 @@ powerauth.service.secureVault.enableBiometricAuthentication=false # PowerAuth Service Scheduled Jobs powerauth.service.scheduled.job.operationCleanup=5000 +powerauth.service.scheduled.job.activationsCleanup=5000 +powerauth.service.scheduled.job.activationsCleanup.lookBackInMilliseconds=3600000 # Database Lock Timeout Configuration spring.jpa.properties.lock.timeout=10000 From b06b9b350600a694431e56354d632f44dfc20ef2 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Mon, 11 Jul 2022 15:50:56 +0200 Subject: [PATCH 20/58] Fix #756: Add support for Active Directory LDAP to Admin --- .../ActiveDirectoryConfiguration.java | 74 ++++++++ .../ApplicationConfiguration.java | 132 -------------- .../configuration/LdapConfiguration.java | 163 ++++++++++++++++++ .../configuration/WebSecurityConfig.java | 57 ++---- .../app/admin/security/SecurityMethod.java | 44 ----- .../security/app/admin/util/SecurityUtil.java | 121 +++++++++++++ .../src/main/resources/application.properties | 8 +- .../src/main/webapp/WEB-INF/jsp/header.jsp | 3 + .../main/webapp/WEB-INF/jsp/headerSimple.jsp | 3 + 9 files changed, 383 insertions(+), 222 deletions(-) create mode 100644 powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/ActiveDirectoryConfiguration.java create mode 100644 powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/LdapConfiguration.java delete mode 100644 powerauth-admin/src/main/java/io/getlime/security/app/admin/security/SecurityMethod.java create mode 100644 powerauth-admin/src/main/java/io/getlime/security/app/admin/util/SecurityUtil.java diff --git a/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/ActiveDirectoryConfiguration.java b/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/ActiveDirectoryConfiguration.java new file mode 100644 index 000000000..88166d20a --- /dev/null +++ b/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/ActiveDirectoryConfiguration.java @@ -0,0 +1,74 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2022 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.getlime.security.app.admin.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +/** + * Active directory configuration. + * @author Petr Dvorak, petr@wultra.com + */ +@Configuration +public class ActiveDirectoryConfiguration { + + @Value("${powerauth.admin.security.activeDirectory.domain}") + private String activeDirectoryDomain; + + @Value("${powerauth.admin.security.activeDirectory.url}") + private String activeDirectoryUrl; + + @Value("${powerauth.admin.security.activeDirectory.root}") + private String activeDirectoryRoot; + + @Value("${powerauth.admin.security.activeDirectory.userSearchFilter}") + private String activeDirectoryUserSearchFilter; + + public String getActiveDirectoryDomain() { + return activeDirectoryDomain; + } + + public void setActiveDirectoryDomain(String activeDirectoryDomain) { + this.activeDirectoryDomain = activeDirectoryDomain; + } + + public String getActiveDirectoryUrl() { + return activeDirectoryUrl; + } + + public void setActiveDirectoryUrl(String activeDirectoryUrl) { + this.activeDirectoryUrl = activeDirectoryUrl; + } + + public String getActiveDirectoryRoot() { + return activeDirectoryRoot; + } + + public void setActiveDirectoryRoot(String activeDirectoryRoot) { + this.activeDirectoryRoot = activeDirectoryRoot; + } + + public String getActiveDirectoryUserSearchFilter() { + return activeDirectoryUserSearchFilter; + } + + public void setActiveDirectoryUserSearchFilter(String activeDirectoryUserSearchFilter) { + this.activeDirectoryUserSearchFilter = activeDirectoryUserSearchFilter; + } +} diff --git a/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/ApplicationConfiguration.java b/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/ApplicationConfiguration.java index 971ca7970..fb18fb8da 100644 --- a/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/ApplicationConfiguration.java +++ b/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/ApplicationConfiguration.java @@ -46,42 +46,6 @@ public class ApplicationConfiguration { @Value("${powerauth.admin.security.method}") private String securityMethod; - @Value("${powerauth.admin.security.ldap.userDNPatterns}") - private String ldapUserDNPatterns; - - @Value("${powerauth.admin.security.ldap.userSearchBase}") - private String ldapUserSearchBase; - - @Value("${powerauth.admin.security.ldap.userSearchFilter}") - private String ldapUserSearchFilter; - - @Value("${powerauth.admin.security.ldap.groupSearchBase}") - private String ldapGroupSearchBase; - - @Value("${powerauth.admin.security.ldap.groupSearchFilter}") - private String ldapGroupSearchFilter; - - @Value("${powerauth.admin.security.ldap.groupRoleAttribute}") - private String ldapGroupRoleAttribute; - - @Value("${powerauth.admin.security.ldap.ldif}") - private String ldapLdif; - - @Value("${powerauth.admin.security.ldap.url}") - private String ldapUrl; - - @Value("${powerauth.admin.security.ldap.port}") - private String ldapPort; - - @Value("${powerauth.admin.security.ldap.root}") - private String ldapRoot; - - @Value("${powerauth.admin.security.ldap.managerDN}") - private String ldapManagerDN; - - @Value("${powerauth.admin.security.ldap.managerPassword}") - private String ldapManagerPassword; - @Value("${powerauth.admin.service.applicationName}") private String applicationName; @@ -133,102 +97,6 @@ public void setSecurityMethod(String securityMethod) { this.securityMethod = securityMethod; } - public String getLdapUserDNPatterns() { - return ldapUserDNPatterns; - } - - public void setLdapUserDNPatterns(String ldapUserDNPatterns) { - this.ldapUserDNPatterns = ldapUserDNPatterns; - } - - public String getLdapUserSearchBase() { - return ldapUserSearchBase; - } - - public void setLdapUserSearchBase(String ldapUserSearchBase) { - this.ldapUserSearchBase = ldapUserSearchBase; - } - - public String getLdapUserSearchFilter() { - return ldapUserSearchFilter; - } - - public void setLdapUserSearchFilter(String ldapUserSearchFilter) { - this.ldapUserSearchFilter = ldapUserSearchFilter; - } - - public String getLdapGroupSearchBase() { - return ldapGroupSearchBase; - } - - public void setLdapGroupSearchBase(String ldapGroupSearchBase) { - this.ldapGroupSearchBase = ldapGroupSearchBase; - } - - public String getLdapGroupSearchFilter() { - return ldapGroupSearchFilter; - } - - public void setLdapGroupSearchFilter(String ldapGroupSearchFilter) { - this.ldapGroupSearchFilter = ldapGroupSearchFilter; - } - - public String getLdapGroupRoleAttribute() { - return ldapGroupRoleAttribute; - } - - public void setLdapGroupRoleAttribute(String ldapGroupRoleAttribute) { - this.ldapGroupRoleAttribute = ldapGroupRoleAttribute; - } - - public String getLdapLdif() { - return ldapLdif; - } - - public void setLdapLdif(String ldapLdif) { - this.ldapLdif = ldapLdif; - } - - public String getLdapUrl() { - return ldapUrl; - } - - public void setLdapUrl(String ldapUrl) { - this.ldapUrl = ldapUrl; - } - - public String getLdapPort() { - return ldapPort; - } - - public void setLdapPort(String ldapPort) { - this.ldapPort = ldapPort; - } - - public String getLdapRoot() { - return ldapRoot; - } - - public void setLdapRoot(String ldapRoot) { - this.ldapRoot = ldapRoot; - } - - public String getLdapManagerDN() { - return ldapManagerDN; - } - - public void setLdapManagerDN(String ldapManagerDN) { - this.ldapManagerDN = ldapManagerDN; - } - - public String getLdapManagerPassword() { - return ldapManagerPassword; - } - - public void setLdapManagerPassword(String ldapManagerPassword) { - this.ldapManagerPassword = ldapManagerPassword; - } - public String getApplicationName() { return applicationName; } diff --git a/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/LdapConfiguration.java b/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/LdapConfiguration.java new file mode 100644 index 000000000..b3183190f --- /dev/null +++ b/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/LdapConfiguration.java @@ -0,0 +1,163 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2022 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.getlime.security.app.admin.configuration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +/** + * LDAP Configuration + * @author Petr Dvorak, petr@wultra.com + */ +@Configuration +public class LdapConfiguration { + + @Value("${powerauth.admin.security.ldap.userDNPatterns}") + private String ldapUserDNPatterns; + + @Value("${powerauth.admin.security.ldap.userSearchBase}") + private String ldapUserSearchBase; + + @Value("${powerauth.admin.security.ldap.userSearchFilter}") + private String ldapUserSearchFilter; + + @Value("${powerauth.admin.security.ldap.groupSearchBase}") + private String ldapGroupSearchBase; + + @Value("${powerauth.admin.security.ldap.groupSearchFilter}") + private String ldapGroupSearchFilter; + + @Value("${powerauth.admin.security.ldap.groupRoleAttribute}") + private String ldapGroupRoleAttribute; + + @Value("${powerauth.admin.security.ldap.ldif}") + private String ldapLdif; + + @Value("${powerauth.admin.security.ldap.url}") + private String ldapUrl; + + @Value("${powerauth.admin.security.ldap.port}") + private String ldapPort; + + @Value("${powerauth.admin.security.ldap.root}") + private String ldapRoot; + + @Value("${powerauth.admin.security.ldap.managerDN}") + private String ldapManagerDN; + + @Value("${powerauth.admin.security.ldap.managerPassword}") + private String ldapManagerPassword; + + public String getLdapUserDNPatterns() { + return ldapUserDNPatterns; + } + + public void setLdapUserDNPatterns(String ldapUserDNPatterns) { + this.ldapUserDNPatterns = ldapUserDNPatterns; + } + + public String getLdapUserSearchBase() { + return ldapUserSearchBase; + } + + public void setLdapUserSearchBase(String ldapUserSearchBase) { + this.ldapUserSearchBase = ldapUserSearchBase; + } + + public String getLdapUserSearchFilter() { + return ldapUserSearchFilter; + } + + public void setLdapUserSearchFilter(String ldapUserSearchFilter) { + this.ldapUserSearchFilter = ldapUserSearchFilter; + } + + public String getLdapGroupSearchBase() { + return ldapGroupSearchBase; + } + + public void setLdapGroupSearchBase(String ldapGroupSearchBase) { + this.ldapGroupSearchBase = ldapGroupSearchBase; + } + + public String getLdapGroupSearchFilter() { + return ldapGroupSearchFilter; + } + + public void setLdapGroupSearchFilter(String ldapGroupSearchFilter) { + this.ldapGroupSearchFilter = ldapGroupSearchFilter; + } + + public String getLdapGroupRoleAttribute() { + return ldapGroupRoleAttribute; + } + + public void setLdapGroupRoleAttribute(String ldapGroupRoleAttribute) { + this.ldapGroupRoleAttribute = ldapGroupRoleAttribute; + } + + public String getLdapLdif() { + return ldapLdif; + } + + public void setLdapLdif(String ldapLdif) { + this.ldapLdif = ldapLdif; + } + + public String getLdapUrl() { + return ldapUrl; + } + + public void setLdapUrl(String ldapUrl) { + this.ldapUrl = ldapUrl; + } + + public String getLdapPort() { + return ldapPort; + } + + public void setLdapPort(String ldapPort) { + this.ldapPort = ldapPort; + } + + public String getLdapRoot() { + return ldapRoot; + } + + public void setLdapRoot(String ldapRoot) { + this.ldapRoot = ldapRoot; + } + + public String getLdapManagerDN() { + return ldapManagerDN; + } + + public void setLdapManagerDN(String ldapManagerDN) { + this.ldapManagerDN = ldapManagerDN; + } + + public String getLdapManagerPassword() { + return ldapManagerPassword; + } + + public void setLdapManagerPassword(String ldapManagerPassword) { + this.ldapManagerPassword = ldapManagerPassword; + } + +} diff --git a/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/WebSecurityConfig.java b/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/WebSecurityConfig.java index 23ad2876b..432ca9323 100644 --- a/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/WebSecurityConfig.java +++ b/powerauth-admin/src/main/java/io/getlime/security/app/admin/configuration/WebSecurityConfig.java @@ -16,11 +16,10 @@ package io.getlime.security.app.admin.configuration; -import io.getlime.security.app.admin.security.SecurityMethod; +import io.getlime.security.app.admin.util.SecurityUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.authentication.configurers.ldap.LdapAuthenticationProviderConfigurer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -33,10 +32,14 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { private final ApplicationConfiguration configuration; + private final LdapConfiguration ldapConfiguration; + private final ActiveDirectoryConfiguration activeDirectoryConfiguration; @Autowired - public WebSecurityConfig(ApplicationConfiguration configuration) { + public WebSecurityConfig(ApplicationConfiguration configuration, LdapConfiguration ldapConfiguration, ActiveDirectoryConfiguration activeDirectoryConfiguration) { this.configuration = configuration; + this.ldapConfiguration = ldapConfiguration; + this.activeDirectoryConfiguration = activeDirectoryConfiguration; } @Override @@ -54,49 +57,13 @@ protected void configure(HttpSecurity http) throws Exception { } } - @Autowired + @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { - if (SecurityMethod.isLdap(configuration.getSecurityMethod())) { - - LdapAuthenticationProviderConfigurer ldapAuthentication = auth.ldapAuthentication(); - if (!configuration.getLdapGroupRoleAttribute().isEmpty()) { - ldapAuthentication = ldapAuthentication.groupRoleAttribute(configuration.getLdapGroupRoleAttribute()); - } - if (!configuration.getLdapGroupSearchBase().isEmpty()) { - ldapAuthentication = ldapAuthentication.groupSearchBase(configuration.getLdapGroupSearchBase()); - } - if (!configuration.getLdapGroupSearchFilter().isEmpty()) { - ldapAuthentication = ldapAuthentication.groupSearchFilter(configuration.getLdapGroupSearchFilter()); - } - if (!configuration.getLdapUserDNPatterns().isEmpty()) { - ldapAuthentication = ldapAuthentication.userDnPatterns(configuration.getLdapUserDNPatterns()); - } - if (!configuration.getLdapUserSearchBase().isEmpty()) { - ldapAuthentication = ldapAuthentication.userSearchBase(configuration.getLdapUserSearchBase()); - } - if (!configuration.getLdapUserSearchFilter().isEmpty()) { - ldapAuthentication = ldapAuthentication.userSearchFilter(configuration.getLdapUserSearchFilter()); - } - - LdapAuthenticationProviderConfigurer.ContextSourceBuilder contextSource = ldapAuthentication.contextSource(); - if (!configuration.getLdapUrl().isEmpty()) { - contextSource.url(configuration.getLdapUrl()); - } - if (!configuration.getLdapPort().isEmpty()) { - contextSource.port(Integer.parseInt(configuration.getLdapPort())); - } - if (!configuration.getLdapRoot().isEmpty()) { - contextSource.root(configuration.getLdapRoot()); - } - if (!configuration.getLdapLdif().isEmpty()) { - contextSource.ldif(configuration.getLdapLdif()); - } - if (!configuration.getLdapManagerDN().isEmpty()) { - contextSource.managerDn(configuration.getLdapManagerDN()); - } - if (!configuration.getLdapManagerPassword().isEmpty()) { - contextSource.managerPassword(configuration.getLdapManagerPassword()); - } + final String securityMethod = configuration.getSecurityMethod(); + if (SecurityUtil.isLdap(securityMethod)) { + SecurityUtil.configureLdap(auth, ldapConfiguration); + } else if (SecurityUtil.isActiveDirectory(securityMethod)) { + SecurityUtil.configureActiveDirectory(auth, activeDirectoryConfiguration); } } diff --git a/powerauth-admin/src/main/java/io/getlime/security/app/admin/security/SecurityMethod.java b/powerauth-admin/src/main/java/io/getlime/security/app/admin/security/SecurityMethod.java deleted file mode 100644 index 596fe4fd9..000000000 --- a/powerauth-admin/src/main/java/io/getlime/security/app/admin/security/SecurityMethod.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2017 Wultra s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.getlime.security.app.admin.security; - -/** - * Helper class that determines which security method is used. - * - * Currently, only LDAP is supported. - * - * @author Petr Dvorak, petr@wultra.com - */ -public class SecurityMethod { - - /** - * Authentication via LDAP. - */ - public static final String LDAP = "ldap"; - - /** - * Checks if a provided security method is LDAP authentication. - * @param securityMethod Security method to be tested. - * @return True in case given method represents LDAP authentication, false otherwise. - */ - public static boolean isLdap(String securityMethod) { - return securityMethod != null && securityMethod - .trim() - .toLowerCase() - .equals(LDAP); - } -} diff --git a/powerauth-admin/src/main/java/io/getlime/security/app/admin/util/SecurityUtil.java b/powerauth-admin/src/main/java/io/getlime/security/app/admin/util/SecurityUtil.java new file mode 100644 index 000000000..28f85ded5 --- /dev/null +++ b/powerauth-admin/src/main/java/io/getlime/security/app/admin/util/SecurityUtil.java @@ -0,0 +1,121 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2022 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.getlime.security.app.admin.util; + +import io.getlime.security.app.admin.configuration.ActiveDirectoryConfiguration; +import io.getlime.security.app.admin.configuration.LdapConfiguration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configurers.ldap.LdapAuthenticationProviderConfigurer; +import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider; +import org.springframework.util.StringUtils; + +/** + * Utility class for various security related tasks. + * + * @author Petr Dvorak, petr@wultra.com + */ +public class SecurityUtil { + + /** + * Authentication via LDAP. + */ + public static final String LDAP = "ldap"; + + /** + * Authentication via Active Directory. + */ + public static final String ACTIVE_DIRECTORY = "active-directory"; + + /** + * Checks if a provided security method is LDAP authentication. + * @param securityMethod Security method to be tested. + * @return True in case given method represents LDAP authentication, false otherwise. + */ + public static boolean isLdap(String securityMethod) { + return securityMethod != null && securityMethod + .trim() + .equalsIgnoreCase(LDAP); + } + + /** + * Checks if a provided security method is Active Directory authentication. + * @param securityMethod Security method to be tested. + * @return True in case given method represents Active Directory authentication, false otherwise. + */ + public static boolean isActiveDirectory(String securityMethod) { + return securityMethod != null && securityMethod + .trim() + .equalsIgnoreCase(ACTIVE_DIRECTORY); + } + + public static void configureLdap(AuthenticationManagerBuilder auth, LdapConfiguration configuration) throws Exception { + final LdapAuthenticationProviderConfigurer ldapAuthenticationBuilder = auth.ldapAuthentication(); + if (!configuration.getLdapGroupRoleAttribute().isEmpty()) { + ldapAuthenticationBuilder.groupRoleAttribute(configuration.getLdapGroupRoleAttribute()); + } + if (!configuration.getLdapGroupSearchBase().isEmpty()) { + ldapAuthenticationBuilder.groupSearchBase(configuration.getLdapGroupSearchBase()); + } + if (!configuration.getLdapGroupSearchFilter().isEmpty()) { + ldapAuthenticationBuilder.groupSearchFilter(configuration.getLdapGroupSearchFilter()); + } + if (!configuration.getLdapUserDNPatterns().isEmpty()) { + ldapAuthenticationBuilder.userDnPatterns(configuration.getLdapUserDNPatterns()); + } + if (!configuration.getLdapUserSearchBase().isEmpty()) { + ldapAuthenticationBuilder.userSearchBase(configuration.getLdapUserSearchBase()); + } + if (!configuration.getLdapUserSearchFilter().isEmpty()) { + ldapAuthenticationBuilder.userSearchFilter(configuration.getLdapUserSearchFilter()); + } + + final LdapAuthenticationProviderConfigurer.ContextSourceBuilder contextSource = ldapAuthenticationBuilder.contextSource(); + if (!configuration.getLdapUrl().isEmpty()) { + contextSource.url(configuration.getLdapUrl()); + } + if (!configuration.getLdapPort().isEmpty()) { + contextSource.port(Integer.parseInt(configuration.getLdapPort())); + } + if (!configuration.getLdapRoot().isEmpty()) { + contextSource.root(configuration.getLdapRoot()); + } + if (!configuration.getLdapLdif().isEmpty()) { + contextSource.ldif(configuration.getLdapLdif()); + } + if (!configuration.getLdapManagerDN().isEmpty()) { + contextSource.managerDn(configuration.getLdapManagerDN()); + } + if (!configuration.getLdapManagerPassword().isEmpty()) { + contextSource.managerPassword(configuration.getLdapManagerPassword()); + } + } + + public static void configureActiveDirectory(AuthenticationManagerBuilder auth, ActiveDirectoryConfiguration configuration) { + final String activeDirectoryDomain = configuration.getActiveDirectoryDomain(); + final String ldapUrl = configuration.getActiveDirectoryUrl(); + final String ldapRoot = configuration.getActiveDirectoryRoot(); + final ActiveDirectoryLdapAuthenticationProvider authenticationProvider = new ActiveDirectoryLdapAuthenticationProvider(activeDirectoryDomain, ldapUrl, ldapRoot); + final String userSearchFilter = configuration.getActiveDirectoryUserSearchFilter(); + if (StringUtils.hasText(userSearchFilter)) { + authenticationProvider.setSearchFilter(userSearchFilter); + } + auth.authenticationProvider(authenticationProvider); + } + +} diff --git a/powerauth-admin/src/main/resources/application.properties b/powerauth-admin/src/main/resources/application.properties index 1d88aca2b..a4ace6ed5 100644 --- a/powerauth-admin/src/main/resources/application.properties +++ b/powerauth-admin/src/main/resources/application.properties @@ -13,7 +13,7 @@ powerauth.service.security.clientSecret= # HTTPS configuration powerauth.service.ssl.acceptInvalidSslCertificate=false -# PowerAuth Admin Security Settings +# PowerAuth Admin Security Settings - 'ldap' or 'active-directory' powerauth.admin.security.method= # LDAP Security @@ -30,6 +30,12 @@ powerauth.admin.security.ldap.ldif= powerauth.admin.security.ldap.managerDN= powerauth.admin.security.ldap.managerPassword= +# Active Directory Security +powerauth.admin.security.activeDirectory.domain= +powerauth.admin.security.activeDirectory.url= +powerauth.admin.security.activeDirectory.root= +powerauth.admin.security.activeDirectory.userSearchFilter= + # Application Service Configuration powerauth.admin.service.applicationName=powerauth-admin powerauth.admin.service.applicationDisplayName=PowerAuth Admin diff --git a/powerauth-admin/src/main/webapp/WEB-INF/jsp/header.jsp b/powerauth-admin/src/main/webapp/WEB-INF/jsp/header.jsp index 63cfbf0b5..e84dfe5d4 100644 --- a/powerauth-admin/src/main/webapp/WEB-INF/jsp/header.jsp +++ b/powerauth-admin/src/main/webapp/WEB-INF/jsp/header.jsp @@ -44,6 +44,9 @@ + diff --git a/powerauth-admin/src/main/webapp/WEB-INF/jsp/headerSimple.jsp b/powerauth-admin/src/main/webapp/WEB-INF/jsp/headerSimple.jsp index 2e75f7245..779e4087b 100644 --- a/powerauth-admin/src/main/webapp/WEB-INF/jsp/headerSimple.jsp +++ b/powerauth-admin/src/main/webapp/WEB-INF/jsp/headerSimple.jsp @@ -32,6 +32,9 @@ + From cf069e88b7d7197add0b1991836ab46153e98b4a Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Mon, 11 Jul 2022 16:08:19 +0200 Subject: [PATCH 21/58] Fix documentation --- ...ting-Up-Active-Directory-Authentication.md | 38 +++++++++++++++++++ docs/Setting-Up-LDAP-Authentication.md | 6 ++- docs/_Sidebar.md | 1 + 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 docs/Setting-Up-Active-Directory-Authentication.md diff --git a/docs/Setting-Up-Active-Directory-Authentication.md b/docs/Setting-Up-Active-Directory-Authentication.md new file mode 100644 index 000000000..0389727eb --- /dev/null +++ b/docs/Setting-Up-Active-Directory-Authentication.md @@ -0,0 +1,38 @@ +# Setting Up Active Directory Authentication + +PowerAuth Admin supports optional authentication using Active Directory. This option is disabled by default. + + +In case you are using Linux/Unix LDAP implementation, please follow the [separate documentation](./Setting-Up-LDAP-Authentication.md). + + +## Using Custom Active Directory Properties + +In case you already have your own Active Directory server and you would like to use it as an authentication provider for PowerAuth Admin, you can configure all required properties. Namely, these properties are available for configuration: + +```sh +# Enable Active Directory Authentication +powerauth.admin.security.method=active-directory + +# Set Properties +powerauth.admin.security.activeDirectory.domain=wultra.com +powerauth.admin.security.activeDirectory.url=ldap://1.2.3.4:389 +powerauth.admin.security.activeDirectory.root=dc=wultra,dc=com +powerauth.admin.security.activeDirectory.userSearchFilter= +``` + +These properties should be sufficient to configure all parameters required for an Active Directory based authentication. + +## Restricting Authentication to a Groups + +The default value for the `powerauth.admin.security.activeDirectory.userSearchFilter` property is: + +``` +(&(objectClass=user)(userPrincipalName={0})) +``` + +To customize the user lookup query, you can change the property to include custom value (the `{0}` will be replaced by the `username@domain`), for example: + +``` +powerauth.admin.security.activeDirectory.userSearchFilter=(&(objectClass=user)(userPrincipalName={0})(memberOf=CN=MyCustomGroup,CN=Users,DC=wultra,DC=com)) +``` diff --git a/docs/Setting-Up-LDAP-Authentication.md b/docs/Setting-Up-LDAP-Authentication.md index 1565060ac..3f9d45752 100644 --- a/docs/Setting-Up-LDAP-Authentication.md +++ b/docs/Setting-Up-LDAP-Authentication.md @@ -1,6 +1,10 @@ # Setting Up LDAP Authentication -PowerAuth Admin supports optional authentication using the LDAP protocol. This option is disabled by default, but we recommend setting up LDAP based authentication at least for the production environment. +PowerAuth Admin supports optional authentication using the LDAP protocol. This option is disabled by default. In case you are using PowerAuth Admin in a multi-user account, we recommend setting up at least the file-based LDAP authentication. + + +In case you are using Active Directory, please follow the [separate documentation](./Setting-Up-Active-Directory-Authentication.md). + ## Enabling LDAP Authentication diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md index 8ccca8d79..07944aef0 100644 --- a/docs/_Sidebar.md +++ b/docs/_Sidebar.md @@ -26,6 +26,7 @@ - [Deploying PowerAuth Admin](./Deploying-PowerAuth-Admin.md) - [Deploying PowerAuth Admin on JBoss/Wildfly](./Admin-Deploying-Wildfly.md) - [Setting Up LDAP Authentication](./Setting-Up-LDAP-Authentication.md) +- [Setting Up AD Authentication](./Setting-Up-Active-Directory-Authentication.md) - [Configuration of Activation Recovery](./Activation-Recovery.md) - [Configuration Properties](./Configuration-Properties-Admin.md) From 899c687ae306d917423783c6fcee30ca013e6dc4 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Mon, 11 Jul 2022 18:26:12 +0200 Subject: [PATCH 22/58] Fix version of dependency --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a8cc73141..7cce26f2b 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ 3.1.1 - 1.4.0-SNAPSHOT + 1.3.0 1.5.2 1.5.2 1.70 From 88167c6e5d260c60c19c488ce9d497066bddde60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Dvo=C5=99=C3=A1k?= Date: Wed, 27 Jul 2022 08:36:48 +0200 Subject: [PATCH 23/58] Add link to 1.3.x migration guides --- docs/Migration-Instructions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Migration-Instructions.md b/docs/Migration-Instructions.md index 0a6842976..e5b43aefa 100644 --- a/docs/Migration-Instructions.md +++ b/docs/Migration-Instructions.md @@ -6,6 +6,7 @@ This page contains PowerAuth Server migration instructions. When updating across multiple versions, you need to perform all migration steps additively. +- [PowerAuth Server 1.3.0](./PowerAuth-Server-1.3.0.md) - [PowerAuth Server 1.2.5](./PowerAuth-Server-1.2.5.md) - [PowerAuth Server 1.2.0](./PowerAuth-Server-1.2.0.md) - [PowerAuth Server 1.1.0](./PowerAuth-Server-1.1.0.md) From 2ee950cb5724bb0a2e37edb6c1e2c5d44aef737d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Dvo=C5=99=C3=A1k?= Date: Wed, 27 Jul 2022 08:41:54 +0200 Subject: [PATCH 24/58] Update PowerAuth-Server-1.3.0.md --- docs/PowerAuth-Server-1.3.0.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/PowerAuth-Server-1.3.0.md b/docs/PowerAuth-Server-1.3.0.md index 7bd2be47b..389f982dd 100644 --- a/docs/PowerAuth-Server-1.3.0.md +++ b/docs/PowerAuth-Server-1.3.0.md @@ -7,6 +7,18 @@ Migration from release `1.2.x` of PowerAuth server to release `1.3.x` is split i - [Migration from 1.2.x to 1.2.5](./PowerAuth-Server-1.2.5.md) - apply these steps for upgrade to version `1.2.5` - Migration from 1.2.5 to 1.3.x (this document) - apply steps below for upgrade from version `1.2.5` to version `1.3.x` +## Change in Application ID (breaking change) + +In earlier versions of PowerAuth Server, we addressed applications via their numeric (`Long`) database record ID. This proved to be problematic, since the same application had different IDs on different environments. In 1.3.x and further, we now address applications via ID equal to their string name (contents of the `name` column in `pa_application` table), and we now call this value "application ID". + + +We highly recommend renaming the application in the database by editing `pa_application.name` column, so that the name is in a technical format, i.e., "mobile-token-retail", rather than in human readable name, such as "Mobile Token For Retail Clients". + + +This change is consistently reflected in all other parts of PowerAuth stack, i.e., in Push Server or Web Flow. + +In case your system needs to store IDs of application, you need to reflect this change. It is no longer possible to access applications using their numeric database record ID. + ## Database Changes ### Relation Between Operations and Applications From be0086effa546835e72a42b90de2a081802b8b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Dvo=C5=99=C3=A1k?= Date: Wed, 27 Jul 2022 08:42:10 +0200 Subject: [PATCH 25/58] Update PowerAuth-Server-1.3.0.md --- docs/PowerAuth-Server-1.3.0.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/PowerAuth-Server-1.3.0.md b/docs/PowerAuth-Server-1.3.0.md index 7bd2be47b..389f982dd 100644 --- a/docs/PowerAuth-Server-1.3.0.md +++ b/docs/PowerAuth-Server-1.3.0.md @@ -7,6 +7,18 @@ Migration from release `1.2.x` of PowerAuth server to release `1.3.x` is split i - [Migration from 1.2.x to 1.2.5](./PowerAuth-Server-1.2.5.md) - apply these steps for upgrade to version `1.2.5` - Migration from 1.2.5 to 1.3.x (this document) - apply steps below for upgrade from version `1.2.5` to version `1.3.x` +## Change in Application ID (breaking change) + +In earlier versions of PowerAuth Server, we addressed applications via their numeric (`Long`) database record ID. This proved to be problematic, since the same application had different IDs on different environments. In 1.3.x and further, we now address applications via ID equal to their string name (contents of the `name` column in `pa_application` table), and we now call this value "application ID". + + +We highly recommend renaming the application in the database by editing `pa_application.name` column, so that the name is in a technical format, i.e., "mobile-token-retail", rather than in human readable name, such as "Mobile Token For Retail Clients". + + +This change is consistently reflected in all other parts of PowerAuth stack, i.e., in Push Server or Web Flow. + +In case your system needs to store IDs of application, you need to reflect this change. It is no longer possible to access applications using their numeric database record ID. + ## Database Changes ### Relation Between Operations and Applications From 9753aa3a6865c88543d8c7780b716fac6be8f69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Dvo=C5=99=C3=A1k?= Date: Wed, 27 Jul 2022 09:46:55 +0200 Subject: [PATCH 26/58] Update PowerAuth-Server-1.3.0.md --- docs/PowerAuth-Server-1.3.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/PowerAuth-Server-1.3.0.md b/docs/PowerAuth-Server-1.3.0.md index 389f982dd..8b89356c5 100644 --- a/docs/PowerAuth-Server-1.3.0.md +++ b/docs/PowerAuth-Server-1.3.0.md @@ -11,7 +11,7 @@ Migration from release `1.2.x` of PowerAuth server to release `1.3.x` is split i In earlier versions of PowerAuth Server, we addressed applications via their numeric (`Long`) database record ID. This proved to be problematic, since the same application had different IDs on different environments. In 1.3.x and further, we now address applications via ID equal to their string name (contents of the `name` column in `pa_application` table), and we now call this value "application ID". - + We highly recommend renaming the application in the database by editing `pa_application.name` column, so that the name is in a technical format, i.e., "mobile-token-retail", rather than in human readable name, such as "Mobile Token For Retail Clients". From 8cc89fe8351176662dd89168256ab11f284e6738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Dvo=C5=99=C3=A1k?= Date: Wed, 27 Jul 2022 09:47:10 +0200 Subject: [PATCH 27/58] Update PowerAuth-Server-1.3.0.md --- docs/PowerAuth-Server-1.3.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/PowerAuth-Server-1.3.0.md b/docs/PowerAuth-Server-1.3.0.md index 389f982dd..8b89356c5 100644 --- a/docs/PowerAuth-Server-1.3.0.md +++ b/docs/PowerAuth-Server-1.3.0.md @@ -11,7 +11,7 @@ Migration from release `1.2.x` of PowerAuth server to release `1.3.x` is split i In earlier versions of PowerAuth Server, we addressed applications via their numeric (`Long`) database record ID. This proved to be problematic, since the same application had different IDs on different environments. In 1.3.x and further, we now address applications via ID equal to their string name (contents of the `name` column in `pa_application` table), and we now call this value "application ID". - + We highly recommend renaming the application in the database by editing `pa_application.name` column, so that the name is in a technical format, i.e., "mobile-token-retail", rather than in human readable name, such as "Mobile Token For Retail Clients". From a72f0e03aa73b1730801d77ab25b39e4fe1d39bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20=C4=8Cern=C3=BD?= Date: Sun, 16 Oct 2022 20:47:19 +0200 Subject: [PATCH 28/58] Test/ci (#763) * add GitHub Action builds part of wultra/tasklist#23 --- .github/workflows/maven-deploy.yml | 50 +++++++++++++++++++++ .github/workflows/maven-test.yml | 19 ++++++++ pom.xml | 70 +++++++++++++++++++++++++----- powerauth-admin/pom.xml | 28 +++++++++--- powerauth-java-server/pom.xml | 29 +++++++++---- 5 files changed, 171 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/maven-deploy.yml create mode 100644 .github/workflows/maven-test.yml diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/maven-deploy.yml new file mode 100644 index 000000000..735ff4c85 --- /dev/null +++ b/.github/workflows/maven-deploy.yml @@ -0,0 +1,50 @@ +name: Deploy with Maven + +on: + workflow_dispatch: + branches: + - 'develop' + - 'master' + - 'releases/*' + - 'test/ci' + inputs: + release_type: + type: choice + description: + default: snapshot + options: + - snapshot + - release + environment: + type: environment + default: internal-publish + description: internal or external repository + push: + branches: + - 'develop' + - 'test/ci' + + + +jobs: + maven-deploy-internal: + if: ${{ github.event_name == 'push' }} + name: Deploy to ${{ inputs.environment }} + uses: wultra/wultra-infrastructure/.github/workflows/maven-deploy.yml@develop + with: + environment: internal-publish + release_type: snapshot + secrets: + username: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + password: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + + maven-deploy-public: + if: ${{ github.event_name == 'workflow_dispatch' }} + name: Deploy to ${{ inputs.environment }} + uses: wultra/wultra-infrastructure/.github/workflows/maven-deploy.yml@develop + with: + environment: ${{ inputs.environment }} + release_type: ${{ inputs.release_type }} + secrets: + username: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + password: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} diff --git a/.github/workflows/maven-test.yml b/.github/workflows/maven-test.yml new file mode 100644 index 000000000..5f4e4c134 --- /dev/null +++ b/.github/workflows/maven-test.yml @@ -0,0 +1,19 @@ +name: Test with Maven + +on: + workflow_dispatch: + push: + branches: + - 'develop' + - 'master' + - 'releases/**' + - 'test/ci' + pull_request: + branches: + - 'develop' + - 'master' + - 'releases/**' + +jobs: + maven-tests: + uses: wultra/wultra-infrastructure/.github/workflows/maven-test.yml@develop \ No newline at end of file diff --git a/pom.xml b/pom.xml index a578c6452..79792f9b1 100644 --- a/pom.xml +++ b/pom.xml @@ -204,6 +204,66 @@ + + internal-repository + + + useInternalRepo + true + + + + + + + jfrog-central + Wultra Artifactory-releases + https://wultra.jfrog.io/artifactory/internal-maven-repository + + + jfrog-central + Wultra Artifactory-snapshots + https://wultra.jfrog.io/artifactory/internal-maven-repository + + + + + jfrog-central + Wultra Artifactory-releases + https://wultra.jfrog.io/artifactory/internal-maven-repository + + + ossrh-snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + false + + + true + + + + + + public-repository + + + !useInternalRepo + + + + + + + ossrh-snapshots-distribution + https://oss.sonatype.org/content/repositories/snapshots/ + + + ossrh-staging-distribution + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + @@ -219,15 +279,5 @@ - - - ossrh-snapshots-distribution - https://oss.sonatype.org/content/repositories/snapshots/ - - - ossrh-staging-distribution - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - diff --git a/powerauth-admin/pom.xml b/powerauth-admin/pom.xml index dada86fb3..148ef4b3a 100644 --- a/powerauth-admin/pom.xml +++ b/powerauth-admin/pom.xml @@ -135,6 +135,27 @@ + + test-repository + + + !useInternalRepo + + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + @@ -151,13 +172,6 @@ - - org.apache.maven.plugins - maven-deploy-plugin - - true - - diff --git a/powerauth-java-server/pom.xml b/powerauth-java-server/pom.xml index 8218722f2..be19cd14c 100644 --- a/powerauth-java-server/pom.xml +++ b/powerauth-java-server/pom.xml @@ -238,14 +238,6 @@ - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - @@ -259,6 +251,27 @@ + + test-repository + + + !useInternalRepo + + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + From f7c9ca2f331ecad47f5d5c5d897d6f483e0c781b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0trobl?= Date: Thu, 20 Oct 2022 14:29:39 +0200 Subject: [PATCH 29/58] Fix #764: Return activation status in ValidateTokenResponse (#765) --- docs/PowerAuth-Server-1.4.0.md | 32 +++++++++++++++ .../behavior/tasks/v3/TokenBehavior.java | 39 +++++++++---------- .../src/main/resources/xsd/PowerAuth-3.0.xsd | 2 + 3 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 docs/PowerAuth-Server-1.4.0.md diff --git a/docs/PowerAuth-Server-1.4.0.md b/docs/PowerAuth-Server-1.4.0.md new file mode 100644 index 000000000..5596d68b7 --- /dev/null +++ b/docs/PowerAuth-Server-1.4.0.md @@ -0,0 +1,32 @@ +# Migration from 1.3.x to 1.4.0 + +This guide contains instructions for migration from PowerAuth Server version `1.3.x` to version `1.4.0`. + +## Change in PowerAuth Token Verification + +In earlier versions of PowerAuth Server, the token verification endpoint `/rest/v3/token/validate` returned an error in case the activation used by the token was not active. In order to always return activation status as part of the response, we changed the endpoint behaviour and removed the error handling for inactive activations. This change unifies the business logic with signature verification endpoint. + +Before change: + +```java +try { + final ValidateTokenResponse response = powerauthClient.validateToken(request); + // regular business logic +} catch (PowerAuthClientException ex) { + // error handling for inactive activation and all other errors +} +``` + +After change: +```java +try { + final ValidateTokenResponse response = powerauthClient.validateToken(request); + if (response.getActivationStatus() != ActivationStatus.ACTIVE) { + // error handling for inactive activations + } +} catch (PowerAuthClientException ex) { + // error handling for all other errors +} +``` + +Adaptation to this change is required only in case this endpoint is called directly on PowerAuth server. In case you use the `@PowerAuthToken` annotation for token validation, no changes are required. diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/TokenBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/TokenBehavior.java index 52259ce72..eb29930c3 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/TokenBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/TokenBehavior.java @@ -22,6 +22,7 @@ import com.google.common.io.BaseEncoding; import com.wultra.security.powerauth.client.v3.*; import io.getlime.security.powerauth.app.server.configuration.PowerAuthServiceConfiguration; +import io.getlime.security.powerauth.app.server.converter.v3.ActivationStatusConverter; import io.getlime.security.powerauth.app.server.converter.v3.ServerPrivateKeyConverter; import io.getlime.security.powerauth.app.server.converter.v3.SignatureTypeConverter; import io.getlime.security.powerauth.app.server.database.RepositoryCatalogue; @@ -82,6 +83,7 @@ public class TokenBehavior { // Helper classes private final SignatureTypeConverter signatureTypeConverter = new SignatureTypeConverter(); + private final ActivationStatusConverter activationStatusConverter = new ActivationStatusConverter(); private final ObjectMapper objectMapper; @@ -274,31 +276,26 @@ public ValidateTokenResponse validateToken(ValidateTokenRequest request) throws // Check if the activation is in correct state final ActivationRecordEntity activation = token.getActivation(); + final byte[] tokenSecret = BaseEncoding.base64().decode(token.getTokenSecret()); + final boolean isTokenValid; if (!ActivationStatus.ACTIVE.equals(activation.getActivationStatus())) { logger.info("Activation is not ACTIVE, activation ID: {}", activation.getActivationId()); - // Rollback is not required, database is not used for writing - throw localizationProvider.buildExceptionForCode(ServiceError.ACTIVATION_INCORRECT_STATE); - } - - final byte[] tokenSecret = BaseEncoding.base64().decode(token.getTokenSecret()); - - final boolean isTokenValid = tokenVerifier.validateTokenDigest(nonce, timestamp, tokenSecret, tokenDigest); - - if (isTokenValid) { - final ValidateTokenResponse response = new ValidateTokenResponse(); - response.setTokenValid(true); - response.setActivationId(activation.getActivationId()); - response.setApplicationId(activation.getApplication().getId()); - response.getApplicationRoles().addAll(activation.getApplication().getRoles()); - response.getActivationFlags().addAll(activation.getFlags()); - response.setUserId(activation.getUserId()); - response.setSignatureType(signatureTypeConverter.convertFrom(token.getSignatureTypeCreated())); - return response; + isTokenValid = false; } else { - final ValidateTokenResponse response = new ValidateTokenResponse(); - response.setTokenValid(false); - return response; + isTokenValid = tokenVerifier.validateTokenDigest(nonce, timestamp, tokenSecret, tokenDigest); } + + final ValidateTokenResponse response = new ValidateTokenResponse(); + response.setTokenValid(isTokenValid); + response.setActivationStatus(activationStatusConverter.convert(activation.getActivationStatus())); + response.setBlockedReason(activation.getBlockedReason()); + response.setActivationId(activation.getActivationId()); + response.setApplicationId(activation.getApplication().getId()); + response.getApplicationRoles().addAll(activation.getApplication().getRoles()); + response.getActivationFlags().addAll(activation.getFlags()); + response.setUserId(activation.getUserId()); + response.setSignatureType(signatureTypeConverter.convertFrom(token.getSignatureTypeCreated())); + return response; } catch (GenericCryptoException ex) { logger.error(ex.getMessage(), ex); // Rollback is not required, database is not used for writing diff --git a/powerauth-java-server/src/main/resources/xsd/PowerAuth-3.0.xsd b/powerauth-java-server/src/main/resources/xsd/PowerAuth-3.0.xsd index 0adb02fef..bac77ab76 100644 --- a/powerauth-java-server/src/main/resources/xsd/PowerAuth-3.0.xsd +++ b/powerauth-java-server/src/main/resources/xsd/PowerAuth-3.0.xsd @@ -1237,6 +1237,8 @@ + + From 471dbde33eb19034f8cffd442f73254cafb2b531 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Fri, 28 Oct 2022 17:01:58 +0200 Subject: [PATCH 30/58] Fix #767: Update commons-text dependency --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 79792f9b1..7a1bd70e7 100644 --- a/pom.xml +++ b/pom.xml @@ -120,7 +120,7 @@ 2.13.3 - 1.9 + 1.10.0 From fdd8748aff5d1d7a596ec8e38d1dc8fe812222c7 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Thu, 3 Nov 2022 10:29:46 +0100 Subject: [PATCH 31/58] Fix #769: Document how to turn off version display in error page for Tomcat --- docs/Deploying-PowerAuth-Server.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/Deploying-PowerAuth-Server.md b/docs/Deploying-PowerAuth-Server.md index c107f4c79..8c427f55b 100644 --- a/docs/Deploying-PowerAuth-Server.md +++ b/docs/Deploying-PowerAuth-Server.md @@ -258,3 +258,12 @@ Follow the extra instructions in chapter [Deploying PowerAuth Server on JBoss / PowerAuth Server uses Bouncy Castle as a Java cryptography provider. If you encounter any issues that may point to an incorrectly installed cryptography provider, please follow our tutorial [how to configure Bouncy Castle](./Installing-Bouncy-Castle.md). +### How to Disable Display of Tomcat Version + +It case you do not want to show Tomcat version on error pages when deploying PowerAuth server, you can use the following configuration: + +- Edit the file `/conf/server.xml`. +- Search for the parameters ``. +- Just below that line, insert the following parameters ``. +- Restart Tomcat. + From b6b61ac2bae9db5c54196f631a5162bcd0f5fbed Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 14 Nov 2022 20:26:49 +0100 Subject: [PATCH 32/58] Fix #771: Property [id] not found on type --- powerauth-admin/src/main/webapp/WEB-INF/jsp/activations.jsp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/powerauth-admin/src/main/webapp/WEB-INF/jsp/activations.jsp b/powerauth-admin/src/main/webapp/WEB-INF/jsp/activations.jsp index 500a4f7dc..4c004a102 100644 --- a/powerauth-admin/src/main/webapp/WEB-INF/jsp/activations.jsp +++ b/powerauth-admin/src/main/webapp/WEB-INF/jsp/activations.jsp @@ -194,8 +194,8 @@ - - + + From 2ebab97873de0033c25f1151b312b9f6d3edbeee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Lukovsk=C3=BD?= <937429+saalistaja@users.noreply.github.com> Date: Tue, 22 Nov 2022 08:35:08 +0100 Subject: [PATCH 33/58] Resolve #773: Check potentially existing shared tables during schema init (#774) --- docs/sql/mysql/create_schema.sql | 16 ++++---- docs/sql/oracle/create_schema.sql | 57 ++++++++++++++++++++------- docs/sql/postgresql/create_schema.sql | 18 ++++----- 3 files changed, 60 insertions(+), 31 deletions(-) diff --git a/docs/sql/mysql/create_schema.sql b/docs/sql/mysql/create_schema.sql index 26eb07257..665a4af3c 100644 --- a/docs/sql/mysql/create_schema.sql +++ b/docs/sql/mysql/create_schema.sql @@ -256,7 +256,7 @@ CREATE TABLE pa_operation_application ( -- -- DDL for Table SHEDLOCK -- -CREATE TABLE shedlock ( +CREATE TABLE IF NOT EXISTS shedlock ( name VARCHAR(64) NOT NULL, lock_until TIMESTAMP(3) NOT NULL, locked_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), @@ -330,11 +330,11 @@ CREATE UNIQUE INDEX `pa_application_name` ON `pa_application`(`name`); -- -- Auditing indexes. -- -CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); -CREATE INDEX audit_log_application ON audit_log (application_name); -CREATE INDEX audit_log_level ON audit_log (audit_level); -CREATE INDEX audit_log_type ON audit_log (audit_type); -CREATE INDEX audit_param_log ON audit_param (audit_log_id); -CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); -CREATE INDEX audit_param_key ON audit_param (param_key); +CREATE INDEX IF NOT EXISTS audit_log_timestamp ON audit_log (timestamp_created); +CREATE INDEX IF NOT EXISTS audit_log_application ON audit_log (application_name); +CREATE INDEX IF NOT EXISTS audit_log_level ON audit_log (audit_level); +CREATE INDEX IF NOT EXISTS audit_log_type ON audit_log (audit_type); +CREATE INDEX IF NOT EXISTS audit_param_log ON audit_param (audit_log_id); +CREATE INDEX IF NOT EXISTS audit_param_timestamp ON audit_param (timestamp_created); +CREATE INDEX IF NOT EXISTS audit_param_key ON audit_param (param_key); CREATE FULLTEXT INDEX audit_param_value ON audit_param (param_value); \ No newline at end of file diff --git a/docs/sql/oracle/create_schema.sql b/docs/sql/oracle/create_schema.sql index f0caa0e93..8fe3d2adf 100755 --- a/docs/sql/oracle/create_schema.sql +++ b/docs/sql/oracle/create_schema.sql @@ -250,17 +250,19 @@ CREATE TABLE pa_operation_application ( -- -- DDL for Table SHEDLOCK -- -CREATE TABLE shedlock ( +BEGIN EXECUTE IMMEDIATE 'CREATE TABLE shedlock ( name VARCHAR(64) NOT NULL PRIMARY KEY, lock_until TIMESTAMP(3) NOT NULL, locked_at TIMESTAMP(3) NOT NULL, locked_by VARCHAR(255) NOT NULL -); +)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ -- -- Create audit log table. -- -CREATE TABLE audit_log ( +BEGIN EXECUTE IMMEDIATE 'CREATE TABLE audit_log ( audit_log_id VARCHAR2(36 CHAR) PRIMARY KEY, application_name VARCHAR2(256 CHAR) NOT NULL, audit_level VARCHAR2(32 CHAR) NOT NULL, @@ -274,17 +276,21 @@ CREATE TABLE audit_log ( thread_name VARCHAR2(256 CHAR) NOT NULL, version VARCHAR2(256 CHAR), build_time TIMESTAMP -); +)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ -- -- Create audit parameters table. -- -CREATE TABLE audit_param ( +BEGIN EXECUTE IMMEDIATE 'CREATE TABLE audit_param ( audit_log_id VARCHAR2(36 CHAR), timestamp_created TIMESTAMP, param_key VARCHAR2(256 CHAR), param_value VARCHAR2(4000 CHAR) -); +)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ -- -- Ref Constraints for Table PA_ACTIVATION @@ -398,11 +404,34 @@ CREATE INDEX PA_OPERATION_TEMPLATE_NAME_IDX ON PA_OPERATION_TEMPLATE(TEMPLATE_NA -- -- Auditing indexes. -- -CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); -CREATE INDEX audit_log_application ON audit_log (application_name); -CREATE INDEX audit_log_level ON audit_log (audit_level); -CREATE INDEX audit_log_type ON audit_log (audit_type); -CREATE INDEX audit_param_log ON audit_param (audit_log_id); -CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); -CREATE INDEX audit_param_key ON audit_param (param_key); -CREATE INDEX audit_param_value ON audit_param (param_value); \ No newline at end of file +BEGIN EXECUTE IMMEDIATE 'CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ + +BEGIN EXECUTE IMMEDIATE 'CREATE INDEX audit_log_application ON audit_log (application_name)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ + +BEGIN EXECUTE IMMEDIATE 'CREATE INDEX audit_log_level ON audit_log (audit_level)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ + +BEGIN EXECUTE IMMEDIATE 'CREATE INDEX audit_log_type ON audit_log (audit_type)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ + +BEGIN EXECUTE IMMEDIATE 'CREATE INDEX audit_param_log ON audit_param (audit_log_id)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ + +BEGIN EXECUTE IMMEDIATE 'CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ + +BEGIN EXECUTE IMMEDIATE 'CREATE INDEX audit_param_key ON audit_param (param_key)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ + +BEGIN EXECUTE IMMEDIATE 'CREATE INDEX audit_param_value ON audit_param (param_value)'; +EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF; END; +/ diff --git a/docs/sql/postgresql/create_schema.sql b/docs/sql/postgresql/create_schema.sql index 32a6b1dcd..2095c8a68 100644 --- a/docs/sql/postgresql/create_schema.sql +++ b/docs/sql/postgresql/create_schema.sql @@ -251,7 +251,7 @@ CREATE TABLE pa_operation_application ( -- -- DDL for Table SHEDLOCK -- -CREATE TABLE shedlock ( +CREATE TABLE IF NOT EXISTS shedlock ( name VARCHAR(64) NOT NULL PRIMARY KEY, lock_until TIMESTAMP NOT NULL, locked_at TIMESTAMP NOT NULL, @@ -399,11 +399,11 @@ CREATE INDEX pa_operation_template_name_idx ON pa_operation_template(template_na -- -- Auditing indexes. -- -CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created); -CREATE INDEX audit_log_application ON audit_log (application_name); -CREATE INDEX audit_log_level ON audit_log (audit_level); -CREATE INDEX audit_log_type ON audit_log (audit_type); -CREATE INDEX audit_param_log ON audit_param (audit_log_id); -CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created); -CREATE INDEX audit_param_key ON audit_param (param_key); -CREATE INDEX audit_param_value ON audit_param (param_value); +CREATE INDEX IF NOT EXISTS audit_log_timestamp ON audit_log (timestamp_created); +CREATE INDEX IF NOT EXISTS audit_log_application ON audit_log (application_name); +CREATE INDEX IF NOT EXISTS audit_log_level ON audit_log (audit_level); +CREATE INDEX IF NOT EXISTS audit_log_type ON audit_log (audit_type); +CREATE INDEX IF NOT EXISTS audit_param_log ON audit_param (audit_log_id); +CREATE INDEX IF NOT EXISTS audit_param_timestamp ON audit_param (timestamp_created); +CREATE INDEX IF NOT EXISTS audit_param_key ON audit_param (param_key); +CREATE INDEX IF NOT EXISTS audit_param_value ON audit_param (param_value); From 840162b71536476157cf4fcc77a918d06fa6d1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Tue, 29 Nov 2022 16:00:34 +0100 Subject: [PATCH 34/58] Fix #776: Exclude tomcat-embed-el dependency (#777) --- pom.xml | 23 +++++++++++++++++++++++ powerauth-admin/pom.xml | 4 ++++ powerauth-java-server/pom.xml | 6 ++++++ 3 files changed, 33 insertions(+) diff --git a/pom.xml b/pom.xml index 7a1bd70e7..e429e9535 100644 --- a/pom.xml +++ b/pom.xml @@ -175,6 +175,29 @@ maven-deploy-plugin ${maven-deploy-plugin.version} + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.1.0 + + + enforce-banned-dependencies + + enforce + + + + + + org.apache.tomcat.embed:tomcat-embed-el:*:*:compile + + + + + + + diff --git a/powerauth-admin/pom.xml b/powerauth-admin/pom.xml index 148ef4b3a..b4edbfd4a 100644 --- a/powerauth-admin/pom.xml +++ b/powerauth-admin/pom.xml @@ -27,6 +27,10 @@ log4j-to-slf4j org.apache.logging.log4j + + org.apache.tomcat.embed + tomcat-embed-el + diff --git a/powerauth-java-server/pom.xml b/powerauth-java-server/pom.xml index be19cd14c..8aa8afc8c 100644 --- a/powerauth-java-server/pom.xml +++ b/powerauth-java-server/pom.xml @@ -88,6 +88,12 @@ org.springframework.boot spring-boot-starter-validation + + + org.apache.tomcat.embed + tomcat-embed-el + + org.springframework.boot From 9cb84c0c72b327cd7004fe2af8aa9c8ea0befe1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Wed, 30 Nov 2022 14:35:48 +0100 Subject: [PATCH 35/58] Fix #778: Exclude tomcat.embed compile dependency (#779) --- pom.xml | 2 +- powerauth-admin/pom.xml | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index e429e9535..f31b1fb4a 100644 --- a/pom.xml +++ b/pom.xml @@ -190,7 +190,7 @@ - org.apache.tomcat.embed:tomcat-embed-el:*:*:compile + org.apache.tomcat.embed:*:*:*:compile diff --git a/powerauth-admin/pom.xml b/powerauth-admin/pom.xml index b4edbfd4a..2c4798405 100644 --- a/powerauth-admin/pom.xml +++ b/powerauth-admin/pom.xml @@ -27,10 +27,6 @@ log4j-to-slf4j org.apache.logging.log4j - - org.apache.tomcat.embed - tomcat-embed-el - @@ -41,6 +37,11 @@ org.springframework.boot spring-boot-starter-actuator + + org.springframework.boot + spring-boot-starter-tomcat + provided + From e54e4bf132f9dfdc9a34a9163c3f759dc4bf56f0 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Thu, 1 Dec 2022 13:43:13 +0100 Subject: [PATCH 36/58] Fix #780: Add schema configuration for shedlock --- lombok.config | 1 + .../ScheduledJobConfiguration.java | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 lombok.config diff --git a/lombok.config b/lombok.config new file mode 100644 index 000000000..2bb794fd6 --- /dev/null +++ b/lombok.config @@ -0,0 +1 @@ +lombok.log.fieldName=logger diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/ScheduledJobConfiguration.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/ScheduledJobConfiguration.java index ad0f521b2..ef067f2c5 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/ScheduledJobConfiguration.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/ScheduledJobConfiguration.java @@ -17,8 +17,11 @@ */ package io.getlime.security.powerauth.app.server.configuration; +import lombok.extern.slf4j.Slf4j; import net.javacrumbs.shedlock.core.LockProvider; import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; @@ -31,16 +34,26 @@ * @author Petr Dvorak, petr@wultra.com */ @Configuration +@Slf4j public class ScheduledJobConfiguration { + @Value("${spring.jpa.properties.hibernate.default_schema:}") + private String defaultSchema; + + private static final String SHEDLOCK_TABLE_NAME = "shedlock"; + @Bean public LockProvider lockProvider(DataSource dataSource) { + final String tableName = StringUtils.isBlank(defaultSchema) + ? SHEDLOCK_TABLE_NAME + : defaultSchema + "." + SHEDLOCK_TABLE_NAME; + logger.info("Following database table will be used by shedlock: {}", tableName); return new JdbcTemplateLockProvider( JdbcTemplateLockProvider.Configuration.builder() .withJdbcTemplate(new JdbcTemplate(dataSource)) + .withTableName(tableName) .usingDbTime() - .build() - ); + .build()); } } From a821882420918bb3a4679d37f19e99701c644b89 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Thu, 1 Dec 2022 15:46:44 +0100 Subject: [PATCH 37/58] Fix #782: Update java core dependencies --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f31b1fb4a..33b711e1a 100644 --- a/pom.xml +++ b/pom.xml @@ -95,8 +95,8 @@ 1.4.0-SNAPSHOT - 1.5.2 - 1.5.2 + 1.6.0-SNAPSHOT + 1.6.0-SNAPSHOT 1.70 From 2ea0d4578186e696ec3dcaddc7826e2625edbfd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Mon, 12 Dec 2022 07:12:34 +0100 Subject: [PATCH 38/58] Fix #786: Update to Spring Boot 2.6.14 (#787) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 33b711e1a..83258b2c9 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ org.springframework.boot spring-boot-starter-parent - 2.6.8 + 2.6.14 From 2e5a21fe2d627ed683c75a802fd79f35a9587f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Mon, 12 Dec 2022 07:16:04 +0100 Subject: [PATCH 39/58] Fix #789: Clean up maven configuration (#790) --- pom.xml | 17 +++++++++++++++++ powerauth-admin/pom.xml | 3 --- powerauth-client-model/pom.xml | 2 -- powerauth-java-server/pom.xml | 3 --- powerauth-rest-client-spring/pom.xml | 3 --- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 83258b2c9..4c7efd4de 100644 --- a/pom.xml +++ b/pom.xml @@ -124,6 +124,23 @@ + + + + + io.getlime.security + powerauth-client-model + ${project.version} + + + + io.getlime.security + powerauth-rest-client-spring + ${project.version} + + + + diff --git a/powerauth-admin/pom.xml b/powerauth-admin/pom.xml index 2c4798405..a7a23c4ca 100644 --- a/powerauth-admin/pom.xml +++ b/powerauth-admin/pom.xml @@ -6,14 +6,12 @@ powerauth-admin PowerAuth Server Admin Console powerauth-admin - 1.4.0-SNAPSHOT war io.getlime.security powerauth-server-parent 1.4.0-SNAPSHOT - ../pom.xml @@ -61,7 +59,6 @@ io.getlime.security powerauth-rest-client-spring - 1.4.0-SNAPSHOT diff --git a/powerauth-client-model/pom.xml b/powerauth-client-model/pom.xml index b79ad87da..e9e25fa62 100644 --- a/powerauth-client-model/pom.xml +++ b/powerauth-client-model/pom.xml @@ -22,7 +22,6 @@ 4.0.0 powerauth-client-model - 1.4.0-SNAPSHOT powerauth-client-model PowerAuth Server Client Model @@ -30,7 +29,6 @@ io.getlime.security powerauth-server-parent 1.4.0-SNAPSHOT - ../pom.xml diff --git a/powerauth-java-server/pom.xml b/powerauth-java-server/pom.xml index 8aa8afc8c..561445e07 100644 --- a/powerauth-java-server/pom.xml +++ b/powerauth-java-server/pom.xml @@ -24,14 +24,12 @@ powerauth-java-server PowerAuth Server powerauth-java-server - 1.4.0-SNAPSHOT war io.getlime.security powerauth-server-parent 1.4.0-SNAPSHOT - ../pom.xml @@ -118,7 +116,6 @@ io.getlime.security powerauth-client-model - 1.4.0-SNAPSHOT io.getlime.security diff --git a/powerauth-rest-client-spring/pom.xml b/powerauth-rest-client-spring/pom.xml index dd13e3845..8068c1716 100644 --- a/powerauth-rest-client-spring/pom.xml +++ b/powerauth-rest-client-spring/pom.xml @@ -22,7 +22,6 @@ 4.0.0 powerauth-rest-client-spring - 1.4.0-SNAPSHOT powerauth-rest-client-spring PowerAuth Server REST Service Client @@ -30,7 +29,6 @@ io.getlime.security powerauth-server-parent 1.4.0-SNAPSHOT - ../pom.xml @@ -38,7 +36,6 @@ io.getlime.security powerauth-client-model - 1.4.0-SNAPSHOT io.getlime.core From a610dff62a0858da57026799df8c8608e57d7800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20=C4=8Cern=C3=BD?= Date: Mon, 12 Dec 2022 19:53:28 +0100 Subject: [PATCH 40/58] workflow for Coverity scan --- .github/workflows/coverity-scan.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/coverity-scan.yml diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml new file mode 100644 index 000000000..8a887f339 --- /dev/null +++ b/.github/workflows/coverity-scan.yml @@ -0,0 +1,16 @@ +name: Run Coverity scan and upload results + +on: + workflow_dispatch: + schedule: + - cron: '0 10 1 * *' # monthly + + +jobs: + coverity-scan: + uses: wultra/wultra-infrastructure/.github/workflows/coverity-scan.yml@develop + secrets: inherit + with: + project-name: ${{ github.event.repository.name }} + version: ${{ github.sha }} + description: ${{ github.ref }} From 1c4d8b6d3a6f26b129e76ca059c8ef19021b3295 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Wed, 14 Dec 2022 08:27:01 +0100 Subject: [PATCH 41/58] Remove travis configuration --- .travis.yml | 23 ----------------------- README.md | 2 +- 2 files changed, 1 insertion(+), 24 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b4831bf4f..000000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: java -jdk: - - openjdk11 -branches: - only: - - master - - coverity_scan -env: - global: - - secure: "t7YtG0/8BDsI8hfb4430jOXQy4n5lwFaxz2o8tTk9c+QisNqAUvUkWabk8XkuBJMb7OwHwEC40s729oFYu9AD1Ul+M/BiyRQXm+tBoZvQESQqRrRlcJfYFbuKVcA4XBIeI1F+j+QUaKdzFYsPDOR3aOtK9wN+UtSHn9Dtq2Up++aifF8S7+GIsW6aJ1Y4oWPbkTPzAVfJ2UP5euv9EsWGYGIueJ0aryoi8J/lCnEU5dsMVooa9S8gGaByeEdF+lRvNiNzli5nuRiYXISFtFC9Ge/TaO3BFHa5HUJ8CLtNfZX9PCLgr78BmRo5iAI45ri8RwtEDeV7HJAXr76UCAxQa0K537LtV4uvJRCWTDg6fY6kAfE1CuYAKOzX6CffeHmakuBsgh0nI1OFjwj2nsPCw7wsYC6uWDlbTge9Hq/smQWQxnUaLKxVWollrsB/N5sxcLbemJSy59O56CWQV97oLN+0et+FBG10I3Xkcy++oz96ZdsX6Vo3VTfLeQXk1u4Irvw8gssJZW/Jv7R6IEwTD73gNl382UuDHUyPPZg59iaJ/GzkqKtba0oKBDzddR2z9F8NswF2s9dpYhsp37bvjYlphdoyjj6SBk7f7qehKSvw3hMCS1Nb91b1HWPWzKMko08HGzqnS1ViyE+ElEPvHk0HUWGETJBPGFH3JqCbNo=" - -before_install: - - echo -n | openssl s_client -connect https://scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- - -addons: - coverity_scan: - project: - name: "wultra/powerauth-server" - description: "Build submitted via Travis CI" - notification_email: roman.strobl@wultra.com - build_command_prepend: "mvn clean" - build_command: "mvn -DskipTests=true compile" - branch_pattern: coverity_scan \ No newline at end of file diff --git a/README.md b/README.md index 948362da0..4f2dbdeb4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # PowerAuth Server -[![Build Status](https://travis-ci.org/wultra/powerauth-server.svg?branch=master)](https://travis-ci.org/wultra/powerauth-server) +[![Build Status](https://github.com/wultra/powerauth-server/actions/workflows/maven-test.yml/badge.svg?branch=master)](https://github.com/wultra/powerauth-server/actions/workflows/maven-test.yml?query=branch%3Amaster) [![Status](https://scan.coverity.com/projects/16632/badge.svg)](https://scan.coverity.com/projects/wultra-powerauth-server) [![GitHub issues](https://img.shields.io/github/issues/wultra/powerauth-server.svg?maxAge=2592000)](https://github.com/wultra/powerauth-server/issues) [![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) From 765409b5bc90333e00f6358cde9a8b6ac151bf90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Wed, 14 Dec 2022 14:09:12 +0100 Subject: [PATCH 42/58] Fix #775: Add risk flags to Operation Template (#784) --- docs/Database-Structure.md | 8 +++-- docs/PowerAuth-Server-1.4.0.md | 36 +++++++++++++++++++ docs/WebServices-Methods.md | 15 ++++++++ docs/sql/mysql/create_schema.sql | 2 ++ docs/sql/oracle/create_schema.sql | 6 ++-- docs/sql/postgresql/create_schema.sql | 6 ++-- .../OperationTemplateCreateRequest.java | 10 ++++++ .../OperationTemplateUpdateRequest.java | 10 ++++++ .../response/OperationDetailResponse.java | 9 +++++ .../OperationTemplateDetailResponse.java | 9 +++++ .../v3/OperationTemplateConverter.java | 3 ++ .../model/entity/OperationEntity.java | 27 ++++++++++++-- .../model/entity/OperationTemplateEntity.java | 27 ++++++++++++-- .../tasks/v3/OperationServiceBehavior.java | 3 ++ 14 files changed, 161 insertions(+), 10 deletions(-) diff --git a/docs/Database-Structure.md b/docs/Database-Structure.md index 76124cb7e..264f4d21e 100644 --- a/docs/Database-Structure.md +++ b/docs/Database-Structure.md @@ -492,7 +492,8 @@ CREATE TABLE "pa_operation" ( "max_failure_count" BIGINT NOT NULL, "timestamp_created" TIMESTAMP NOT NULL, "timestamp_expires" TIMESTAMP NOT NULL, - "timestamp_finalized" TIMESTAMP + "timestamp_finalized" TIMESTAMP, + "risk_flags" VARCHAR(255) ); ``` @@ -514,6 +515,7 @@ CREATE TABLE "pa_operation" ( | timestamp_created | timestamp | - | Timestamp of when the operation was created. | | timestamp_expires | timestamp | - | Timestamp of when the operation will expire. | | timestamp_finalized | timestamp | - | Timestamp of when the operation reached the terminal state (approved, rejected, expired, etc.). | +| risk_flages | varchar(255) | - | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | @@ -531,7 +533,8 @@ CREATE TABLE "pa_operation_template" ( "data_template" VARCHAR(255) NOT NULL, "signature_type" VARCHAR(255) NOT NULL, "max_failure_count" BIGINT NOT NULL, - "expiration" BIGINT NOT NULL + "expiration" BIGINT NOT NULL, + "risk_flags" VARCHAR(255) ); ``` @@ -546,6 +549,7 @@ CREATE TABLE "pa_operation_template" ( | signature_type | varchar(255) | - | Comma-separated list of allowed signature types. | | max_failure_count | bigint | - | Maximum allowed number of failed attempts when approving the operation. | | expiration | bigint | - | Operation expiration in seconds (300 = 5 minutes). | +| risk_flages | varchar(255) | - | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | diff --git a/docs/PowerAuth-Server-1.4.0.md b/docs/PowerAuth-Server-1.4.0.md index 5596d68b7..9f7aac232 100644 --- a/docs/PowerAuth-Server-1.4.0.md +++ b/docs/PowerAuth-Server-1.4.0.md @@ -30,3 +30,39 @@ try { ``` Adaptation to this change is required only in case this endpoint is called directly on PowerAuth server. In case you use the `@PowerAuthToken` annotation for token validation, no changes are required. + +## Database Changes + +### Add Risk Flags to Operations and Templates + +Add a column `risk_flags` to the templates and operations. + +#### PostgreSQL + +```sql +ALTER TABLE pa_operation + ADD COLUMN risk_flags VARCHAR(255); + +ALTER TABLE pa_operation_template + ADD COLUMN risk_flags VARCHAR(255); +``` + +#### Oracle + +```sql +ALTER TABLE pa_operation + ADD risk_flags VARCHAR2(255 CHAR); + +ALTER TABLE pa_operation_template + ADD risk_flags VARCHAR2(255 CHAR); +``` + +#### MySQL + +```sql +ALTER TABLE pa_operation + ADD COLUMN risk_flags varchar(255); + +ALTER TABLE pa_operation_template + ADD COLUMN risk_flags varchar(255); +``` diff --git a/docs/WebServices-Methods.md b/docs/WebServices-Methods.md index 588ca781f..34d068bed 100644 --- a/docs/WebServices-Methods.md +++ b/docs/WebServices-Methods.md @@ -1994,6 +1994,7 @@ REST endpoint: `POST /rest/v3/operation/create` | `Date` | `timestampCreated` | Timestamp of when the operation was created | | `Date` | `timestampExpires` | Timestamp of when the operation will expires / expired | | `Date` | `timestampFinalized` | Timestamp of when the operation was switched to a terminating status | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'operationDetail' @@ -2029,6 +2030,7 @@ REST endpoint: `POST /rest/v3/operation/detail` | `Date` | `timestampCreated` | Timestamp of when the operation was created | | `Date` | `timestampExpires` | Timestamp of when the operation will expires / expired | | `Date` | `timestampFinalized` | Timestamp of when the operation was switched to a terminating status | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'findPendingOperationsForUser' @@ -2068,6 +2070,7 @@ A collection of records with the following structure: | `Date` | `timestampCreated` | Timestamp of when the operation was created | | `Date` | `timestampExpires` | Timestamp of when the operation will expires / expired | | `Date` | `timestampFinalized` | Timestamp of when the operation was switched to a terminating status | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'findAllOperationsForUser' @@ -2107,6 +2110,7 @@ A collection of records with the following structure: | `Date` | `timestampCreated` | Timestamp of when the operation was created | | `Date` | `timestampExpires` | Timestamp of when the operation will expires / expired | | `Date` | `timestampFinalized` | Timestamp of when the operation was switched to a terminating status | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'findAllOperationsByExternalID' @@ -2146,6 +2150,7 @@ A collection of records with the following structure: | `Date` | `timestampCreated` | Timestamp of when the operation was created | | `Date` | `timestampExpires` | Timestamp of when the operation will expires / expired | | `Date` | `timestampFinalized` | Timestamp of when the operation was switched to a terminating status | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'cancelOperation' @@ -2181,6 +2186,7 @@ REST endpoint: `POST /rest/v3/operation/cancel` | `Date` | `timestampCreated` | Timestamp of when the operation was created | | `Date` | `timestampExpires` | Timestamp of when the operation will expires / expired | | `Date` | `timestampFinalized` | Timestamp of when the operation was switched to a terminating status | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'approveOperation' @@ -2228,6 +2234,7 @@ REST endpoint: `POST /rest/v3/operation/approve` | `Date` | `timestampCreated` | Timestamp of when the operation was created | | `Date` | `timestampExpires` | Timestamp of when the operation will expires / expired | | `Date` | `timestampFinalized` | Timestamp of when the operation was switched to a terminating status | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'failApproveOperation' @@ -2271,6 +2278,7 @@ REST endpoint: `POST /rest/v3/operation/approve/fail` | `Date` | `timestampCreated` | Timestamp of when the operation was created | | `Date` | `timestampExpires` | Timestamp of when the operation will expires / expired | | `Date` | `timestampFinalized` | Timestamp of when the operation was switched to a terminating status | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'rejectOperation' @@ -2316,6 +2324,7 @@ REST endpoint: `POST /rest/v3/operation/reject` | `Date` | `timestampCreated` | Timestamp of when the operation was created | | `Date` | `timestampExpires` | Timestamp of when the operation will expires / expired | | `Date` | `timestampFinalized` | Timestamp of when the operation was switched to a terminating status | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ## Operation Templates @@ -2337,6 +2346,7 @@ REST endpoint: `POST /rest/v3/operation/template/create` | `List` | `signatureType` | Allowed signature types | | `Long` | `maxFailureCount` | How many failed attempts should be allowed for th operation | | `Long` | `expiration` | Operation expiration period in seconds | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | #### Response @@ -2351,6 +2361,7 @@ REST endpoint: `POST /rest/v3/operation/template/create` | `List` | `signatureType` | Allowed signature types | | `Long` | `maxFailureCount` | How many failed attempts should be allowed for th operation | | `Long` | `expiration` | Operation expiration period in seconds | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'getAllTemplates' @@ -2377,6 +2388,7 @@ Collection of items with the following structure: | `List` | `signatureType` | Allowed signature types | | `Long` | `maxFailureCount` | How many failed attempts should be allowed for th operation | | `Long` | `expiration` | Operation expiration period in seconds | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'getTemplateDetail' @@ -2405,6 +2417,7 @@ REST endpoint: `POST /rest/v3/operation/template/detail` | `List` | `signatureType` | Allowed signature types | | `Long` | `maxFailureCount` | How many failed attempts should be allowed for th operation | | `Long` | `expiration` | Operation expiration period in seconds | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'updateOperationTemplate' @@ -2424,6 +2437,7 @@ REST endpoint: `POST /rest/v3/operation/template/update` | `List` | `signatureType` | Allowed signature types | | `Long` | `maxFailureCount` | How many failed attempts should be allowed for th operation | | `Long` | `expiration` | Operation expiration period in seconds | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | #### Response @@ -2438,6 +2452,7 @@ REST endpoint: `POST /rest/v3/operation/template/update` | `List` | `signatureType` | Allowed signature types | | `Long` | `maxFailureCount` | How many failed attempts should be allowed for th operation | | `Long` | `expiration` | Operation expiration period in seconds | +| `String` | `riskFlags` | Risk flags for offline QR code. Uppercase letters without separator, e.g. `XFC`. | ### Method 'removeOperationTemplate' diff --git a/docs/sql/mysql/create_schema.sql b/docs/sql/mysql/create_schema.sql index 665a4af3c..f4426a075 100644 --- a/docs/sql/mysql/create_schema.sql +++ b/docs/sql/mysql/create_schema.sql @@ -227,6 +227,7 @@ CREATE TABLE pa_operation ( timestamp_created datetime NOT NULL, timestamp_expires datetime NOT NULL, timestamp_finalized datetime NULL, + risk_flags varchar(255), PRIMARY KEY (id) ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; @@ -241,6 +242,7 @@ CREATE TABLE pa_operation_template ( signature_type varchar(255) NOT NULL, max_failure_count bigint(20) NOT NULL, expiration bigint(20) NOT NULL, + risk_flags varchar(255), PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/docs/sql/oracle/create_schema.sql b/docs/sql/oracle/create_schema.sql index 8fe3d2adf..1bce83249 100755 --- a/docs/sql/oracle/create_schema.sql +++ b/docs/sql/oracle/create_schema.sql @@ -222,7 +222,8 @@ CREATE TABLE "PA_OPERATION" ( "MAX_FAILURE_COUNT" NUMBER(19,0) NOT NULL, "TIMESTAMP_CREATED" TIMESTAMP(6) NOT NULL, "TIMESTAMP_EXPIRES" TIMESTAMP(6) NOT NULL, - "TIMESTAMP_FINALIZED" TIMESTAMP(6) + "TIMESTAMP_FINALIZED" TIMESTAMP(6), + "RISK_FLAGS" VARCHAR2(255 CHAR) ); -- @@ -235,7 +236,8 @@ CREATE TABLE "PA_OPERATION_TEMPLATE" ( "DATA_TEMPLATE" VARCHAR2(255 CHAR) NOT NULL, "SIGNATURE_TYPE" VARCHAR2(255 CHAR) NOT NULL, "MAX_FAILURE_COUNT" NUMBER(19,0) NOT NULL, - "EXPIRATION" NUMBER(19,0) NOT NULL + "EXPIRATION" NUMBER(19,0) NOT NULL, + "RISK_FLAGS" VARCHAR2(255 CHAR) ); -- diff --git a/docs/sql/postgresql/create_schema.sql b/docs/sql/postgresql/create_schema.sql index 2095c8a68..a1d748be6 100644 --- a/docs/sql/postgresql/create_schema.sql +++ b/docs/sql/postgresql/create_schema.sql @@ -223,7 +223,8 @@ CREATE TABLE pa_operation ( max_failure_count BIGINT NOT NULL, timestamp_created TIMESTAMP NOT NULL, timestamp_expires TIMESTAMP NOT NULL, - timestamp_finalized TIMESTAMP + timestamp_finalized TIMESTAMP, + risk_flags VARCHAR(255) ); -- @@ -236,7 +237,8 @@ CREATE TABLE pa_operation_template ( data_template VARCHAR(255) NOT NULL, signature_type VARCHAR(255) NOT NULL, max_failure_count BIGINT NOT NULL, - expiration BIGINT NOT NULL + expiration BIGINT NOT NULL, + risk_flags VARCHAR(255) ); -- diff --git a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/OperationTemplateCreateRequest.java b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/OperationTemplateCreateRequest.java index 8209902c5..f5100af13 100644 --- a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/OperationTemplateCreateRequest.java +++ b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/OperationTemplateCreateRequest.java @@ -36,6 +36,7 @@ public class OperationTemplateCreateRequest { private final List signatureType = new ArrayList<>(); private Long maxFailureCount; private Long expiration; + private String riskFlags; public String getTemplateName() { return templateName; @@ -81,6 +82,14 @@ public void setExpiration(Long expiration) { this.expiration = expiration; } + public String getRiskFlags() { + return riskFlags; + } + + public void setRiskFlags(String riskFlags) { + this.riskFlags = riskFlags; + } + @Override public String toString() { return "OperationTemplateCreateRequest{" + @@ -90,6 +99,7 @@ public String toString() { ", signatureType=" + signatureType + ", maxFailureCount=" + maxFailureCount + ", expiration=" + expiration + + ", riskFlags=" + riskFlags + '}'; } } diff --git a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/OperationTemplateUpdateRequest.java b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/OperationTemplateUpdateRequest.java index 2dc828d1b..9b8f54aa9 100644 --- a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/OperationTemplateUpdateRequest.java +++ b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/OperationTemplateUpdateRequest.java @@ -36,6 +36,7 @@ public class OperationTemplateUpdateRequest { private final List signatureType = new ArrayList<>(); private Long maxFailureCount; private Long expiration; + private String riskFlags; public Long getId() { return id; @@ -81,6 +82,14 @@ public void setExpiration(Long expiration) { this.expiration = expiration; } + public String getRiskFlags() { + return riskFlags; + } + + public void setRiskFlags(String riskFlags) { + this.riskFlags = riskFlags; + } + @Override public String toString() { return "OperationTemplateUpdateRequest{" + @@ -90,6 +99,7 @@ public String toString() { ", signatureType=" + signatureType + ", maxFailureCount=" + maxFailureCount + ", expiration=" + expiration + + ", riskFlags=" + riskFlags + '}'; } } diff --git a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/OperationDetailResponse.java b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/OperationDetailResponse.java index e54084f1d..a74857d7c 100644 --- a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/OperationDetailResponse.java +++ b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/OperationDetailResponse.java @@ -49,6 +49,7 @@ public class OperationDetailResponse { private Date timestampCreated; private Date timestampExpires; private Date timestampFinalized; + private String riskFlags; public void setId(String id) { this.id = id; @@ -185,4 +186,12 @@ public void setTimestampFinalized(Date timestampFinalized) { public Date getTimestampFinalized() { return timestampFinalized; } + + public String getRiskFlags() { + return riskFlags; + } + + public void setRiskFlags(String riskFlags) { + this.riskFlags = riskFlags; + } } diff --git a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/OperationTemplateDetailResponse.java b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/OperationTemplateDetailResponse.java index 1ddc7e6a7..3904e0194 100644 --- a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/OperationTemplateDetailResponse.java +++ b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/OperationTemplateDetailResponse.java @@ -36,6 +36,7 @@ public class OperationTemplateDetailResponse { private List signatureType; private Long maxFailureCount; private Long expiration; + private String riskFlags; public Long getId() { return id; @@ -92,4 +93,12 @@ public Long getExpiration() { public void setExpiration(Long expiration) { this.expiration = expiration; } + + public String getRiskFlags() { + return riskFlags; + } + + public void setRiskFlags(String riskFlags) { + this.riskFlags = riskFlags; + } } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/OperationTemplateConverter.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/OperationTemplateConverter.java index 37101c6b6..f6d97bcd5 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/OperationTemplateConverter.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/OperationTemplateConverter.java @@ -47,6 +47,7 @@ public OperationTemplateEntity convertToDB(OperationTemplateCreateRequest source destination.setDataTemplate(source.getDataTemplate()); destination.setMaxFailureCount(source.getMaxFailureCount()); destination.setExpiration(source.getExpiration()); + destination.setRiskFlags(source.getRiskFlags()); final List signatureTypes = new ArrayList<>(); for (final SignatureType type : source.getSignatureType()) { @@ -70,6 +71,7 @@ public OperationTemplateEntity convertToDB(OperationTemplateEntity original, Ope original.setDataTemplate(source.getDataTemplate()); original.setMaxFailureCount(source.getMaxFailureCount()); original.setExpiration(source.getExpiration()); + original.setRiskFlags(source.getRiskFlags()); final List signatureTypes = new ArrayList<>(); for (final SignatureType type : source.getSignatureType()) { @@ -92,6 +94,7 @@ public OperationTemplateDetailResponse convertFromDB(OperationTemplateEntity sou destination.setDataTemplate(source.getDataTemplate()); destination.setExpiration(source.getExpiration()); destination.setMaxFailureCount(source.getMaxFailureCount()); + destination.setRiskFlags(source.getRiskFlags()); final List signatureTypesResponse = new ArrayList<>(); for (final PowerAuthSignatureTypes type : source.getSignatureType()) { final SignatureType signatureType = SignatureType.enumFromString(type.toString()); diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationEntity.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationEntity.java index aadd49728..f45d031c2 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationEntity.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationEntity.java @@ -99,6 +99,9 @@ public class OperationEntity implements Serializable { @Column(name = "timestamp_finalized") private Date timestampFinalized; + @Column(name = "risk_flags") + private String riskFlags; + /** * Get operation ID. * @return Operation ID. @@ -371,6 +374,24 @@ public void setTimestampFinalized(Date timestampFinalized) { this.timestampFinalized = timestampFinalized; } + /** + * Get risk flags. + * + * @return Risk flags. + */ + public String getRiskFlags() { + return riskFlags; + } + + /** + * Set risk flags. + * + * @param riskFlags Risk flags. + */ + public void setRiskFlags(String riskFlags) { + this.riskFlags = riskFlags; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -384,13 +405,14 @@ public boolean equals(Object o) { && templateName.equals(that.templateName) && data.equals(that.data) && Objects.equals(parameters, that.parameters) - && Objects.equals(additionalData, that.additionalData); + && Objects.equals(additionalData, that.additionalData) + && Objects.equals(riskFlags, that.riskFlags); } @Override public int hashCode() { return Objects.hash( - id, userId, applications, activationFlag, operationType, templateName, data, parameters, additionalData + id, userId, applications, activationFlag, operationType, templateName, data, parameters, additionalData, riskFlags ); } @@ -414,6 +436,7 @@ public String toString() { ", timestampCreated=" + timestampCreated + ", timestampExpires=" + timestampExpires + ", timestampFinalized=" + timestampFinalized + + ", riskFlags=" + riskFlags + '}'; } } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationTemplateEntity.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationTemplateEntity.java index 346897e1f..aedf58ca4 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationTemplateEntity.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationTemplateEntity.java @@ -62,6 +62,9 @@ public class OperationTemplateEntity implements Serializable { @Column(name = "expiration", nullable=false) private Long expiration; + @Column(name = "risk_flags") + private String riskFlags; + /** * Default constructor. */ @@ -180,6 +183,24 @@ public void setExpiration(Long expiration) { this.expiration = expiration; } + /** + * Get risk flags. + * + * @return Risk flags. + */ + public String getRiskFlags() { + return riskFlags; + } + + /** + * Set risk flags. + * + * @param riskFlags Risk flags. + */ + public void setRiskFlags(String riskFlags) { + this.riskFlags = riskFlags; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof OperationTemplateEntity)) return false; @@ -189,12 +210,13 @@ public void setExpiration(Long expiration) { && Objects.equals(dataTemplate, that.dataTemplate) && Arrays.equals(signatureType, that.signatureType) && Objects.equals(maxFailureCount, that.maxFailureCount) - && Objects.equals(expiration, that.expiration); + && Objects.equals(expiration, that.expiration) + && Objects.equals(riskFlags, that.riskFlags); } @Override public int hashCode() { int result = Objects.hash( - templateName, operationType, dataTemplate, maxFailureCount, expiration + templateName, operationType, dataTemplate, maxFailureCount, expiration, riskFlags ); result = 31 * result + Arrays.hashCode(signatureType); return result; @@ -209,6 +231,7 @@ public void setExpiration(Long expiration) { ", signatureType=" + Arrays.toString(signatureType) + ", maxFailureCount=" + maxFailureCount + ", expiration=" + expiration + + ", riskFlags=" + riskFlags + '}'; } } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/OperationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/OperationServiceBehavior.java index 2bb0e90a6..3b07a7f6f 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/OperationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/OperationServiceBehavior.java @@ -166,6 +166,7 @@ public OperationDetailResponse createOperation(OperationCreateRequest request) t operationEntity.setTimestampCreated(currentTimestamp); operationEntity.setTimestampExpires(timestampExpiration); operationEntity.setTimestampFinalized(null); // empty initially + operationEntity.setRiskFlags(templateEntity.getRiskFlags()); final AuditDetail auditDetail = AuditDetail.builder() .type("operation") @@ -632,6 +633,8 @@ private OperationDetailResponse convertFromEntity(OperationEntity source) { destination.setTimestampCreated(source.getTimestampCreated()); destination.setTimestampExpires(source.getTimestampExpires()); destination.setTimestampFinalized(source.getTimestampFinalized()); + destination.setRiskFlags(source.getRiskFlags()); + switch (source.getStatus()) { case PENDING: destination.setStatus(OperationStatus.PENDING); From cce101c18a41ac1e8c80e71a802093aede5da6cb Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 19 Dec 2022 07:29:09 +0100 Subject: [PATCH 43/58] Fix #802: Update Wultra dependencies --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 4c7efd4de..ac8a415f1 100644 --- a/pom.xml +++ b/pom.xml @@ -94,9 +94,9 @@ 3.1.1 - 1.4.0-SNAPSHOT - 1.6.0-SNAPSHOT - 1.6.0-SNAPSHOT + 1.4.0 + 1.6.0 + 1.6.0 1.70 From 079a7d4b5255349e838f208f6265fa019db7f0af Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 19 Dec 2022 07:32:30 +0100 Subject: [PATCH 44/58] Fix #800: Set release version to 1.4.0 --- pom.xml | 2 +- powerauth-admin/pom.xml | 2 +- powerauth-client-model/pom.xml | 2 +- powerauth-java-server/pom.xml | 2 +- powerauth-rest-client-spring/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 4c7efd4de..e3dae5cd0 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ io.getlime.security powerauth-server-parent - 1.4.0-SNAPSHOT + 1.4.0 pom diff --git a/powerauth-admin/pom.xml b/powerauth-admin/pom.xml index a7a23c4ca..eb1e79f3b 100644 --- a/powerauth-admin/pom.xml +++ b/powerauth-admin/pom.xml @@ -11,7 +11,7 @@ io.getlime.security powerauth-server-parent - 1.4.0-SNAPSHOT + 1.4.0 diff --git a/powerauth-client-model/pom.xml b/powerauth-client-model/pom.xml index e9e25fa62..0ac380727 100644 --- a/powerauth-client-model/pom.xml +++ b/powerauth-client-model/pom.xml @@ -28,7 +28,7 @@ io.getlime.security powerauth-server-parent - 1.4.0-SNAPSHOT + 1.4.0 diff --git a/powerauth-java-server/pom.xml b/powerauth-java-server/pom.xml index 561445e07..b53c76a8d 100644 --- a/powerauth-java-server/pom.xml +++ b/powerauth-java-server/pom.xml @@ -29,7 +29,7 @@ io.getlime.security powerauth-server-parent - 1.4.0-SNAPSHOT + 1.4.0 diff --git a/powerauth-rest-client-spring/pom.xml b/powerauth-rest-client-spring/pom.xml index 8068c1716..5ea2e93b6 100644 --- a/powerauth-rest-client-spring/pom.xml +++ b/powerauth-rest-client-spring/pom.xml @@ -28,7 +28,7 @@ io.getlime.security powerauth-server-parent - 1.4.0-SNAPSHOT + 1.4.0 From e16ee5942310f9560b02a48af1fd31bddf6d982e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Mon, 19 Dec 2022 09:27:50 +0100 Subject: [PATCH 45/58] Fix #806: Update dependencies (#807) * Fix #806: Update dependencies --- pom.xml | 28 ++++++---------------------- powerauth-client-model/pom.xml | 1 - powerauth-java-server/pom.xml | 1 - 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/pom.xml b/pom.xml index ac8a415f1..e92ae56a9 100644 --- a/pom.xml +++ b/pom.xml @@ -85,10 +85,10 @@ 1.8 1.8 - 3.2.2 - 3.0.0-M2 - 3.4.0 - 3.3.2 + 3.3.0 + 3.0.0 + 3.4.1 + 3.1.0 3.1.1 @@ -116,10 +116,9 @@ 5.8.2 - 2.1.212 + 2.1.214 - 2.13.3 1.10.0 @@ -156,16 +155,6 @@ - - org.apache.maven.plugins - maven-jar-plugin - ${maven-jar-plugin.version} - - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - org.apache.maven.plugins maven-javadoc-plugin @@ -187,16 +176,11 @@ - - org.apache.maven.plugins - maven-deploy-plugin - ${maven-deploy-plugin.version} - org.apache.maven.plugins maven-enforcer-plugin - 3.1.0 + ${maven-enforcer-plugin.version} enforce-banned-dependencies diff --git a/powerauth-client-model/pom.xml b/powerauth-client-model/pom.xml index e9e25fa62..a30f1ba9a 100644 --- a/powerauth-client-model/pom.xml +++ b/powerauth-client-model/pom.xml @@ -40,7 +40,6 @@ com.fasterxml.jackson.core jackson-databind - ${jackson.version} javax.xml.bind diff --git a/powerauth-java-server/pom.xml b/powerauth-java-server/pom.xml index 561445e07..943e5c3ec 100644 --- a/powerauth-java-server/pom.xml +++ b/powerauth-java-server/pom.xml @@ -195,7 +195,6 @@ com.h2database h2 - ${h2.version} test From cc749b84dbd7dad4268617da3464a6fe76dc5f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zden=C4=9Bk=20=C4=8Cern=C3=BD?= Date: Mon, 19 Dec 2022 09:31:16 +0100 Subject: [PATCH 46/58] Issues/owasp dependency check (#799) * OWASP dependency check action * Secrets for snapshot build * Normalize naming of jobs --- .github/workflows/maven-deploy.yml | 16 ++++++++-------- .github/workflows/maven-test.yml | 9 ++++----- .github/workflows/owas-dependecy-check.yml | 12 ++++++++++++ 3 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/owas-dependecy-check.yml diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/maven-deploy.yml index 735ff4c85..8f31c6b75 100644 --- a/.github/workflows/maven-deploy.yml +++ b/.github/workflows/maven-deploy.yml @@ -21,15 +21,13 @@ on: description: internal or external repository push: branches: - - 'develop' - - 'test/ci' - - + - 'develop' + - 'test/ci' jobs: - maven-deploy-internal: + maven-deploy-jfrog: if: ${{ github.event_name == 'push' }} - name: Deploy to ${{ inputs.environment }} + name: Deploy to jfrog uses: wultra/wultra-infrastructure/.github/workflows/maven-deploy.yml@develop with: environment: internal-publish @@ -38,9 +36,9 @@ jobs: username: ${{ secrets.MAVEN_CENTRAL_USERNAME }} password: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} - maven-deploy-public: + maven-deploy-manual: if: ${{ github.event_name == 'workflow_dispatch' }} - name: Deploy to ${{ inputs.environment }} + name: Deploy by parameter uses: wultra/wultra-infrastructure/.github/workflows/maven-deploy.yml@develop with: environment: ${{ inputs.environment }} @@ -48,3 +46,5 @@ jobs: secrets: username: ${{ secrets.MAVEN_CENTRAL_USERNAME }} password: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + gpg_passphrase: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} + gpg_key: ${{ secrets.OSSRH_GPG_SECRET_KEY }} \ No newline at end of file diff --git a/.github/workflows/maven-test.yml b/.github/workflows/maven-test.yml index 5f4e4c134..6bdada9fe 100644 --- a/.github/workflows/maven-test.yml +++ b/.github/workflows/maven-test.yml @@ -4,10 +4,8 @@ on: workflow_dispatch: push: branches: - - 'develop' - - 'master' - - 'releases/**' - - 'test/ci' + - 'master' + - 'releases/**' pull_request: branches: - 'develop' @@ -16,4 +14,5 @@ on: jobs: maven-tests: - uses: wultra/wultra-infrastructure/.github/workflows/maven-test.yml@develop \ No newline at end of file + uses: wultra/wultra-infrastructure/.github/workflows/maven-test.yml@develop + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/owas-dependecy-check.yml b/.github/workflows/owas-dependecy-check.yml new file mode 100644 index 000000000..c79178b2a --- /dev/null +++ b/.github/workflows/owas-dependecy-check.yml @@ -0,0 +1,12 @@ +name: Run OWASP Dependency Check +on: + workflow_dispatch: + + push: + branches: + - 'develop' + +jobs: + owasp-check: + uses: wultra/wultra-infrastructure/.github/workflows/owasp-dependency-check.yml@develop + secrets: inherit \ No newline at end of file From 89f61af594a419eebdf3616abadf33a9e4427c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Mon, 19 Dec 2022 12:30:22 +0100 Subject: [PATCH 47/58] Fix #808: Update Bouncy Castle to 1.72 (#809) --- docs/Deploying-Wildfly.md | 2 +- docs/Installing-Bouncy-Castle.md | 18 +++++++++--------- pom.xml | 2 +- powerauth-java-server/pom.xml | 4 ++-- .../WEB-INF/jboss-deployment-structure.xml | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/Deploying-Wildfly.md b/docs/Deploying-Wildfly.md index b25ad17f5..d233ca35e 100644 --- a/docs/Deploying-Wildfly.md +++ b/docs/Deploying-Wildfly.md @@ -19,7 +19,7 @@ PowerAuth server contains the following configuration in `jboss-deployment-struc - + diff --git a/docs/Installing-Bouncy-Castle.md b/docs/Installing-Bouncy-Castle.md index 2f7bc246b..366d41188 100644 --- a/docs/Installing-Bouncy-Castle.md +++ b/docs/Installing-Bouncy-Castle.md @@ -11,7 +11,7 @@ Bouncy Castle library installation depends on Java version and used web containe PowerAuth server uses dynamic initialization of Bouncy Castle provider, so it is not required to configure security provider statically in the Java Runtime configuration. You can get the Bouncy Castle provider here: -https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on +https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk18on ### Installing on Java 11 @@ -19,7 +19,7 @@ Java 11 no longer provides a library extension mechanism and thus Bouncy Castle #### Bouncy Castle on Tomcat -Copy [`bcprov-jdk15on-168.jar`](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on) to your `${CATALINA_HOME}/lib` folder. +Copy [`bcprov-jdk18on-172.jar`](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk18on) to your `${CATALINA_HOME}/lib` folder. Bouncy Castle library will not work properly in case any war file deployed to Tomcat contains another copy of the Bouncy Castle library, even if the war file is not related to PowerAuth. @@ -28,7 +28,7 @@ Bouncy Castle library must be only present in the `${CATALINA_HOME}/lib` folder. #### Bouncy Castle on JBoss / Wildfly -PowerAuth server requires a specific version of Bouncy Castle library: `bcprov-jdk15on-168.jar` +PowerAuth server requires a specific version of Bouncy Castle library: `bcprov-jdk18on-172.jar` In order to make PowerAuth Server work on JBoss / Wildfly, you need to add and enable the external Bouncy Castle module on the server by adding the `` element in the `standalone.xml` file: @@ -46,12 +46,12 @@ The module should be defined using a new module XML file in JBoss folder `module - + ``` -Finally, copy the Bouncy Castle library `bcprov-jdk15on-167.jar` into folder `modules/system/layers/base/org/bouncycastle/external/main` so that it is available for the module. +Finally, copy the Bouncy Castle library `bcprov-jdk18on-172.jar` into folder `modules/system/layers/base/org/bouncycastle/external/main` so that it is available for the module. Do not reuse Bouncy Castle module `org.bouncycastle` from JBoss, because version of library provided by JBoss may differ from version required by PowerAuth. @@ -82,7 +82,7 @@ Java 8 provides a library extension mechanism which can be used to installed Bou ##### Standalone Tomcat -When running a standalone Tomcat instance, all you need to do is to copy [`bcprov-jdk15on-167.jar`](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on) to your `${JDK_HOME}/jre/lib/ext` folder. +When running a standalone Tomcat instance, all you need to do is to copy [`bcprov-jdk18on-172.jar`](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk18on) to your `${JDK_HOME}/jre/lib/ext` folder. ##### Embedded Tomcat @@ -96,7 +96,7 @@ Make sure to add the provider to the top of the list (ideally, N=2). #### Bouncy Castle on JBoss / Wildfly -PowerAuth server requires a specific version of Bouncy Castle library: `bcprov-jdk15on-167.jar` +PowerAuth server requires a specific version of Bouncy Castle library: `bcprov-jdk18on-172.jar` In order to make PowerAuth Server work on JBoss / Wildfly, you need to add and enable the external Bouncy Castle module on the server by adding the `` element in the `standalone.xml` file: @@ -114,12 +114,12 @@ The module should be defined using a new module XML file in JBoss folder `module - + ``` -Finally, copy the Bouncy Castle library `bcprov-jdk15on-167.jar` into folder `modules/system/layers/base/org/bouncycastle/external/main` so that it is available for the module. +Finally, copy the Bouncy Castle library `bcprov-jdk18on-172.jar` into folder `modules/system/layers/base/org/bouncycastle/external/main` so that it is available for the module. Do not reuse Bouncy Castle module `org.bouncycastle` from JBoss, because version of library provided by JBoss may differ from version required by PowerAuth. diff --git a/pom.xml b/pom.xml index e92ae56a9..2fb1cb181 100644 --- a/pom.xml +++ b/pom.xml @@ -97,7 +97,7 @@ 1.4.0 1.6.0 1.6.0 - 1.70 + 1.72 2.3.1 diff --git a/powerauth-java-server/pom.xml b/powerauth-java-server/pom.xml index 943e5c3ec..27b40b23b 100644 --- a/powerauth-java-server/pom.xml +++ b/powerauth-java-server/pom.xml @@ -157,8 +157,8 @@ org.bouncycastle - bcprov-jdk15on - ${bcprov-jdk15on.version} + bcprov-jdk18on + ${bcprov-jdk18on.version} diff --git a/powerauth-java-server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/powerauth-java-server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml index 07eb48f50..45f68d9cf 100644 --- a/powerauth-java-server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml +++ b/powerauth-java-server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml @@ -12,7 +12,7 @@ - + From 01e22bf32ebc7af915b7f59ddf38d918e31256b9 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 19 Dec 2022 13:19:34 +0100 Subject: [PATCH 48/58] Fix #810: Exclude Bouncy Castle bcprov-jdk15on --- pom.xml | 2 ++ powerauth-java-server/pom.xml | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/pom.xml b/pom.xml index 2fb1cb181..023f16744 100644 --- a/pom.xml +++ b/pom.xml @@ -192,6 +192,8 @@ org.apache.tomcat.embed:*:*:*:compile + org.bouncycastle:bcpkix-jdk15on:*:*:compile + org.bouncycastle:bcprov-jdk15on:*:*:compile diff --git a/powerauth-java-server/pom.xml b/powerauth-java-server/pom.xml index 27b40b23b..798485e3e 100644 --- a/powerauth-java-server/pom.xml +++ b/powerauth-java-server/pom.xml @@ -106,6 +106,12 @@ org.springframework.cloud spring-cloud-starter-vault-config ${spring-cloud-vault.version} + + + org.bouncycastle + bcpkix-jdk15on + + org.springframework.boot From bcb78d501573b178c04c62e178cb1575f0792c37 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 19 Dec 2022 14:23:48 +0100 Subject: [PATCH 49/58] Fix #813: Update schedlock --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 864fe6b6b..3b7388302 100644 --- a/pom.xml +++ b/pom.xml @@ -112,7 +112,7 @@ 1.6.9 - 4.36.0 + 4.43.0 5.8.2 From 49ce884e8f04ae90ab9ce69ba9f9cee35f244198 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 19 Dec 2022 14:47:07 +0100 Subject: [PATCH 50/58] Fix #815: Fix method name for activation expiration --- .../service/behavior/tasks/v3/ActivationServiceBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index 93365610a..8e3d6dc30 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -1967,7 +1967,7 @@ private ActivationRecovery createRecoveryCodeForActivation(ActivationRecordEntit @Scheduled(fixedRateString = "${powerauth.service.scheduled.job.activationsCleanup:5000}") @SchedulerLock(name = "expireActivationsTask") @Transactional - public void expireOperations() { + public void expireActivations() { LockAssert.assertLocked(); final Date currentTimestamp = new Date(); final Date lookBackTimestamp = new Date(currentTimestamp.getTime() - powerAuthServiceConfiguration.getActivationsCleanupLookBackInMilliseconds()); From 9fa6c165738555bbbac27e9a9b1c3f89b058543d Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 19 Dec 2022 15:46:39 +0100 Subject: [PATCH 51/58] Fix #817: Review business logic for activation code revocation --- .../repository/ActivationRepository.java | 2 + .../tasks/v3/ActivationServiceBehavior.java | 58 ++++++++++++------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java index 317062031..52701e481 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/repository/ActivationRepository.java @@ -171,11 +171,13 @@ default Long getActivationCountByActivationCode(String applicationId, String act /** * Fetch all activations that are in a given state, were expired after a specified timestamp, and are already expired according to a provided current timestamp. + * The activations are locked in DB in PESSIMISTIC_WRITE mode to avoid concurrency issues. * @param states Activation states that are used for the lookup. * @param startingTimestamp Timestamp after which the activation was expired. * @param currentTimestamp Current timestamp, to identify already expired operations. * @return Stream of activations. */ + @Lock(LockModeType.PESSIMISTIC_WRITE) @Query("SELECT a FROM ActivationRecordEntity a WHERE a.activationStatus IN :states AND a.timestampActivationExpire >= :startingTimestamp AND a.timestampActivationExpire < :currentTimestamp") Stream findAbandonedActivations(Collection states, Date startingTimestamp, Date currentTimestamp); } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index 93365610a..886a352c6 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -1452,26 +1452,14 @@ public RemoveActivationResponse removeActivation(String activationId, String ext * @return Response with confirmation of removal. */ public RemoveActivationResponse removeActivation(@NotNull ActivationRecordEntity activation, String externalUserId, boolean revokeRecoveryCodes) { + logger.info("Processing activation removal, activation ID: {}", activation.getActivationId()); activation.setActivationStatus(io.getlime.security.powerauth.app.server.database.model.ActivationStatus.REMOVED); - if (revokeRecoveryCodes) { - final RecoveryCodeRepository recoveryCodeRepository = repositoryCatalogue.getRecoveryCodeRepository(); - final List recoveryCodeEntities = recoveryCodeRepository.findAllByActivationId(activation.getActivationId()); - final Date now = new Date(); - for (RecoveryCodeEntity recoveryCode : recoveryCodeEntities) { - // revoke only codes that are not yet revoked, to avoid messing up with timestamp - if (!RecoveryCodeStatus.REVOKED.equals(recoveryCode.getStatus())) { - recoveryCode.setStatus(RecoveryCodeStatus.REVOKED); - recoveryCode.setTimestampLastChange(now); - // Change status of PUKs with status VALID to INVALID - for (RecoveryPukEntity puk : recoveryCode.getRecoveryPuks()) { - if (RecoveryPukStatus.VALID.equals(puk.getStatus())) { - puk.setStatus(RecoveryPukStatus.INVALID); - puk.setTimestampLastChange(now); - } - } - recoveryCodeRepository.save(recoveryCode); - } - } + // Recovery codes are revoked in case revocation is requested, or always when the activation is in CREATED or PENDING_COMMIT state + if (revokeRecoveryCodes || + (activation.getActivationStatus() == ActivationStatus.CREATED || + activation.getActivationStatus() == ActivationStatus.PENDING_COMMIT)) { + logger.info("Revoking recovery codes for activation ID: {}", activation.getActivationId()); + revokeRecoveryCodes(activation); } activationHistoryServiceBehavior.saveActivationAndLogChange(activation, externalUserId); callbackUrlBehavior.notifyCallbackListenersOnActivationChange(activation); @@ -1962,12 +1950,38 @@ private ActivationRecovery createRecoveryCodeForActivation(ActivationRecordEntit } } + /** + * Revoke recovery codes for an activation entity. + * @param activation Activation entity. + */ + private void revokeRecoveryCodes(ActivationRecordEntity activation) { + final RecoveryCodeRepository recoveryCodeRepository = repositoryCatalogue.getRecoveryCodeRepository(); + final List recoveryCodeEntities = recoveryCodeRepository.findAllByActivationId(activation.getActivationId()); + final Date now = new Date(); + for (RecoveryCodeEntity recoveryCode : recoveryCodeEntities) { + logger.debug("Revoking recovery code: {} for activation ID: {}", recoveryCode.getRecoveryCode(), activation.getActivationId()); + // revoke only codes that are not yet revoked, to avoid messing up with timestamp + if (!RecoveryCodeStatus.REVOKED.equals(recoveryCode.getStatus())) { + recoveryCode.setStatus(RecoveryCodeStatus.REVOKED); + recoveryCode.setTimestampLastChange(now); + // Change status of PUKs with status VALID to INVALID + for (RecoveryPukEntity puk : recoveryCode.getRecoveryPuks()) { + if (RecoveryPukStatus.VALID.equals(puk.getStatus())) { + puk.setStatus(RecoveryPukStatus.INVALID); + puk.setTimestampLastChange(now); + } + } + recoveryCodeRepository.save(recoveryCode); + } + } + } + // Scheduled tasks @Scheduled(fixedRateString = "${powerauth.service.scheduled.job.activationsCleanup:5000}") @SchedulerLock(name = "expireActivationsTask") @Transactional - public void expireOperations() { + public void expireActivations() { LockAssert.assertLocked(); final Date currentTimestamp = new Date(); final Date lookBackTimestamp = new Date(currentTimestamp.getTime() - powerAuthServiceConfiguration.getActivationsCleanupLookBackInMilliseconds()); @@ -1976,8 +1990,8 @@ public void expireOperations() { final ImmutableSet activationStatuses = ImmutableSet.of(ActivationStatus.CREATED, ActivationStatus.PENDING_COMMIT); try (final Stream abandonedActivations = activationRepository.findAbandonedActivations(activationStatuses, lookBackTimestamp, currentTimestamp)) { abandonedActivations.forEach(activation -> { - logger.info("Removing abandoned activation with ID: {}, revoking recovery codes.", activation.getActivationId()); - deactivatePendingActivation(currentTimestamp, activation, false); + logger.info("Removing abandoned activation with ID: {}", activation.getActivationId()); + removeActivation(activation, null, true); }); } } From 9d0006a32992f79c6ca0ddb36ca47395340e725d Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 19 Dec 2022 16:03:25 +0100 Subject: [PATCH 52/58] Revoke recovery code in method deactivatePendingActivation --- .../service/behavior/tasks/v3/ActivationServiceBehavior.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index 886a352c6..10c86381a 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -163,11 +163,13 @@ public void setRecoveryPukConverter(RecoveryPukConverter recoveryPukConverter) { */ private void deactivatePendingActivation(Date timestamp, ActivationRecordEntity activation, boolean isActivationLocked) { if ((activation.getActivationStatus().equals(ActivationStatus.CREATED) || activation.getActivationStatus().equals(ActivationStatus.PENDING_COMMIT)) && (timestamp.getTime() > activation.getTimestampActivationExpire().getTime())) { + logger.info("Deactivating pending activation, activation ID: {}", activation.getActivationId()); if (!isActivationLocked) { // Make sure activation is locked until the end of transaction in case it was not locked yet activation = repositoryCatalogue.getActivationRepository().findActivationWithLock(activation.getActivationId()); } activation.setActivationStatus(io.getlime.security.powerauth.app.server.database.model.ActivationStatus.REMOVED); + revokeRecoveryCodes(activation); activationHistoryServiceBehavior.saveActivationAndLogChange(activation); callbackUrlBehavior.notifyCallbackListenersOnActivationChange(activation); } From ba7b7166421b4bfaf6285365b39d7002a71c5f63 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 19 Dec 2022 16:05:40 +0100 Subject: [PATCH 53/58] Improve logging for recovery code revocation --- .../service/behavior/tasks/v3/ActivationServiceBehavior.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index 10c86381a..c3f25dd32 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -1460,7 +1460,6 @@ public RemoveActivationResponse removeActivation(@NotNull ActivationRecordEntity if (revokeRecoveryCodes || (activation.getActivationStatus() == ActivationStatus.CREATED || activation.getActivationStatus() == ActivationStatus.PENDING_COMMIT)) { - logger.info("Revoking recovery codes for activation ID: {}", activation.getActivationId()); revokeRecoveryCodes(activation); } activationHistoryServiceBehavior.saveActivationAndLogChange(activation, externalUserId); @@ -1957,6 +1956,7 @@ private ActivationRecovery createRecoveryCodeForActivation(ActivationRecordEntit * @param activation Activation entity. */ private void revokeRecoveryCodes(ActivationRecordEntity activation) { + logger.info("Revoking recovery codes for activation ID: {}", activation.getActivationId()); final RecoveryCodeRepository recoveryCodeRepository = repositoryCatalogue.getRecoveryCodeRepository(); final List recoveryCodeEntities = recoveryCodeRepository.findAllByActivationId(activation.getActivationId()); final Date now = new Date(); From f143a53d3c4931b0a420bd1b357063584dd8498f Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 19 Dec 2022 16:07:42 +0100 Subject: [PATCH 54/58] Code cleanup --- .../tasks/v3/ActivationServiceBehavior.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index c3f25dd32..e07b7d418 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -169,7 +169,7 @@ private void deactivatePendingActivation(Date timestamp, ActivationRecordEntity activation = repositoryCatalogue.getActivationRepository().findActivationWithLock(activation.getActivationId()); } activation.setActivationStatus(io.getlime.security.powerauth.app.server.database.model.ActivationStatus.REMOVED); - revokeRecoveryCodes(activation); + revokeRecoveryCodes(activation.getActivationId()); activationHistoryServiceBehavior.saveActivationAndLogChange(activation); callbackUrlBehavior.notifyCallbackListenersOnActivationChange(activation); } @@ -1460,7 +1460,7 @@ public RemoveActivationResponse removeActivation(@NotNull ActivationRecordEntity if (revokeRecoveryCodes || (activation.getActivationStatus() == ActivationStatus.CREATED || activation.getActivationStatus() == ActivationStatus.PENDING_COMMIT)) { - revokeRecoveryCodes(activation); + revokeRecoveryCodes(activation.getActivationId()); } activationHistoryServiceBehavior.saveActivationAndLogChange(activation, externalUserId); callbackUrlBehavior.notifyCallbackListenersOnActivationChange(activation); @@ -1953,15 +1953,15 @@ private ActivationRecovery createRecoveryCodeForActivation(ActivationRecordEntit /** * Revoke recovery codes for an activation entity. - * @param activation Activation entity. + * @param activationId Activation identifier. */ - private void revokeRecoveryCodes(ActivationRecordEntity activation) { - logger.info("Revoking recovery codes for activation ID: {}", activation.getActivationId()); + private void revokeRecoveryCodes(String activationId) { + logger.info("Revoking recovery codes for activation ID: {}", activationId); final RecoveryCodeRepository recoveryCodeRepository = repositoryCatalogue.getRecoveryCodeRepository(); - final List recoveryCodeEntities = recoveryCodeRepository.findAllByActivationId(activation.getActivationId()); + final List recoveryCodeEntities = recoveryCodeRepository.findAllByActivationId(activationId); final Date now = new Date(); for (RecoveryCodeEntity recoveryCode : recoveryCodeEntities) { - logger.debug("Revoking recovery code: {} for activation ID: {}", recoveryCode.getRecoveryCode(), activation.getActivationId()); + logger.debug("Revoking recovery code: {} for activation ID: {}", recoveryCode.getRecoveryCode(), activationId); // revoke only codes that are not yet revoked, to avoid messing up with timestamp if (!RecoveryCodeStatus.REVOKED.equals(recoveryCode.getStatus())) { recoveryCode.setStatus(RecoveryCodeStatus.REVOKED); From 6f92ef8f25b743373a4a53bdb0603a0e281b06fd Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Tue, 20 Dec 2022 09:11:22 +0100 Subject: [PATCH 55/58] Unify internal logic for activation removal --- .../tasks/v3/ActivationServiceBehavior.java | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index e07b7d418..fbd1117a2 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -168,10 +168,7 @@ private void deactivatePendingActivation(Date timestamp, ActivationRecordEntity // Make sure activation is locked until the end of transaction in case it was not locked yet activation = repositoryCatalogue.getActivationRepository().findActivationWithLock(activation.getActivationId()); } - activation.setActivationStatus(io.getlime.security.powerauth.app.server.database.model.ActivationStatus.REMOVED); - revokeRecoveryCodes(activation.getActivationId()); - activationHistoryServiceBehavior.saveActivationAndLogChange(activation); - callbackUrlBehavior.notifyCallbackListenersOnActivationChange(activation); + removeActivationInternal(activation, null, true); } } @@ -1455,15 +1452,11 @@ public RemoveActivationResponse removeActivation(String activationId, String ext */ public RemoveActivationResponse removeActivation(@NotNull ActivationRecordEntity activation, String externalUserId, boolean revokeRecoveryCodes) { logger.info("Processing activation removal, activation ID: {}", activation.getActivationId()); - activation.setActivationStatus(io.getlime.security.powerauth.app.server.database.model.ActivationStatus.REMOVED); // Recovery codes are revoked in case revocation is requested, or always when the activation is in CREATED or PENDING_COMMIT state - if (revokeRecoveryCodes || - (activation.getActivationStatus() == ActivationStatus.CREATED || - activation.getActivationStatus() == ActivationStatus.PENDING_COMMIT)) { - revokeRecoveryCodes(activation.getActivationId()); - } - activationHistoryServiceBehavior.saveActivationAndLogChange(activation, externalUserId); - callbackUrlBehavior.notifyCallbackListenersOnActivationChange(activation); + revokeRecoveryCodes = revokeRecoveryCodes + || activation.getActivationStatus() == ActivationStatus.CREATED + || activation.getActivationStatus() == ActivationStatus.PENDING_COMMIT; + removeActivationInternal(activation, externalUserId, revokeRecoveryCodes); RemoveActivationResponse response = new RemoveActivationResponse(); response.setActivationId(activation.getActivationId()); response.setRemoved(true); @@ -1951,6 +1944,21 @@ private ActivationRecovery createRecoveryCodeForActivation(ActivationRecordEntit } } + /** + * Internal logic for processing activation removal. + * @param activation Activation entity. + * @param externalUserId External user identifier. + * @param revokeRecoveryCodes Whether associated recovery codes should be revoked. + */ + private void removeActivationInternal(ActivationRecordEntity activation, String externalUserId, boolean revokeRecoveryCodes) { + activation.setActivationStatus(io.getlime.security.powerauth.app.server.database.model.ActivationStatus.REMOVED); + if (revokeRecoveryCodes) { + revokeRecoveryCodes(activation.getActivationId()); + } + activationHistoryServiceBehavior.saveActivationAndLogChange(activation, externalUserId); + callbackUrlBehavior.notifyCallbackListenersOnActivationChange(activation); + } + /** * Revoke recovery codes for an activation entity. * @param activationId Activation identifier. @@ -1993,7 +2001,7 @@ public void expireActivations() { try (final Stream abandonedActivations = activationRepository.findAbandonedActivations(activationStatuses, lookBackTimestamp, currentTimestamp)) { abandonedActivations.forEach(activation -> { logger.info("Removing abandoned activation with ID: {}", activation.getActivationId()); - removeActivation(activation, null, true); + deactivatePendingActivation(currentTimestamp, activation, true); }); } } From 0a5eb8991a349a75f21909cfe7e0dc7c4e9dec4f Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Tue, 20 Dec 2022 09:49:44 +0100 Subject: [PATCH 56/58] Force correct recovery code revocation logic for activations which are in CREATED or PENDING_COMMIT states --- .../behavior/tasks/v3/ActivationServiceBehavior.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index fbd1117a2..8b30c65c5 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -1452,10 +1452,6 @@ public RemoveActivationResponse removeActivation(String activationId, String ext */ public RemoveActivationResponse removeActivation(@NotNull ActivationRecordEntity activation, String externalUserId, boolean revokeRecoveryCodes) { logger.info("Processing activation removal, activation ID: {}", activation.getActivationId()); - // Recovery codes are revoked in case revocation is requested, or always when the activation is in CREATED or PENDING_COMMIT state - revokeRecoveryCodes = revokeRecoveryCodes - || activation.getActivationStatus() == ActivationStatus.CREATED - || activation.getActivationStatus() == ActivationStatus.PENDING_COMMIT; removeActivationInternal(activation, externalUserId, revokeRecoveryCodes); RemoveActivationResponse response = new RemoveActivationResponse(); response.setActivationId(activation.getActivationId()); @@ -1952,6 +1948,10 @@ private ActivationRecovery createRecoveryCodeForActivation(ActivationRecordEntit */ private void removeActivationInternal(ActivationRecordEntity activation, String externalUserId, boolean revokeRecoveryCodes) { activation.setActivationStatus(io.getlime.security.powerauth.app.server.database.model.ActivationStatus.REMOVED); + // Recovery codes are revoked in case revocation is requested, or always when the activation is in CREATED or PENDING_COMMIT state + revokeRecoveryCodes = revokeRecoveryCodes + || activation.getActivationStatus() == ActivationStatus.CREATED + || activation.getActivationStatus() == ActivationStatus.PENDING_COMMIT; if (revokeRecoveryCodes) { revokeRecoveryCodes(activation.getActivationId()); } From 5e463808e4b83264b4f7d6ba1d59f2e77ab7ca7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0trobl?= Date: Wed, 21 Dec 2022 08:36:13 +0100 Subject: [PATCH 57/58] Avoid using parameter revokeRecoveryCodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Luboš Račanský --- .../behavior/tasks/v3/ActivationServiceBehavior.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index 8b30c65c5..a0c74d3b3 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -1946,13 +1946,12 @@ private ActivationRecovery createRecoveryCodeForActivation(ActivationRecordEntit * @param externalUserId External user identifier. * @param revokeRecoveryCodes Whether associated recovery codes should be revoked. */ - private void removeActivationInternal(ActivationRecordEntity activation, String externalUserId, boolean revokeRecoveryCodes) { + private void removeActivationInternal(final ActivationRecordEntity activation, final String externalUserId, final boolean revokeRecoveryCodes) { activation.setActivationStatus(io.getlime.security.powerauth.app.server.database.model.ActivationStatus.REMOVED); // Recovery codes are revoked in case revocation is requested, or always when the activation is in CREATED or PENDING_COMMIT state - revokeRecoveryCodes = revokeRecoveryCodes + if (revokeRecoveryCodes || activation.getActivationStatus() == ActivationStatus.CREATED - || activation.getActivationStatus() == ActivationStatus.PENDING_COMMIT; - if (revokeRecoveryCodes) { + || activation.getActivationStatus() == ActivationStatus.PENDING_COMMIT) { revokeRecoveryCodes(activation.getActivationId()); } activationHistoryServiceBehavior.saveActivationAndLogChange(activation, externalUserId); From 6837f60d0e78f6602712c46ba773267c65e8905c Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Wed, 21 Dec 2022 08:53:14 +0100 Subject: [PATCH 58/58] Fix #759: Optimize query for getting expired activations --- docs/PowerAuth-Server-1.4.0.md | 6 +++ docs/sql/mysql/create_schema.sql | 54 +++++++++++++++++++-------- docs/sql/oracle/create_schema.sql | 2 + docs/sql/postgresql/create_schema.sql | 2 + 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/docs/PowerAuth-Server-1.4.0.md b/docs/PowerAuth-Server-1.4.0.md index 9f7aac232..ada7b0aa3 100644 --- a/docs/PowerAuth-Server-1.4.0.md +++ b/docs/PowerAuth-Server-1.4.0.md @@ -66,3 +66,9 @@ ALTER TABLE pa_operation ALTER TABLE pa_operation_template ADD COLUMN risk_flags varchar(255); ``` + +### Added Database Indexes + +```sql +CREATE INDEX pa_activation_expiration on pa_activation (activation_status, timestamp_activation_expire); +``` diff --git a/docs/sql/mysql/create_schema.sql b/docs/sql/mysql/create_schema.sql index f4426a075..ce157165e 100644 --- a/docs/sql/mysql/create_schema.sql +++ b/docs/sql/mysql/create_schema.sql @@ -299,35 +299,59 @@ CREATE TABLE IF NOT EXISTS audit_param ( -- Indexes for better performance. InnoDB engine creates indexes on foreign keys automatically, so they are not included. -- -CREATE INDEX `pa_activation_code` ON `pa_activation`(`activation_code`); +CREATE INDEX pa_activation_application ON pa_activation(application_id); -CREATE INDEX `pa_activation_user_id` ON `pa_activation`(`user_id`); +CREATE INDEX pa_activation_keypair ON pa_activation(master_keypair_id); -CREATE INDEX `pa_activation_history_created` ON `pa_activation_history`(`timestamp_created`); +CREATE INDEX pa_activation_code ON pa_activation(activation_code); -CREATE UNIQUE INDEX `pa_app_version_app_key` ON `pa_application_version`(`application_key`); +CREATE INDEX pa_activation_user_id ON pa_activation(user_id); -CREATE INDEX `pa_app_callback_app` ON `pa_application_callback`(`application_id`); +CREATE INDEX pa_activation_expiration on pa_activation (activation_status, timestamp_activation_expire); -CREATE UNIQUE INDEX `pa_integration_token` ON `pa_integration`(`client_token`); +CREATE INDEX pa_activation_history_act ON pa_activation_history(activation_id); -CREATE INDEX `pa_signature_audit_created` ON `pa_signature_audit`(`timestamp_created`); +CREATE INDEX pa_activation_history_created ON pa_activation_history(timestamp_created); -CREATE INDEX `pa_recovery_code` ON `pa_recovery_code`(`recovery_code`); +CREATE INDEX pa_application_version_app ON pa_application_version(application_id); -CREATE INDEX `pa_recovery_code_user` ON `pa_recovery_code`(`user_id`); +CREATE INDEX pa_master_keypair_application ON pa_master_keypair(application_id); -CREATE INDEX `pa_operation_user` ON `pa_operation`(`user_id`); +CREATE UNIQUE INDEX pa_app_version_app_key ON pa_application_version(application_key); -CREATE INDEX `pa_operation_ts_created_idx` ON `pa_operation`(`timestamp_created`); +CREATE INDEX pa_app_callback_app ON pa_application_callback(application_id); -CREATE INDEX `pa_operation_ts_expires_idx` ON `pa_operation`(`timestamp_expires`); +CREATE UNIQUE INDEX pa_integration_token ON pa_integration(client_token); -CREATE INDEX `pa_operation_template_name_idx` ON `pa_operation_template` (`template_name`); +CREATE INDEX pa_signature_audit_activation ON pa_signature_audit(activation_id); -CREATE UNIQUE INDEX `pa_recovery_code_puk` ON `pa_recovery_puk`(`recovery_code_id`, `puk_index`); +CREATE INDEX pa_signature_audit_created ON pa_signature_audit(timestamp_created); -CREATE UNIQUE INDEX `pa_application_name` ON `pa_application`(`name`); +CREATE INDEX pa_token_activation ON pa_token(activation_id); + +CREATE INDEX pa_recovery_code_code ON pa_recovery_code(recovery_code); + +CREATE INDEX pa_recovery_code_app ON pa_recovery_code(application_id); + +CREATE INDEX pa_recovery_code_user ON pa_recovery_code(user_id); + +CREATE INDEX pa_recovery_code_act ON pa_recovery_code(activation_id); + +CREATE UNIQUE INDEX pa_recovery_code_puk ON pa_recovery_puk(recovery_code_id, puk_index); + +CREATE INDEX pa_recovery_puk_code ON pa_recovery_puk(recovery_code_id); + +CREATE UNIQUE INDEX pa_recovery_config_app ON pa_recovery_config(application_id); + +CREATE UNIQUE INDEX pa_application_name ON pa_application(name); + +CREATE INDEX pa_operation_user ON pa_operation(user_id); + +CREATE INDEX pa_operation_ts_created_idx ON pa_operation(timestamp_created); + +CREATE INDEX pa_operation_ts_expires_idx ON pa_operation(timestamp_expires); + +CREATE INDEX pa_operation_template_name_idx ON pa_operation_template(template_name); -- -- Auditing indexes. diff --git a/docs/sql/oracle/create_schema.sql b/docs/sql/oracle/create_schema.sql index 1bce83249..0b713e0fb 100755 --- a/docs/sql/oracle/create_schema.sql +++ b/docs/sql/oracle/create_schema.sql @@ -359,6 +359,8 @@ CREATE INDEX PA_ACTIVATION_CODE ON PA_ACTIVATION(ACTIVATION_CODE); CREATE INDEX PA_ACTIVATION_USER_ID ON PA_ACTIVATION(USER_ID); +CREATE INDEX PA_ACTIVATION_EXPIRATION ON PA_ACTIVATION (ACTIVATION_STATUS, TIMESTAMP_ACTIVATION_EXPIRE); + CREATE INDEX PA_ACTIVATION_HISTORY_ACT ON PA_ACTIVATION_HISTORY(ACTIVATION_ID); CREATE INDEX PA_ACTIVATION_HISTORY_CREATED ON PA_ACTIVATION_HISTORY(TIMESTAMP_CREATED); diff --git a/docs/sql/postgresql/create_schema.sql b/docs/sql/postgresql/create_schema.sql index a1d748be6..c39b93eaa 100644 --- a/docs/sql/postgresql/create_schema.sql +++ b/docs/sql/postgresql/create_schema.sql @@ -354,6 +354,8 @@ CREATE INDEX pa_activation_code ON pa_activation(activation_code); CREATE INDEX pa_activation_user_id ON pa_activation(user_id); +CREATE INDEX pa_activation_expiration on pa_activation (activation_status, timestamp_activation_expire); + CREATE INDEX pa_activation_history_act ON pa_activation_history(activation_id); CREATE INDEX pa_activation_history_created ON pa_activation_history(timestamp_created);