You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2018/05/03 14:58:11 UTC
[4/8] syncope git commit: [SYNCOPE-1270] implementation for OpenID
Connect for Admin Console and Enduser
[SYNCOPE-1270] implementation for OpenID Connect for Admin Console and Enduser
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/f29e60f6
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/f29e60f6
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/f29e60f6
Branch: refs/heads/2_0_X
Commit: f29e60f62f12bc7ec77ce6de4d2674db466a8f4f
Parents: 13f442a
Author: dayash <di...@tirasa.net>
Authored: Wed May 2 09:50:13 2018 +0200
Committer: dayash <di...@tirasa.net>
Committed: Thu May 3 16:16:14 2018 +0200
----------------------------------------------------------------------
archetype/pom.xml | 31 ++
.../archetype-resources/console/pom.xml | 6 +
.../resources/archetype-resources/core/pom.xml | 11 +
.../archetype-resources/enduser/pom.xml | 6 +
.../resources/META-INF/resources/app/index.html | 1 +
.../resources/META-INF/resources/app/js/app.js | 27 +-
.../app/js/controllers/LoginController.js | 2 +
.../app/js/services/oidcProviderService.js | 42 ++
.../META-INF/resources/app/views/self.html | 8 +
deb/console/pom.xml | 13 +
deb/console/src/deb/control/conffiles | 2 +
deb/enduser/pom.xml | 13 +
deb/enduser/src/deb/control/conffiles | 2 +
deb/enduser/src/deb/control/preinst | 1 +
ext/oidcclient/agent/pom.xml | 126 ++++++
.../ext/oidcclient/agent/CodeConsumer.java | 92 ++++
.../syncope/ext/oidcclient/agent/Constants.java | 40 ++
.../syncope/ext/oidcclient/agent/Login.java | 89 ++++
.../oidcclient/agent/OIDCClientAgentSetup.java | 77 ++++
.../resources/oidcclient/loginError.jsp | 35 ++
.../resources/oidcclient/loginSuccess.jsp | 33 ++
.../main/resources/META-INF/web-fragment.xml | 26 ++
.../main/resources/oidcclient-agent.properties | 26 ++
ext/oidcclient/client-console/pom.xml | 83 ++++
.../client/console/pages/OIDCClient.java | 68 +++
.../client/console/pages/OIDCClientLogin.java | 68 +++
.../panels/OIDCProvidersDirectoryPanel.java | 291 +++++++++++++
.../console/panels/OIDCSSOLoginFormPanel.java | 109 +++++
.../console/rest/OIDCProviderRestClient.java | 59 +++
.../wizards/OIDCProviderMappingPanel.java | 104 +++++
.../wizards/OIDCProviderWizardBuilder.java | 290 +++++++++++++
.../client/console/pages/OIDCClient.html | 37 ++
.../client/console/pages/OIDCClient.properties | 17 +
.../console/pages/OIDCClient_it.properties | 17 +
.../console/pages/OIDCClient_pt_BR.properties | 17 +
.../console/pages/OIDCClient_ru.properties | 17 +
.../panels/OIDCProvidersDirectoryPanel.html | 23 +
.../OIDCProvidersDirectoryPanel.properties | 30 ++
.../OIDCProvidersDirectoryPanel_it.properties | 30 ++
...OIDCProvidersDirectoryPanel_pt_BR.properties | 30 ++
.../OIDCProvidersDirectoryPanel_ru.properties | 30 ++
.../console/panels/OIDCSSOLoginFormPanel.html | 25 ++
.../OIDCProviderWizardBuilder$Mapping.html | 23 +
.../wizards/OIDCProviderWizardBuilder$OP.html | 28 ++
.../OIDCProviderWizardBuilder$OP.properties | 24 ++
.../OIDCProviderWizardBuilder$OPContinue.html | 33 ++
...CProviderWizardBuilder$OPContinue.properties | 27 ++
...oviderWizardBuilder$OPContinue_it.properties | 27 ++
...derWizardBuilder$OPContinue_pt_BR.properties | 27 ++
...oviderWizardBuilder$OPContinue_ru.properties | 27 ++
.../OIDCProviderWizardBuilder$OP_it.properties | 24 ++
...IDCProviderWizardBuilder$OP_pt_BR.properties | 24 ++
.../OIDCProviderWizardBuilder$OP_ru.properties | 24 ++
ext/oidcclient/client-enduser/pom.xml | 83 ++++
.../client/enduser/pages/OIDCClientLogin.java | 63 +++
.../resources/OIDCProvidersResource.java | 72 ++++
ext/oidcclient/common-lib/pom.xml | 56 +++
.../syncope/common/lib/OIDCConstants.java | 45 ++
.../common/lib/to/OIDCLoginRequestTO.java | 91 ++++
.../common/lib/to/OIDCLoginResponseTO.java | 140 +++++++
.../syncope/common/lib/to/OIDCProviderTO.java | 229 ++++++++++
.../common/lib/types/OIDCClientEntitlement.java | 57 +++
ext/oidcclient/logic/pom.xml | 76 ++++
.../syncope/core/logic/OIDCClientLogic.java | 418 +++++++++++++++++++
.../syncope/core/logic/OIDCProviderLogic.java | 177 ++++++++
...ClientClassPathScanImplementationLookup.java | 78 ++++
.../core/logic/init/OIDCClientLoader.java | 55 +++
.../model/OIDCProviderDiscoveryDocument.java | 128 ++++++
.../core/logic/model/TokenEndpointResponse.java | 86 ++++
.../core/logic/oidc/OIDCUserManager.java | 306 ++++++++++++++
ext/oidcclient/persistence-api/pom.xml | 61 +++
.../persistence/api/dao/OIDCProviderDAO.java | 35 ++
.../api/entity/OIDCEntityFactory.java | 25 ++
.../persistence/api/entity/OIDCProvider.java | 84 ++++
.../api/entity/OIDCProviderItem.java | 29 ++
.../api/entity/OIDCUserTemplate.java | 27 ++
ext/oidcclient/persistence-jpa/pom.xml | 134 ++++++
.../persistence/jpa/dao/JPAOIDCProviderDAO.java | 78 ++++
.../jpa/entity/JPAOIDCEntityFactory.java | 49 +++
.../persistence/jpa/entity/JPAOIDCProvider.java | 257 ++++++++++++
.../jpa/entity/JPAOIDCProviderItem.java | 74 ++++
.../jpa/entity/JPAOIDCUserTemplate.java | 52 +++
ext/oidcclient/pom.xml | 55 +++
ext/oidcclient/provisioning-api/pom.xml | 67 +++
.../provisioning/api/OIDCProviderActions.java | 35 ++
.../api/data/OIDCProviderDataBinder.java | 32 ++
ext/oidcclient/provisioning-java/pom.xml | 61 +++
.../java/DefaultOIDCProviderActions.java | 48 +++
.../java/data/OIDCProviderDataBinderImpl.java | 266 ++++++++++++
ext/oidcclient/rest-api/pom.xml | 77 ++++
.../rest/api/service/OIDCClientService.java | 74 ++++
.../rest/api/service/OIDCProviderService.java | 151 +++++++
ext/oidcclient/rest-cxf/pom.xml | 72 ++++
.../rest/cxf/service/OIDCClientServiceImpl.java | 44 ++
.../cxf/service/OIDCProviderServiceImpl.java | 83 ++++
ext/pom.xml | 1 +
.../syncope/ext/saml2lsp/agent/Login.java | 2 +-
fit/console-reference/pom.xml | 6 +
.../main/resources/oidcclient-agent.properties | 26 ++
.../src/main/webapp/WEB-INF/web.xml | 10 +
.../src/test/resources/rebel.xml | 8 +
fit/core-reference/pom.xml | 23 +
.../org/apache/syncope/fit/AbstractITCase.java | 8 +
.../apache/syncope/fit/OIDCClientDetector.java | 52 +++
.../syncope/fit/core/OIDCClientITCase.java | 152 +++++++
fit/core-reference/src/test/resources/rebel.xml | 17 +
fit/enduser-reference/pom.xml | 6 +
.../main/resources/oidcclient-agent.properties | 26 ++
.../src/main/webapp/WEB-INF/web.xml | 10 +
.../src/test/resources/rebel.xml | 8 +
pom.xml | 10 +
.../reference-guide/concepts/extensions.adoc | 33 ++
.../workingwithapachesyncope/customization.adoc | 52 +++
113 files changed, 6920 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/archetype/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/pom.xml b/archetype/pom.xml
index baf1272..ee4d3fa 100644
--- a/archetype/pom.xml
+++ b/archetype/pom.xml
@@ -233,6 +233,13 @@ under the License.
</includes>
</resource>
<resource>
+ <directory>../ext/oidcclient/agent/src/main/resources</directory>
+ <targetPath>${project.build.outputDirectory}/archetype-resources/console/src/main/resources/all</targetPath>
+ <includes>
+ <include>oidcclient-agent.properties</include>
+ </includes>
+ </resource>
+ <resource>
<directory>../fit/console-reference/src/main/resources</directory>
<targetPath>${project.build.outputDirectory}/archetype-resources/console/src/main/resources</targetPath>
<includes>
@@ -250,6 +257,14 @@ under the License.
</includes>
</resource>
<resource>
+ <directory>../fit/console-reference/src/main/resources</directory>
+ <targetPath>${project.build.outputDirectory}/archetype-resources/console/src/test/resources</targetPath>
+ <includes>
+ <include>console.properties</include>
+ <include>oidcclient-agent.properties</include>
+ </includes>
+ </resource>
+ <resource>
<directory>../fit/console-reference/src/main/webapp/WEB-INF</directory>
<targetPath>${project.build.outputDirectory}/archetype-resources/console/src/main/webapp/WEB-INF</targetPath>
</resource>
@@ -270,6 +285,13 @@ under the License.
</includes>
</resource>
<resource>
+ <directory>../ext/oidcclient/agent/src/main/resources</directory>
+ <targetPath>${project.build.outputDirectory}/archetype-resources/enduser/src/main/resources/all</targetPath>
+ <includes>
+ <include>oidcclient-agent.properties</include>
+ </includes>
+ </resource>
+ <resource>
<directory>../client/enduser/src/main/resources/META-INF/resources/app</directory>
<targetPath>${project.build.outputDirectory}/archetype-resources/enduser/src/main/webapp/app</targetPath>
</resource>
@@ -290,6 +312,15 @@ under the License.
</includes>
</resource>
<resource>
+ <directory>../fit/enduser-reference/src/main/resources</directory>
+ <targetPath>${project.build.outputDirectory}/archetype-resources/enduser/src/test/resources</targetPath>
+ <includes>
+ <include>enduser.properties</include>
+ <include>oidcclient-agent.properties</include>
+ <include>customForm.json</include>
+ </includes>
+ </resource>
+ <resource>
<directory>../fit/enduser-reference/src/main/webapp/WEB-INF</directory>
<targetPath>${project.build.outputDirectory}/archetype-resources/enduser/src/main/webapp/WEB-INF</targetPath>
</resource>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/archetype/src/main/resources/archetype-resources/console/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/src/main/resources/archetype-resources/console/pom.xml b/archetype/src/main/resources/archetype-resources/console/pom.xml
index 8506fa9..287562a 100644
--- a/archetype/src/main/resources/archetype-resources/console/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/console/pom.xml
@@ -141,6 +141,12 @@ under the License.
</dependency>
<dependency>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+ <version>${syncope.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>org.apache.syncope.ext.scimv2</groupId>
<artifactId>syncope-ext-scimv2-client-console</artifactId>
<version>${syncope.version}</version>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/archetype/src/main/resources/archetype-resources/core/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/src/main/resources/archetype-resources/core/pom.xml b/archetype/src/main/resources/archetype-resources/core/pom.xml
index 3f3ef73..a24b17d 100644
--- a/archetype/src/main/resources/archetype-resources/core/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/core/pom.xml
@@ -193,6 +193,17 @@ under the License.
</dependency>
<dependency>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-rest-cxf</artifactId>
+ <version>${syncope.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-persistence-jpa</artifactId>
+ <version>${syncope.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>org.apache.syncope.ext.scimv2</groupId>
<artifactId>syncope-ext-scimv2-rest-cxf</artifactId>
<version>${syncope.version}</version>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/archetype/src/main/resources/archetype-resources/enduser/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/src/main/resources/archetype-resources/enduser/pom.xml b/archetype/src/main/resources/archetype-resources/enduser/pom.xml
index 2f9943c..4e8826c 100644
--- a/archetype/src/main/resources/archetype-resources/enduser/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/enduser/pom.xml
@@ -332,6 +332,12 @@ under the License.
<artifactId>syncope-ext-saml2sp-client-enduser</artifactId>
<version>${syncope.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-client-enduser</artifactId>
+ <version>${syncope.version}</version>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/client/enduser/src/main/resources/META-INF/resources/app/index.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/index.html b/client/enduser/src/main/resources/META-INF/resources/app/index.html
index cd4542a..2613a6e 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/index.html
+++ b/client/enduser/src/main/resources/META-INF/resources/app/index.html
@@ -100,6 +100,7 @@ under the License.
<script src="js/services/groupService.js"></script>
<script src="js/services/anyService.js"></script>
<script src="js/services/saml2IdPService.js"></script>
+ <script src="js/services/oidcProviderService.js"></script>
<script src="js/services/saml2SPService.js"></script>
<!--controllers-->
<script src="js/controllers/HomeController.js"></script>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/client/enduser/src/main/resources/META-INF/resources/app/js/app.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/app.js b/client/enduser/src/main/resources/META-INF/resources/app/js/app.js
index 3ae4f9d..1019cad 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/app.js
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/app.js
@@ -341,7 +341,8 @@ app.run(['$rootScope', '$location', '$state', 'AuthService',
};
}]);
app.controller('ApplicationController', ['$scope', '$rootScope', '$location', 'InfoService', 'SAML2IdPService',
- function ($scope, $rootScope, $location, InfoService, SAML2IdPService) {
+ 'OIDCProviderService',
+ function ($scope, $rootScope, $location, InfoService, SAML2IdPService, OIDCProviderService) {
$scope.initApplication = function () {
/*
* disable by default wizard buttons in self-registration
@@ -377,6 +378,10 @@ app.controller('ApplicationController', ['$scope', '$rootScope', '$location', 'I
available: [],
selected: {}
};
+ $rootScope.oidcops = {
+ available: [],
+ selected: {}
+ };
InfoService.getInfo().then(
function (response) {
@@ -406,6 +411,19 @@ app.controller('ApplicationController', ['$scope', '$rootScope', '$location', 'I
/*
* configuration getters
*/
+
+ /* <Extensions> */
+ OIDCProviderService.getAvailableOIDCProviders().then(
+ function (response) {
+ $rootScope.oidcops.available = response;
+ },
+ function (response) {
+ console.debug("No OIDC Client extension available", response);
+ });
+ /* </Extensions> */
+ /*
+ * configuration getters
+ */
$rootScope.isSelfRegAllowed = function () {
return $rootScope.selfRegAllowed === true;
};
@@ -418,6 +436,13 @@ app.controller('ApplicationController', ['$scope', '$rootScope', '$location', 'I
$rootScope.saml2login = function () {
window.location.href = '../saml2sp/login?idp=' + $rootScope.saml2idps.selected.entityID;
};
+
+ $rootScope.oidcclientExtAvailable = function () {
+ return $rootScope.oidcops.available.length > 0;
+ };
+ $rootScope.oidclogin = function () {
+ window.location.href = '../oidcclient/login?op=' + $rootScope.oidcops.selected.name;
+ };
$rootScope.getVersion = function () {
return $rootScope.version;
};
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
index b58aced..d2b755c 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
@@ -34,6 +34,8 @@ angular.module("login").controller("LoginController", ['$scope', '$rootScope', '
$scope.credentials.errorMessage = '';
// reset SAML 2.0 entityID
$rootScope.saml2idps.selected.entityID = null;
+ // reset OIDC name
+ $rootScope.oidcops.selected.name = null;
// got to update page
$location.path("/self/update");
}, function (response) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/client/enduser/src/main/resources/META-INF/resources/app/js/services/oidcProviderService.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/services/oidcProviderService.js b/client/enduser/src/main/resources/META-INF/resources/app/js/services/oidcProviderService.js
new file mode 100644
index 0000000..d2ce926
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/services/oidcProviderService.js
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+angular.module('self')
+ .factory('OIDCProviderService', ['$resource', '$q', '$http',
+ function ($resource, $q, $http) {
+
+ var oidcProviderService = {};
+
+ oidcProviderService.getAvailableOIDCProviders = function () {
+ return $http.get("../api/oidcProviders")
+ .then(function (response) {
+ return response.data;
+ }, function (response) {
+ console.error("Something went wrong during oidcProviders extension retrieval, exit with status: ",
+ response);
+ return $q.reject(response.data || response.statusText);
+ });
+ };
+
+ return oidcProviderService;
+ }]);
+
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/self.html b/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
index 1cc279e..cedb21c 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
@@ -62,6 +62,14 @@ under the License.
ng-model="saml2idps.selected" ng-change="saml2login()">
</select>
</div>
+ <div class="form-group">
+ <span ng-if="$root.oidcclientExtAvailable()">OpenID Connect</span>
+ <select id="oiscclient" style="width: 100%; text-align: left;" class="btn dropdown-toggle btn-default"
+ ng-if="$root.oidcclientExtAvailable()"
+ ng-options="op.name for op in oidcops.available track by op.name"
+ ng-model="oidcops.selected" ng-change="oidclogin()">
+ </select>
+ </div>
</fieldset>
</form>
</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/deb/console/pom.xml
----------------------------------------------------------------------
diff --git a/deb/console/pom.xml b/deb/console/pom.xml
index 9688af6..8898ce3 100644
--- a/deb/console/pom.xml
+++ b/deb/console/pom.xml
@@ -55,6 +55,11 @@ under the License.
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.syncope.ext.scimv2</groupId>
<artifactId>syncope-ext-scimv2-client-console</artifactId>
<version>${project.version}</version>
@@ -116,6 +121,14 @@ under the License.
<filtering>true</filtering>
</resource>
<resource>
+ <directory>${project.basedir}/../../ext/oidcclient/agent/src/main/resources</directory>
+ <includes>
+ <include>oidcclient-agent.properties</include>
+ </includes>
+ <targetPath>${project.build.directory}/etc</targetPath>
+ <filtering>true</filtering>
+ </resource>
+ <resource>
<directory>${basedir}/../../fit/console-reference/src/main/resources</directory>
<includes>
<include>log4j2.xml</include>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/deb/console/src/deb/control/conffiles
----------------------------------------------------------------------
diff --git a/deb/console/src/deb/control/conffiles b/deb/console/src/deb/control/conffiles
index 47e5201..a9bfb08 100644
--- a/deb/console/src/deb/control/conffiles
+++ b/deb/console/src/deb/control/conffiles
@@ -1,3 +1,5 @@
/etc/tomcat8/Catalina/localhost/syncope-console.xml
/etc/apache-syncope/console.properties
/etc/apache-syncope/saml2sp-agent.properties
+/etc/apache-syncope/oidcclient-agent.properties
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/deb/enduser/pom.xml
----------------------------------------------------------------------
diff --git a/deb/enduser/pom.xml b/deb/enduser/pom.xml
index fc2ce00..64505df 100644
--- a/deb/enduser/pom.xml
+++ b/deb/enduser/pom.xml
@@ -44,6 +44,11 @@ under the License.
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-client-enduser</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.syncope.client</groupId>
<artifactId>syncope-client-enduser</artifactId>
<version>${project.version}</version>
@@ -106,6 +111,14 @@ under the License.
<filtering>true</filtering>
</resource>
<resource>
+ <directory>${project.basedir}/../../ext/oidcclient/agent/src/main/resources</directory>
+ <includes>
+ <include>oidcclient-agent.properties</include>
+ </includes>
+ <targetPath>${project.build.directory}/etc</targetPath>
+ <filtering>true</filtering>
+ </resource>
+ <resource>
<directory>${basedir}/../../fit/enduser-reference/src/main/resources</directory>
<includes>
<include>log4j2.xml</include>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/deb/enduser/src/deb/control/conffiles
----------------------------------------------------------------------
diff --git a/deb/enduser/src/deb/control/conffiles b/deb/enduser/src/deb/control/conffiles
index 934c7fb..8fb2453 100644
--- a/deb/enduser/src/deb/control/conffiles
+++ b/deb/enduser/src/deb/control/conffiles
@@ -2,3 +2,5 @@
/etc/apache-syncope/enduser.properties
/etc/apache-syncope/customForm.json
/etc/apache-syncope/saml2sp-agent.properties
+/etc/apache-syncope/oidcclient-agent.properties
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/deb/enduser/src/deb/control/preinst
----------------------------------------------------------------------
diff --git a/deb/enduser/src/deb/control/preinst b/deb/enduser/src/deb/control/preinst
index afdca38..0e88785 100644
--- a/deb/enduser/src/deb/control/preinst
+++ b/deb/enduser/src/deb/control/preinst
@@ -16,3 +16,4 @@
# specific language governing permissions and limitations
# under the License.
dpkg-divert --add --package apache-syncope-enduser --rename --divert /etc/apache-syncope/saml2sp-agent.properties.disabled /etc/apache-syncope/saml2sp-agent.properties
+dpkg-divert --add --package apache-syncope-enduser --rename --divert /etc/apache-syncope/oidcclient-agent.properties.disabled /etc/apache-syncope/oidcclient-agent.properties
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/agent/pom.xml
----------------------------------------------------------------------
diff --git a/ext/oidcclient/agent/pom.xml b/ext/oidcclient/agent/pom.xml
new file mode 100644
index 0000000..adb83d1
--- /dev/null
+++ b/ext/oidcclient/agent/pom.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope.ext</groupId>
+ <artifactId>syncope-ext-oidcclient</artifactId>
+ <version>2.0.9-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Ext: OIDC Client Agent</name>
+ <description>Apache Syncope Ext: OIDC Client Agent</description>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-agent</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet.jsp</groupId>
+ <artifactId>javax.servlet.jsp-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jstl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.client</groupId>
+ <artifactId>syncope-client-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-rest-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+
+ <resource>
+ <directory>${basedir}</directory>
+ <targetPath>META-INF</targetPath>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ </includes>
+ </resource>
+ </resources>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>apache-release</id>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <inherited>false</inherited>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ <configuration>
+ <includes>
+ <include>${basedir}/LICENSE</include>
+ <include>${basedir}/NOTICE</include>
+ </includes>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/CodeConsumer.java
----------------------------------------------------------------------
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/CodeConsumer.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/CodeConsumer.java
new file mode 100644
index 0000000..08e9d23
--- /dev/null
+++ b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/CodeConsumer.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.ext.oidcclient.agent;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.OIDCConstants;
+import org.apache.syncope.common.lib.to.OIDCLoginResponseTO;
+import org.apache.syncope.common.rest.api.service.OIDCClientService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@WebServlet(name = "codeConsumer", urlPatterns = { "/oidcclient/code-consumer" })
+public class CodeConsumer extends HttpServlet {
+
+ private static final long serialVersionUID = 968480296813639041L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(CodeConsumer.class);
+
+ @Override
+ protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
+ throws ServletException, IOException {
+
+ try {
+ String authorizationCode = request.getParameter(OIDCConstants.CODE);
+ String state = request.getParameter(OIDCConstants.STATE);
+ if (StringUtils.isBlank(authorizationCode) || StringUtils.isBlank(state)) {
+ throw new IllegalArgumentException("Empty " + OIDCConstants.CODE + " or " + OIDCConstants.STATE);
+ }
+ if (state.equals(request.getSession().getAttribute(OIDCConstants.STATE).toString())) {
+ SyncopeClient anonymous = (SyncopeClient) request.getServletContext().
+ getAttribute(Constants.SYNCOPE_ANONYMOUS_CLIENT);
+
+ OIDCLoginResponseTO responseTO = anonymous.getService(OIDCClientService.class).login(
+ request.getRequestURL().toString(),
+ authorizationCode,
+ request.getSession().getAttribute(OIDCConstants.OP).toString());
+ request.getSession().setAttribute(
+ Constants.OIDCCLIENTJWT, responseTO.getAccessToken());
+ request.getSession().setAttribute(
+ Constants.OIDCCLIENTJWT_EXPIRE, responseTO.getAccessTokenExpiryTime());
+
+ String successURL = getServletContext().getInitParameter(Constants.CONTEXT_PARAM_LOGIN_SUCCESS_URL);
+ if (successURL == null) {
+ request.setAttribute("responseTO", responseTO);
+ request.getRequestDispatcher("loginSuccess.jsp").forward(request, response);
+ } else {
+ response.sendRedirect(successURL);
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid " + OIDCConstants.STATE + " provided");
+ }
+ } catch (Exception e) {
+ LOG.error("While processing authentication response from OP", e);
+ String errorURL = getServletContext().getInitParameter(Constants.CONTEXT_PARAM_LOGIN_ERROR_URL);
+
+ if (errorURL == null) {
+ request.setAttribute("exception", e);
+ request.getRequestDispatcher("loginError.jsp").forward(request, response);
+
+ e.printStackTrace(response.getWriter());
+ } else {
+ response.sendRedirect(errorURL + "?errorMessage="
+ + URLEncoder.encode(e.getMessage(), StandardCharsets.UTF_8.name()));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Constants.java
----------------------------------------------------------------------
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Constants.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Constants.java
new file mode 100644
index 0000000..1ff3327
--- /dev/null
+++ b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Constants.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.ext.oidcclient.agent;
+
+public final class Constants {
+
+ public static final String SYNCOPE_ANONYMOUS_CLIENT = "SyncopeAnonymousClient";
+
+ public static final String SYNCOPE_CLIENT_FACTORY = "SyncopeClientFactory";
+
+ public static final String PARAM_OP = "op";
+
+ public static final String CONTEXT_PARAM_LOGIN_SUCCESS_URL = "oidcclient.login.success.url";
+
+ public static final String CONTEXT_PARAM_LOGIN_ERROR_URL = "oidcclient.login.error.url";
+
+ public static final String OIDCCLIENTJWT = "oidcclient.jwt";
+
+ public static final String OIDCCLIENTJWT_EXPIRE = "oidcclient.jwt.expire";
+
+ private Constants() {
+ // private constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Login.java
----------------------------------------------------------------------
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Login.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Login.java
new file mode 100644
index 0000000..36850e4
--- /dev/null
+++ b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/Login.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.ext.oidcclient.agent;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriBuilder;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.OIDCConstants;
+import org.apache.syncope.common.lib.to.OIDCLoginRequestTO;
+import org.apache.syncope.common.rest.api.service.OIDCClientService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@WebServlet(name = "oidcclientLogin", urlPatterns = { "/oidcclient/login" })
+public class Login extends HttpServlet {
+
+ private static final long serialVersionUID = 968480296813639041L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(Login.class);
+
+ @Override
+ protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
+ throws ServletException, IOException {
+
+ String op = request.getParameter(Constants.PARAM_OP);
+
+ SyncopeClient anonymous = (SyncopeClient) request.getServletContext().
+ getAttribute(Constants.SYNCOPE_ANONYMOUS_CLIENT);
+ try {
+ String redirectURI = StringUtils.substringBefore(request.getRequestURL().toString(), "/login")
+ + "/code-consumer";
+ OIDCLoginRequestTO requestTO = anonymous.getService(OIDCClientService.class).
+ createLoginRequest(redirectURI, op);
+
+ request.getSession().setAttribute(OIDCConstants.STATE, requestTO.getState());
+ request.getSession().setAttribute(OIDCConstants.OP, op);
+
+ response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store");
+ response.setHeader("Pragma", "no-cache");
+ response.setStatus(HttpServletResponse.SC_SEE_OTHER);
+
+ UriBuilder ub = UriBuilder.fromUri(requestTO.getProviderAddress());
+ ub.queryParam(OIDCConstants.CLIENT_ID, requestTO.getClientId());
+ ub.queryParam(OIDCConstants.REDIRECT_URI, requestTO.getRedirectURI());
+ ub.queryParam(OIDCConstants.RESPOSNSE_TYPE, requestTO.getResponseType());
+ ub.queryParam(OIDCConstants.SCOPE, requestTO.getScope());
+ ub.queryParam(OIDCConstants.STATE, requestTO.getState());
+ response.setHeader("Location", ub.build().toASCIIString());
+ } catch (Exception e) {
+ LOG.error("While preparing the Authentication Request", e);
+
+ String errorURL = getServletContext().getInitParameter(Constants.CONTEXT_PARAM_LOGIN_ERROR_URL);
+ if (errorURL == null) {
+ request.setAttribute("exception", e);
+ request.getRequestDispatcher("loginError.jsp").forward(request, response);
+
+ e.printStackTrace(response.getWriter());
+ } else {
+ response.sendRedirect(errorURL + "?errorMessage="
+ + URLEncoder.encode(e.getMessage(), StandardCharsets.UTF_8.name()));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/OIDCClientAgentSetup.java
----------------------------------------------------------------------
diff --git a/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/OIDCClientAgentSetup.java b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/OIDCClientAgentSetup.java
new file mode 100644
index 0000000..887d0d6
--- /dev/null
+++ b/ext/oidcclient/agent/src/main/java/org/apache/syncope/ext/oidcclient/agent/OIDCClientAgentSetup.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.ext.oidcclient.agent;
+
+import java.util.Properties;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.PropertyUtils;
+
+@WebListener
+public class OIDCClientAgentSetup implements ServletContextListener {
+
+ private static final String OIDCCLIENT_AGENT_PROPERTIES = "oidcclient-agent.properties";
+
+ private static <T> T assertNotNull(final T argument, final String name) {
+ if (argument == null) {
+ throw new IllegalArgumentException("Argument '" + name + "' may not be null.");
+ }
+ return argument;
+ }
+
+ @Override
+ public void contextInitialized(final ServletContextEvent sce) {
+ // read oidcclientagent.properties
+ Properties props = PropertyUtils.read(getClass(), OIDCCLIENT_AGENT_PROPERTIES, "conf.directory").getLeft();
+
+ String anonymousUser = props.getProperty("anonymousUser");
+ assertNotNull(anonymousUser, "<anonymousUser>");
+ String anonymousKey = props.getProperty("anonymousKey");
+ assertNotNull(anonymousKey, "<anonymousKey>");
+
+ String scheme = props.getProperty("scheme");
+ assertNotNull(scheme, "<scheme>");
+ String host = props.getProperty("host");
+ assertNotNull(host, "<host>");
+ String port = props.getProperty("port");
+ assertNotNull(port, "<port>");
+ String rootPath = props.getProperty("rootPath");
+ assertNotNull(rootPath, "<rootPath>");
+ String useGZIPCompression = props.getProperty("useGZIPCompression");
+ assertNotNull(useGZIPCompression, "<useGZIPCompression>");
+
+ SyncopeClientFactoryBean clientFactory = new SyncopeClientFactoryBean().
+ setAddress(scheme + "://" + host + ":" + port + "/" + rootPath).
+ setUseCompression(BooleanUtils.toBoolean(useGZIPCompression));
+
+ sce.getServletContext().setAttribute(Constants.SYNCOPE_CLIENT_FACTORY, clientFactory);
+ sce.getServletContext().setAttribute(
+ Constants.SYNCOPE_ANONYMOUS_CLIENT,
+ clientFactory.create(new AnonymousAuthenticationHandler(anonymousUser, anonymousKey)));
+ }
+
+ @Override
+ public void contextDestroyed(final ServletContextEvent sce) {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginError.jsp
----------------------------------------------------------------------
diff --git a/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginError.jsp b/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginError.jsp
new file mode 100644
index 0000000..b3c80d9
--- /dev/null
+++ b/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginError.jsp
@@ -0,0 +1,35 @@
+<%--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+--%>
+<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%
+ Exception exception = (Exception) request.getAttribute("exception");
+%>
+<html>
+ <head>
+ <title>Apache Syncope ${syncope.version} - OIDC CLIENT - Login Error</title>
+ </head>
+ <body>
+ <h1>An error was found</h1>
+
+ <h2><%=exception.getMessage()%></h2>
+ <pre>
+ <%exception.printStackTrace(new java.io.PrintWriter(out));%>
+ </pre>
+ </body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginSuccess.jsp
----------------------------------------------------------------------
diff --git a/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginSuccess.jsp b/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginSuccess.jsp
new file mode 100644
index 0000000..7361842
--- /dev/null
+++ b/ext/oidcclient/agent/src/main/resources/META-INF/resources/oidcclient/loginSuccess.jsp
@@ -0,0 +1,33 @@
+<%--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+--%>
+<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%@page import="org.apache.syncope.common.lib.to.OIDCLoginResponseTO"%>
+<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
+<c:set var="responseTO" value="${requestScope['responseTO']}"/>
+<html>
+ <head>
+ <title>Apache Syncope ${syncope.version} - OIDC CLIENT - Successful Login</title>
+ </head>
+ <body>
+ <h1>Welcome ${responseTO.userName}</h1>
+
+ <p>You have been successfully authenticated by the requested OIDC Provider</p>
+
+ </body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/agent/src/main/resources/META-INF/web-fragment.xml
----------------------------------------------------------------------
diff --git a/ext/oidcclient/agent/src/main/resources/META-INF/web-fragment.xml b/ext/oidcclient/agent/src/main/resources/META-INF/web-fragment.xml
new file mode 100644
index 0000000..fab858a
--- /dev/null
+++ b/ext/oidcclient/agent/src/main/resources/META-INF/web-fragment.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+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.
+-->
+<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+ http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
+ id="${pom.artifactId}" version="3.1">
+
+</web-fragment>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/agent/src/main/resources/oidcclient-agent.properties
----------------------------------------------------------------------
diff --git a/ext/oidcclient/agent/src/main/resources/oidcclient-agent.properties b/ext/oidcclient/agent/src/main/resources/oidcclient-agent.properties
new file mode 100644
index 0000000..d3fee30
--- /dev/null
+++ b/ext/oidcclient/agent/src/main/resources/oidcclient-agent.properties
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+conf.directory=${conf.directory}
+
+anonymousUser=${anonymousUser}
+anonymousKey=${anonymousKey}
+
+scheme=http
+host=localhost
+port=8080
+rootPath=/syncope/rest/
+useGZIPCompression=true
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/client-console/pom.xml
----------------------------------------------------------------------
diff --git a/ext/oidcclient/client-console/pom.xml b/ext/oidcclient/client-console/pom.xml
new file mode 100644
index 0000000..51b190b
--- /dev/null
+++ b/ext/oidcclient/client-console/pom.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope.ext</groupId>
+ <artifactId>syncope-ext-oidcclient</artifactId>
+ <version>2.0.9-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Ext: OIDC Client Console</name>
+ <description>Apache Syncope Ext: OIDC Client Console</description>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-client-console</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-common-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-rest-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.ext.oidcclient</groupId>
+ <artifactId>syncope-ext-oidcclient-agent</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.client</groupId>
+ <artifactId>syncope-client-console</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClient.java
----------------------------------------------------------------------
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClient.java b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClient.java
new file mode 100644
index 0000000..f588733
--- /dev/null
+++ b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClient.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.pages;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
+import org.apache.syncope.client.console.annotations.ExtPage;
+import org.apache.syncope.client.console.panels.OIDCProvidersDirectoryPanel;
+import org.apache.syncope.common.lib.types.OIDCClientEntitlement;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+@ExtPage(label = "OIDC Client", icon = "fa-openid ", listEntitlement = OIDCClientEntitlement.OP_READ, priority = 100)
+public class OIDCClient extends BaseExtPage {
+
+ private static final long serialVersionUID = -599601954212606001L;
+
+ public OIDCClient(final PageParameters parameters) {
+ super(parameters);
+
+ body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
+
+ WebMarkupContainer content = new WebMarkupContainer("content");
+ content.setOutputMarkupId(true);
+ content.add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList()));
+ body.add(content);
+ }
+
+ private List<ITab> buildTabList() {
+
+ final List<ITab> tabs = new ArrayList<>(1);
+
+ tabs.add(new AbstractTab(new ResourceModel("op")) {
+ private static final long serialVersionUID = -6815067322125799251L;
+
+
+ @Override
+ public Panel getPanel(final String panelId) {
+ return new OIDCProvidersDirectoryPanel(panelId, getPageReference());
+ }
+ });
+
+ return tabs;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogin.java
----------------------------------------------------------------------
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogin.java b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogin.java
new file mode 100644
index 0000000..41b6cdc
--- /dev/null
+++ b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/pages/OIDCClientLogin.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.pages;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+
+import org.apache.wicket.authentication.IAuthenticationStrategy;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OIDCClientLogin extends WebPage {
+
+ private static final long serialVersionUID = 8581614051773949262L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(OIDCClientLogin.class);
+
+ private static final String OIDC_ACCESS_ERROR = "OIDC access error";
+
+ public OIDCClientLogin(final PageParameters parameters) {
+ super(parameters);
+
+ String token = (String) ((ServletWebRequest) getRequest()).getContainerRequest().
+ getSession().getAttribute(org.apache.syncope.ext.oidcclient.agent.Constants.OIDCCLIENTJWT);
+ if (StringUtils.isBlank(token)) {
+ LOG.error("No JWT found, redirecting to default greeter");
+
+ PageParameters params = new PageParameters();
+ params.add("errorMessage", OIDC_ACCESS_ERROR);
+ setResponsePage(Login.class, params);
+ }
+
+ IAuthenticationStrategy strategy = getApplication().getSecuritySettings().getAuthenticationStrategy();
+
+ if (SyncopeConsoleSession.get().authenticate(token)) {
+
+ // If login has been called because the user was not yet logged in, than continue to the
+ // original destination, otherwise to the Home page
+ continueToOriginalDestination();
+ setResponsePage(getApplication().getHomePage());
+ } else {
+ PageParameters params = new PageParameters();
+ params.add("errorMessage", OIDC_ACCESS_ERROR);
+ setResponsePage(Login.class, params);
+ }
+ strategy.remove();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
new file mode 100644
index 0000000..dd66cc6
--- /dev/null
+++ b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
@@ -0,0 +1,291 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.DirectoryDataProvider;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
+import org.apache.syncope.client.console.pages.BasePage;
+import org.apache.syncope.client.console.panels.OIDCProvidersDirectoryPanel.OIDCProvidersProvider;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
+import org.apache.syncope.client.console.rest.OIDCProviderRestClient;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
+import org.apache.syncope.client.console.wizards.AjaxWizard;
+import org.apache.syncope.client.console.wizards.OIDCProviderWizardBuilder;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.any.AnyWrapper;
+import org.apache.syncope.client.console.wizards.any.UserTemplateWizardBuilder;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.OIDCProviderTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.OIDCClientEntitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.StringResourceModel;
+
+public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
+ OIDCProviderTO, OIDCProviderTO, OIDCProvidersProvider, OIDCProviderRestClient> {
+
+ private static final long serialVersionUID = -1356497878858616714L;
+
+ private static final String PREF_OIDC_PROVIDERS_PAGINATOR_ROWS = "oidc.providers.paginator.rows";
+
+ private final BaseModal<Serializable> templateModal;
+
+ public OIDCProvidersDirectoryPanel(final String id, final PageReference pageRef) {
+ super(id, new Builder<OIDCProviderTO, OIDCProviderTO, OIDCProviderRestClient>(new OIDCProviderRestClient(),
+ pageRef) {
+
+ private static final long serialVersionUID = -5542535388772406165L;
+
+ @Override
+ protected WizardMgtPanel<OIDCProviderTO> newInstance(final String id, final boolean wizardInModal) {
+ throw new UnsupportedOperationException();
+ }
+ }.disableCheckBoxes());
+
+ this.addNewItemPanelBuilder(new OIDCProviderWizardBuilder(this, new OIDCProviderTO(), pageRef), true);
+ MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, OIDCClientEntitlement.OP_CREATE);
+
+ modal.size(Modal.Size.Large);
+
+ actionTogglePanel = new ActionLinksTogglePanel<OIDCProviderTO>("outer", pageRef) {
+
+ private static final long serialVersionUID = -7688359318035249200L;
+
+ @Override
+ public void toggleWithContent(
+ final AjaxRequestTarget target,
+ final ActionsPanel<OIDCProviderTO> actionsPanel,
+ final OIDCProviderTO modelObject) {
+
+ super.toggleWithContent(target, actionsPanel, modelObject);
+ setHeader(target, StringUtils.abbreviate(modelObject.getName(), 25));
+ this.toggle(target, true);
+ }
+
+ };
+ addOuterObject(actionTogglePanel);
+
+ templateModal = new BaseModal<Serializable>("outer") {
+
+ private static final long serialVersionUID = 5787433530654262016L;
+
+ @Override
+ protected void onConfigure() {
+ super.onConfigure();
+ setFooterVisible(false);
+ }
+ };
+ templateModal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+ private static final long serialVersionUID = 8804221891699487139L;
+
+ @Override
+ public void onClose(final AjaxRequestTarget target) {
+// target.add(content);
+ templateModal.show(false);
+ }
+ });
+ templateModal.size(Modal.Size.Large);
+ addOuterObject(templateModal);
+
+ initResultTable();
+
+ }
+
+ @Override
+ protected OIDCProvidersProvider dataProvider() {
+ return new OIDCProvidersProvider(rows);
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return PREF_OIDC_PROVIDERS_PAGINATOR_ROWS;
+
+ }
+
+ @Override
+ protected List<IColumn<OIDCProviderTO, String>> getColumns() {
+ List<IColumn<OIDCProviderTO, String>> columns = new ArrayList<>();
+ columns.add(new KeyPropertyColumn<OIDCProviderTO>(new ResourceModel("key"), "key", "key"));
+ columns.add(new PropertyColumn<OIDCProviderTO, String>(new ResourceModel("name"), "name", "name"));
+ columns.add(new PropertyColumn<OIDCProviderTO, String>(new ResourceModel("issuer"), "issuer", "issuer"));
+ columns.add(new PropertyColumn<OIDCProviderTO, String>(new ResourceModel("clientID"), "clientID", "clientID"));
+ return columns;
+
+ }
+
+ @Override
+ protected Collection<ActionLink.ActionType> getBulkActions() {
+ return Collections.<ActionLink.ActionType>emptyList();
+
+ }
+
+ @Override
+ public ActionsPanel<OIDCProviderTO> getActions(final IModel<OIDCProviderTO> model) {
+ final ActionsPanel<OIDCProviderTO> panel = super.getActions(model);
+
+ panel.add(new ActionLink<OIDCProviderTO>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final OIDCProviderTO ignore) {
+ OIDCProviderTO object = restClient.read(model.getObject().getKey());
+ send(OIDCProvidersDirectoryPanel.this, Broadcast.EXACT,
+ new AjaxWizard.EditItemActionEvent<>(object, target));
+ modal.header(Model.of(StringUtils.capitalize(("Edit " + object.getName()))));
+ }
+ }, ActionLink.ActionType.EDIT, OIDCClientEntitlement.OP_UPDATE);
+
+ panel.add(new ActionLink<OIDCProviderTO>() {
+
+ private static final long serialVersionUID = 8557679125857348178L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final OIDCProviderTO ignore) {
+ final OIDCProviderTO object = restClient.read(model.getObject().getKey());
+
+ UserTemplateWizardBuilder builder = new UserTemplateWizardBuilder(
+ object.getUserTemplate(),
+ new AnyTypeRestClient().read(AnyTypeKind.USER.name()).getClasses(),
+ new UserFormLayoutInfo(),
+ pageRef) {
+
+ private static final long serialVersionUID = -7978723352517770634L;
+
+ @Override
+ protected Serializable onApplyInternal(final AnyWrapper<UserTO> modelObject) {
+ object.setUserTemplate(modelObject.getInnerObject());
+ restClient.update(object);
+
+ return modelObject;
+ }
+ };
+ templateModal.header(Model.of(StringUtils.capitalize(
+ new StringResourceModel("template.title", OIDCProvidersDirectoryPanel.this).getString())));
+ templateModal.setContent(builder.build(BaseModal.CONTENT_ID));
+ templateModal.show(true);
+ target.add(templateModal);
+
+ }
+ }, ActionLink.ActionType.TEMPLATE, OIDCClientEntitlement.OP_UPDATE);
+
+ panel.add(new ActionLink<OIDCProviderTO>() {
+
+ private static final long serialVersionUID = -5467832321897812767L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final OIDCProviderTO ignore) {
+ try {
+ restClient.delete(model.getObject().getKey());
+ SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+ target.add(container);
+ } catch (SyncopeClientException e) {
+ LOG.error("While deleting object {}", model.getObject().getKey(), e);
+ SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
+ ? e.getClass().getName() : e.getMessage());
+ }
+ ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+ }
+ }, ActionLink.ActionType.DELETE, OIDCClientEntitlement.OP_DELETE, true);
+ return panel;
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ super.onEvent(event);
+
+ if (event.getPayload() instanceof AjaxWizard.NewItemEvent) {
+ AjaxWizard.NewItemEvent<?> newItemEvent = AjaxWizard.NewItemEvent.class.cast(event.getPayload());
+ WizardModalPanel<?> modalPanel = newItemEvent.getModalPanel();
+
+ if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
+ final IModel<Serializable> model = new CompoundPropertyModel<>(modalPanel.getItem());
+ templateModal.setFormModel(model);
+ templateModal.header(newItemEvent.getResourceModel());
+ newItemEvent.getTarget().add(templateModal.setContent(modalPanel));
+ templateModal.show(true);
+ } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
+ templateModal.close(newItemEvent.getTarget());
+ } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
+ templateModal.close(newItemEvent.getTarget());
+ }
+ }
+ }
+
+ protected final class OIDCProvidersProvider extends DirectoryDataProvider<OIDCProviderTO> {
+
+ private static final long serialVersionUID = -2865055116864423761L;
+
+ private final SortableDataProviderComparator<OIDCProviderTO> comparator;
+
+ public OIDCProvidersProvider(final int paginatorRows) {
+ super(paginatorRows);
+
+ setSort("name", SortOrder.ASCENDING);
+ comparator = new SortableDataProviderComparator<>(this);
+ }
+
+ @Override
+ public Iterator<OIDCProviderTO> iterator(final long first, final long count) {
+ List<OIDCProviderTO> list = restClient.list();
+ Collections.sort(list, comparator);
+ return list.subList((int) first, (int) first + (int) count).iterator();
+ }
+
+ @Override
+ public long size() {
+ return restClient.list().size();
+ }
+
+ @Override
+ public IModel<OIDCProviderTO> model(final OIDCProviderTO object) {
+ return new CompoundPropertyModel<>(object);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.java
----------------------------------------------------------------------
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.java b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.java
new file mode 100644
index 0000000..5b108e5
--- /dev/null
+++ b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCSSOLoginFormPanel.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.panels;
+
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.common.lib.to.OIDCProviderTO;
+import org.apache.syncope.common.rest.api.service.OIDCProviderService;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.markup.html.form.IChoiceRenderer;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.request.UrlUtils;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.http.handler.RedirectRequestHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OIDCSSOLoginFormPanel extends SSOLoginFormPanel {
+
+ private static final long serialVersionUID = 1154933731474854671L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(OIDCSSOLoginFormPanel.class);
+
+ public OIDCSSOLoginFormPanel(final String id) {
+ super(id);
+
+ List<OIDCProviderTO> available =
+ SyncopeConsoleSession.get().getAnonymousClient().getService(OIDCProviderService.class).list();
+
+ final Model<OIDCProviderTO> model = new Model<>();
+ AjaxDropDownChoicePanel<OIDCProviderTO> ops =
+ new AjaxDropDownChoicePanel<>("ops", "OpenID Connect", model, false);
+ ops.setChoices(available);
+ ops.setChoiceRenderer(new IChoiceRenderer<OIDCProviderTO>() {
+
+ private static final long serialVersionUID = 1814750973898916102L;
+
+ @Override
+ public Object getDisplayValue(final OIDCProviderTO object) {
+ return object.getName();
+ }
+
+ @Override
+ public String getIdValue(final OIDCProviderTO object, final int index) {
+ return object.getName();
+ }
+
+ @Override
+ public OIDCProviderTO getObject(final String id,
+ final IModel<? extends List<? extends OIDCProviderTO>> choices) {
+ return IterableUtils.find(choices.getObject(), new Predicate<OIDCProviderTO>() {
+
+ @Override
+ public boolean evaluate(final OIDCProviderTO object) {
+ return object.getName().equals(id);
+ }
+ });
+ }
+ });
+
+ ops.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ if (model.getObject() != null) {
+ try {
+ RequestCycle.get().scheduleRequestHandlerAfterCurrent(new RedirectRequestHandler(
+ UrlUtils.rewriteToContextRelative("oidcclient/login?op="
+ + URLEncoder.encode(
+ model.getObject().getName(), StandardCharsets.UTF_8.name()),
+ RequestCycle.get())));
+ } catch (Exception e) {
+ LOG.error("Could not redirect to the selected OP {}", model.getObject().getName(), e);
+ }
+ }
+ }
+ });
+ ops.setOutputMarkupPlaceholderTag(true);
+ ops.setVisible(!available.isEmpty());
+ add(ops);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f29e60f6/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/rest/OIDCProviderRestClient.java
----------------------------------------------------------------------
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/rest/OIDCProviderRestClient.java b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/rest/OIDCProviderRestClient.java
new file mode 100644
index 0000000..a666d74
--- /dev/null
+++ b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/rest/OIDCProviderRestClient.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.rest;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.common.lib.to.OIDCProviderTO;
+import org.apache.syncope.common.rest.api.service.OIDCProviderService;
+
+public class OIDCProviderRestClient extends BaseRestClient {
+
+ private static final long serialVersionUID = -4006712447589576324L;
+
+ public List<OIDCProviderTO> list() {
+ return getService(OIDCProviderService.class).list();
+ }
+
+ public Set<String> getActionsClasses() {
+ return getService(OIDCProviderService.class).getActionsClasses();
+ }
+
+ public void create(final OIDCProviderTO op) {
+ SyncopeConsoleSession.get().getService(OIDCProviderService.class).create(op);
+ }
+
+ public void createFromDiscovery(final OIDCProviderTO op) {
+ SyncopeConsoleSession.get().getService(OIDCProviderService.class).createFromDiscovery(op);
+ }
+
+ public OIDCProviderTO read(final String key) {
+ return getService(OIDCProviderService.class).read(key);
+ }
+
+ public void update(final OIDCProviderTO op) {
+ getService(OIDCProviderService.class).update(op);
+ }
+
+ public void delete(final String key) {
+ getService(OIDCProviderService.class).delete(key);
+ }
+
+}