This is an automated email from the ASF dual-hosted git repository.

buhhunyx pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf-fediz.git


The following commit(s) were added to refs/heads/master by this push:
     new 45c9e35  FEDIZ-245 OIDC: Client Update (#52)
45c9e35 is described below

commit 45c9e3597f5c5c8c18a2d80d5f4385930c938841
Author: Alexey Markevich <[email protected]>
AuthorDate: Mon Jun 15 12:50:29 2020 +0300

    FEDIZ-245 OIDC: Client Update (#52)
    
    * FEDIZ-245 OIDC: Client Update
    
    * Change null to an empty list
---
 .../oidc/clients/ClientRegistrationService.java    | 228 +++++++++++++--------
 .../cxf/fediz/service/oidc/clients/EditClient.java |  43 ++++
 .../oidc/src/main/webapp/WEB-INF/views/client.jsp  |  28 +--
 .../views/{registerClient.jsp => editClient.jsp}   |  44 ++--
 .../main/webapp/WEB-INF/views/registerClient.jsp   |  14 +-
 .../webapp/WEB-INF/views/registeredClients.jsp     |   2 +-
 .../cxf/fediz/systests/oidc/AbstractOIDCTest.java  |  43 +++-
 7 files changed, 270 insertions(+), 132 deletions(-)

diff --git 
a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/clients/ClientRegistrationService.java
 
b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/clients/ClientRegistrationService.java
index 8d063b1..08eb8db 100644
--- 
a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/clients/ClientRegistrationService.java
+++ 
b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/clients/ClientRegistrationService.java
@@ -77,7 +77,6 @@ public class ClientRegistrationService {
     private static final Logger LOG = 
LogUtils.getL7dLogger(ClientRegistrationService.class);
 
     private final Map<String, Collection<Client>> registrations = new 
HashMap<>();
-    private final Map<String, Set<String>> clientNames = new HashMap<>();
     private OAuthDataProvider dataProvider;
     private ClientRegistrationProvider clientProvider;
     private Map<String, String> homeRealms = Collections.emptyMap();
@@ -121,6 +120,18 @@ public class ClientRegistrationService {
         return null;
     }
 
+    @GET
+    @Produces(MediaType.TEXT_HTML)
+    @Path("/{id}/edit")
+    public EditClient editClient(@PathParam("id") String id) {
+        checkSecurityContext();
+        for (Client c : getClientRegistrations()) {
+            if (c.getClientId().equals(id)) {
+                return new EditClient(c, homeRealms);
+            }
+        }
+        return null;
+    }
 
     @POST
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@@ -138,10 +149,6 @@ public class ClientRegistrationService {
             if (c.getClientId().equals(id)) {
                 clientProvider.removeClient(id);
                 it.remove();
-                Set<String> names = clientNames.get(getUserName());
-                if (names != null) {
-                    names.remove(c.getApplicationName());
-                }
                 break;
             }
         }
@@ -159,7 +166,7 @@ public class ClientRegistrationService {
 
         Client c = getRegisteredClient(id);
         if (c == null) {
-            throwInvalidRegistrationException("The client id is invalid");
+            throw new InvalidRegistrationException("The client id is invalid");
         }
         if (c.isConfidential()) {
             c.setClientSecret(generateClientSecret());
@@ -175,7 +182,7 @@ public class ClientRegistrationService {
         checkSecurityContext();
         Client c = getRegisteredClient(id);
         if (c == null) {
-            throwInvalidRegistrationException("The client id is invalid");
+            throw new InvalidRegistrationException("The client id is invalid");
         }
         return doGetClientIssuedTokens(c);
     }
@@ -220,7 +227,7 @@ public class ClientRegistrationService {
 
         Client c = getRegisteredClient(clientId);
         if (c == null) {
-            throwInvalidRegistrationException("The client id is invalid");
+            throw new InvalidRegistrationException("The client id is invalid");
         }
         dataProvider.revokeToken(c, tokenId, tokenType);
         return doGetClientIssuedTokens(c);
@@ -234,7 +241,7 @@ public class ClientRegistrationService {
         if (dataProvider instanceof AuthorizationCodeDataProvider) {
             Client c = getRegisteredClient(id);
             if (c == null) {
-                throwInvalidRegistrationException("The client id is invalid");
+                throw new InvalidRegistrationException("The client id is 
invalid");
             }
             UserSubject subject = new OidcUserSubject(getUserName());
             Collection<ServerAuthorizationCodeGrant> codeGrants = new 
TreeSet<>(
@@ -282,14 +289,14 @@ public class ClientRegistrationService {
 
             // Client Name
             if (StringUtils.isEmpty(appName)) {
-                throwInvalidRegistrationException("The client name must not be 
empty");
+                throw new InvalidRegistrationException("The client name must 
not be empty");
             }
             // Client Type
             if (StringUtils.isEmpty(appType)) {
-                throwInvalidRegistrationException("The client type must not be 
empty");
+                throw new InvalidRegistrationException("The client type must 
not be empty");
             }
             if (!("confidential".equals(appType) || "public".equals(appType))) 
{
-                throwInvalidRegistrationException("An invalid client type was 
specified: "
+                throw new InvalidRegistrationException("An invalid client type 
was specified: "
                     + StringEscapeUtils.escapeHtml4(appType));
             }
             // Client ID
@@ -310,66 +317,130 @@ public class ClientRegistrationService {
             // Client Registration Time
             newClient.setRegisteredAt(System.currentTimeMillis() / 1000);
 
-            // Client Realm
-            if (homeRealm != null) {
-                newClient.setHomeRealm(homeRealm);
-                if (homeRealms.containsKey(homeRealm)) {
-                    newClient.getProperties().put("homeRealmAlias", 
homeRealms.get(homeRealm));
-                }
+            updateClientDetails(newClient, audience, redirectURI, logoutURI, 
homeRealm);
+
+            // Client Scopes
+            if (clientScopes != null && !clientScopes.isEmpty()) {
+                newClient.setRegisteredScopes(new 
ArrayList<>(clientScopes.keySet()));
             }
 
-            // Client Redirect URIs
-            if (!StringUtils.isEmpty(redirectURI)) {
-                String[] allUris = redirectURI.trim().split(" ");
-                List<String> redirectUris = new ArrayList<>(allUris.length);
-                for (String uri : allUris) {
-                    if (!StringUtils.isEmpty(uri)) {
-                        if (!isValidURI(uri, false)) {
-                            throwInvalidRegistrationException("An invalid 
redirect URI was specified: "
-                                + StringEscapeUtils.escapeHtml4(uri));
-                        }
-                        redirectUris.add(uri);
+            return Response.ok(registerNewClient(newClient)).build();
+        } catch (InvalidRegistrationException ex) {
+            // For the view handlers to handle it
+            return Response.ok(new 
InvalidRegistration(ex.getMessage())).build();
+        }
+    }
+
+    @POST
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    @Produces(MediaType.TEXT_HTML)
+    @Path("/{id}")
+    public Response editForm(@PathParam("id") String clientId,
+                             @FormParam("client_name") String appName,
+                             @FormParam("client_audience") String audience,
+                             @FormParam("client_redirectURI") String 
redirectURI,
+                             @FormParam("client_logoutURI") String logoutURI,
+                             @FormParam("client_homeRealm") String homeRealm,
+                             @FormParam("client_csrfToken") String csrfToken
+    ) {
+        try {
+            // CSRF
+            checkCSRFToken(csrfToken);
+            // checkSecurityContext();
+            Client client = getRegisteredClient(clientId);
+
+            // Client Name
+            if (StringUtils.isEmpty(appName)) {
+                throw new InvalidRegistrationException("The client name must 
not be empty");
+            }
+
+            updateClientDetails(client, audience, redirectURI, logoutURI, 
homeRealm);
+
+            if (!client.getApplicationName().equals(appName)) {
+                Collection<Client> clientRegistrations = 
getClientRegistrations(
+                    client.getResourceOwnerSubject().getLogin());
+                for (Iterator<Client> it = clientRegistrations.iterator(); 
it.hasNext();) {
+                    Client c = it.next();
+                    if (c.getClientId().equals(clientId)) {
+                        it.remove();
+                        break;
                     }
                 }
-                newClient.setRedirectUris(redirectUris);
+                client.setApplicationName(appName);
+                updateClientApplicationName(client, clientRegistrations);
+                clientRegistrations.add(client);
             }
-            // Client Logout URI
-            if (!StringUtils.isEmpty(logoutURI)) {
-                String[] logoutUris = logoutURI.split(" ");
-                for (String uri : logoutUris) {
+
+            clientProvider.setClient(client);
+
+            return Response.ok(client).build();
+        } catch (InvalidRegistrationException ex) {
+            // For the view handlers to handle it
+            return Response.ok(new 
InvalidRegistration(ex.getMessage())).build();
+        }
+    }
+
+    private void updateClientDetails(final Client client,
+        String audience, String redirectURI, String logoutURI, String 
homeRealm) {
+        // Client Redirect URIs
+        if (!StringUtils.isEmpty(redirectURI)) {
+            String[] allUris = redirectURI.trim().split(" ");
+            List<String> redirectUris = new ArrayList<>(allUris.length);
+            for (String uri : allUris) {
+                if (!StringUtils.isEmpty(uri)) {
                     if (!isValidURI(uri, false)) {
-                        throwInvalidRegistrationException("An invalid logout 
URI was specified: "
+                        throw new InvalidRegistrationException("An invalid 
redirect URI was specified: "
                             + StringEscapeUtils.escapeHtml4(uri));
                     }
+                    redirectUris.add(uri);
                 }
-                //TODO: replace this code with newClient.setLogoutUri() once 
it becomes available
-                newClient.getProperties().put("post_logout_redirect_uris", 
logoutURI);
             }
+            client.setRedirectUris(redirectUris);
+        } else {
+            client.setRedirectUris(Collections.emptyList());
+        }
 
-            // Client Audience URIs
-            if (!StringUtils.isEmpty(audience)) {
-                String[] auds = audience.trim().split(" ");
-                List<String> registeredAuds = new ArrayList<>(auds.length);
-                for (String aud : auds) {
-                    if (!StringUtils.isEmpty(aud)) {
-                        if (!isValidURI(aud, true)) {
-                            throwInvalidRegistrationException("An invalid 
audience URI was specified: "
-                                + StringEscapeUtils.escapeHtml4(aud));
-                        }
-                        registeredAuds.add(aud);
+        // Client Logout URI
+        if (!StringUtils.isEmpty(logoutURI)) {
+            String[] logoutUris = logoutURI.split(" ");
+            for (String uri : logoutUris) {
+                if (!isValidURI(uri, false)) {
+                    throw new InvalidRegistrationException("An invalid logout 
URI was specified: "
+                        + StringEscapeUtils.escapeHtml4(uri));
+                }
+            }
+            //TODO: replace this code with newClient.setLogoutUri() once it 
becomes available
+            client.getProperties().put("post_logout_redirect_uris", logoutURI);
+        } else {
+            client.getProperties().remove("post_logout_redirect_uris");
+        }
+
+        // Client Audience URIs
+        if (!StringUtils.isEmpty(audience)) {
+            String[] auds = audience.trim().split(" ");
+            List<String> registeredAuds = new ArrayList<>(auds.length);
+            for (String aud : auds) {
+                if (!StringUtils.isEmpty(aud)) {
+                    if (!isValidURI(aud, true)) {
+                        throw new InvalidRegistrationException("An invalid 
audience URI was specified: "
+                            + StringEscapeUtils.escapeHtml4(aud));
                     }
+                    registeredAuds.add(aud);
                 }
-                newClient.setRegisteredAudiences(registeredAuds);
             }
+            client.setRegisteredAudiences(registeredAuds);
+        } else {
+            client.setRegisteredAudiences(Collections.emptyList());
+        }
 
-            // Client Scopes
-            if (clientScopes != null && !clientScopes.isEmpty()) {
-                newClient.setRegisteredScopes(new 
ArrayList<>(clientScopes.keySet()));
+        // Client Realm
+        if (homeRealm != null) {
+            client.setHomeRealm(homeRealm);
+            if (homeRealms.containsKey(homeRealm)) {
+                client.getProperties().put("homeRealmAlias", 
homeRealms.get(homeRealm));
+            } else {
+                client.getProperties().remove("homeRealmAlias");
             }
-            return Response.ok(registerNewClient(newClient)).build();
-        } catch (InvalidRegistrationException ex) {
-            // For the view handlers to handle it
-            return Response.ok(new 
InvalidRegistration(ex.getMessage())).build();
         }
     }
 
@@ -388,14 +459,10 @@ public class ClientRegistrationService {
         String savedToken = CSRFUtils.getCSRFToken(httpRequest, false);
         if (StringUtils.isEmpty(csrfToken) || StringUtils.isEmpty(savedToken)
             || !savedToken.equals(csrfToken)) {
-            throwInvalidRegistrationException("Invalid CSRF Token");
+            throw new InvalidRegistrationException("Invalid CSRF Token");
         }
     }
 
-    private void throwInvalidRegistrationException(String error) {
-        throw new InvalidRegistrationException(error);
-    }
-
     private static boolean isValidURI(String uri, boolean requireHttps) {
 
         final UrlValidator urlValidator;
@@ -439,13 +506,21 @@ public class ClientRegistrationService {
     }
 
     protected RegisteredClients registerNewClient(Client newClient) {
-        String userName = newClient.getResourceOwnerSubject().getLogin();
-        Set<String> names = clientNames.get(userName);
-        if (names == null) {
-            names = new HashSet<>();
-            clientNames.put(userName, names);
-        } else if (names.contains(newClient.getApplicationName())) {
-            String newName = newClient.getApplicationName();
+        Collection<Client> clientRegistrations = 
getClientRegistrations(newClient.getResourceOwnerSubject().getLogin());
+        updateClientApplicationName(newClient, clientRegistrations);
+
+        clientProvider.setClient(newClient);
+        clientRegistrations.add(newClient);
+        return new RegisteredClients(clientRegistrations);
+    }
+
+    private static void updateClientApplicationName(Client client, 
Collection<Client> clientRegistrations) {
+        Set<String> names = new HashSet<>();
+        for (Client c : clientRegistrations) {
+            names.add(c.getApplicationName());
+        }
+        if (names.contains(client.getApplicationName())) {
+            String newName = client.getApplicationName();
             SortedSet<Integer> numbers = new TreeSet<>();
             for (String name : names) {
                 if (name.startsWith(newName) && !name.equals(newName)) {
@@ -457,19 +532,12 @@ public class ClientRegistrationService {
                 }
             }
             int nextNumber = numbers.isEmpty() ? 2 : numbers.last() + 1;
-            newClient.setApplicationName(newName + nextNumber);
+            client.setApplicationName(newName + nextNumber);
         }
-        names.add(newClient.getApplicationName());
-
-        clientProvider.setClient(newClient);
-        Collection<Client> clientRegistrations = getClientRegistrations();
-        clientRegistrations.add(newClient);
-        return new RegisteredClients(clientRegistrations);
     }
 
     protected Collection<Client> getClientRegistrations() {
-        String userName = getUserName();
-        return getClientRegistrations(userName);
+        return getClientRegistrations(getUserName());
     }
 
     protected Collection<Client> getClientRegistrations(String userName) {
@@ -500,12 +568,6 @@ public class ClientRegistrationService {
             if (c.getResourceOwnerSubject() != null) {
                 String userName = c.getResourceOwnerSubject().getLogin();
                 getClientRegistrations(userName).add(c);
-                Set<String> names = clientNames.get(userName);
-                if (names == null) {
-                    names = new HashSet<>();
-                    clientNames.put(userName, names);
-                }
-                names.add(c.getApplicationName());
             }
         }
     }
diff --git 
a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/clients/EditClient.java
 
b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/clients/EditClient.java
new file mode 100644
index 0000000..350d830
--- /dev/null
+++ 
b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/clients/EditClient.java
@@ -0,0 +1,43 @@
+/**
+ * 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.cxf.fediz.service.oidc.clients;
+
+import java.util.Map;
+
+import org.apache.cxf.rs.security.oauth2.common.Client;
+
+public class EditClient {
+
+    private final Client client;
+    private final Map<String, String> homeRealms;
+
+    public EditClient(Client client, Map<String, String> homeRealms) {
+        this.client = client;
+        this.homeRealms = homeRealms;
+    }
+
+    public Client getClient() {
+        return client;
+    }
+
+    public Map<String, String> getHomeRealms() {
+        return homeRealms;
+    }
+
+}
diff --git a/services/oidc/src/main/webapp/WEB-INF/views/client.jsp 
b/services/oidc/src/main/webapp/WEB-INF/views/client.jsp
index b1ff4c5..f66f04b 100644
--- a/services/oidc/src/main/webapp/WEB-INF/views/client.jsp
+++ b/services/oidc/src/main/webapp/WEB-INF/views/client.jsp
@@ -9,11 +9,6 @@
 
 <%
        Client client = (Client)request.getAttribute("data");
-       String clientType = client.isConfidential() ? "Confidential" : "Public";
-       String homeRealmAlias = client.getProperties().get("homeRealmAlias");
-       if (homeRealmAlias == null || homeRealmAlias.trim().isEmpty()) {
-           homeRealmAlias = "Default - User selection at login";
-       } 
     String basePath = request.getContextPath() + request.getServletPath();
     if (!basePath.endsWith("/")) {
         basePath += "/";
@@ -77,7 +72,7 @@
 </head>
 <body>
 <div class="padded">
-<h1><%= StringEscapeUtils.escapeHtml4(client.getApplicationName()) %></h1>
+<h1><a href="<%= basePath + "console/clients/" + client.getClientId() + 
"/edit" %>"><%= StringEscapeUtils.escapeHtml4(client.getApplicationName()) 
%></a></h1>
 <br/>
 <table border="1" id=client>
     <%
@@ -90,7 +85,7 @@
                <%= client.getClientId() %>
            </td>
            <td>
-               <%= clientType %>
+               <%= client.isConfidential() ? "Confidential" : "Public" %>
            </td> 
            <td>
            <%
@@ -110,7 +105,7 @@
                Date date = new Date(client.getRegisteredAt() * 1000);
                String created = dateFormat.format(date);
                   %>
-           <%=    created %><br/>
+           <%=    created %>
            
            </td>
            
@@ -126,6 +121,11 @@
 <b>Home Realm</b>
 </td>
 <td>
+<%  String homeRealmAlias = client.getProperties().get("homeRealmAlias");
+    if (homeRealmAlias == null || homeRealmAlias.trim().isEmpty()) {
+        homeRealmAlias = "Default - User selection at login";
+    }
+%> 
     <%=  homeRealmAlias %>
 </td>
 </tr>
@@ -185,10 +185,10 @@
     <div class="form-line">
         <input type="hidden" value="<%=token%>" name="client_csrfToken" />
     </div>
-     <div data-type="control_button" class="form-line">
-       <button name="submit_reset_button" class="form-submit-button" 
type="submit">Reset Client Secret</button>
+    <div data-type="control_button" class="form-line">
+        <button name="submit_reset_button" class="form-submit-button" 
type="submit">Reset Client Secret</button>
+    </div>
 </form>
-     </div> 
 </td>
 <%
     }
@@ -198,9 +198,9 @@
     <div class="form-line">
         <input type="hidden" value="<%=token%>" name="client_csrfToken" />
     </div>
-        <div data-type="control_button" class="form-line">
-       <button name="submit_delete_button" class="form-submit-button" 
type="submit">Delete Client</button>
-        </div>
+    <div data-type="control_button" class="form-line">
+       <button name="submit_delete_button" class="form-submit-button" 
type="submit">Delete Client</button>
+    </div>
 </form>
 </td>
 </tr>
diff --git a/services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp 
b/services/oidc/src/main/webapp/WEB-INF/views/editClient.jsp
similarity index 59%
copy from services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp
copy to services/oidc/src/main/webapp/WEB-INF/views/editClient.jsp
index ffe0541..4f24410 100644
--- a/services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp
+++ b/services/oidc/src/main/webapp/WEB-INF/views/editClient.jsp
@@ -1,9 +1,10 @@
 <%@ page
-       
import="javax.servlet.http.HttpServletRequest,java.util.Map,java.util.Iterator,org.apache.cxf.fediz.service.oidc.clients.RegisterClient,
-       org.apache.cxf.fediz.service.oidc.CSRFUtils"
+       import="javax.servlet.http.HttpServletRequest, java.util.Map, 
org.apache.cxf.fediz.service.oidc.clients.EditClient,
+        org.apache.cxf.rs.security.oauth2.common.Client, 
org.apache.cxf.fediz.service.oidc.CSRFUtils"
 %>
 <%
-    RegisterClient reg = (RegisterClient)request.getAttribute("data");
+    EditClient editClient = (EditClient)request.getAttribute("data");
+    Client c = editClient.getClient();
     String basePath = request.getContextPath() + request.getServletPath();
     if (!basePath.endsWith("/")) {
         basePath += "/";
@@ -66,55 +67,50 @@ input, select, button {
 </style>
 </head>
 <body>
-       <form action="<%=basePath%>console/clients" method="POST">
+       <form action="<%= basePath + "console/clients/" + c.getClientId() %>" 
method="POST">
                <div class="form">
                        <div class="header-text">
-                               <h2>OIDC Client Registration</h2>
+                               <h2>OIDC Client Modification</h2>
                        </div>
                        <div class="form-line">
-                               <label for="client_name" id="label_name" 
class="form-label"> Name <span class="form-required"> * </span></label>
-                               <input placeholder="OIDC Client Name" 
type="text" value=""
+                               <label for="client_name" id="label_name" 
class="form-label"> Name </label>
+                               <input placeholder="OIDC Client Name" 
type="text" value="<%=c.getApplicationName()%>"
                                        size="40" name="client_name" 
id="input_name" data-type="input-textbox" />
                        </div>
                        <div class="form-line">
-                               <label for="client_type" id="label_type" 
class="form-label"> Type <span class="form-required"> * </span></label>
-                               <select name="client_type" id="input_type">
-                                       <option value="confidential" 
selected="selected">Confidential</option>
-                                       <option value="public">Public</option>
+                               <label for="client_type" id="label_type" 
class="form-label"> Type </label>
+                               <select name="client_type" id="input_type" 
disabled="true">
+                                       <option selected="selected"><%= 
c.isConfidential() ? "Confidential" : "Public" %></option>
                                </select>
                        </div>
                        <div class="form-line">
                                <label for="client_redirectURI" 
id="label_redirect" class="form-label"> Redirect URL </label>
-                               <input type="text" value="" size="40" 
name="client_redirectURI"
+                               <input type="text" value="<%= 
c.getRedirectUris() != null ? String.join(" ", c.getRedirectUris()) : "" %>" 
size="40" name="client_redirectURI"
                                        placeholder="URL of the client to 
consume OIDC service response"
                                        id="input_6" data-type="input-textbox" 
/>
                        </div>
                        <div class="form-line">
                                <label for="client_audience" 
id="label_audience" class="form-label"> Audience URL </label>
-                               <input type="text" value="" size="40" 
name="client_audience"
+                               <input type="text" value="<%= 
c.getRegisteredAudiences() != null ? String.join(" ", 
c.getRegisteredAudiences()) : "" %>" size="40" name="client_audience"
                                        placeholder="URL of the server the 
tokens will be restricted to"
                                        id="input_7" data-type="input-textbox" 
/>
                        </div>
                        <div class="form-line">
                                <label for="client_logoutURI" id="label_logout" 
class="form-label"> Logout URL </label>
-                               <input type="text" value="" size="40" 
name="client_logoutURI"
+                               <input type="text" value="<%= 
c.getProperties().get("post_logout_redirect_uris") != null ? 
c.getProperties().get("post_logout_redirect_uris") : "" %>" size="40" 
name="client_logoutURI"
                                        placeholder="URL of the client to 
finalize OIDC logout process"
                                        id="input_6" data-type="input-textbox" 
/>
                        </div>
                        <div class="form-line">
                                <label for="client_homeRealm" 
id="label_homeRealm" class="form-label"> Home Realm </label>
                                <select name="client_homeRealm" 
id="input_homeRealm">
-                                       <option value="" selected>Default - 
User selection at login</option>
+                                       <option value="" <%= 
c.getHomeRealm().isEmpty() ? "selected=\"selected\"" : "" %>>Default - User 
selection at login</option>
                                        <%
-                                           if 
(!reg.getHomeRealms().entrySet().isEmpty()) {
-                                                       
Iterator<Map.Entry<String, String>> it = 
reg.getHomeRealms().entrySet().iterator();
-                                               while (it.hasNext()) {
-                                                               
Map.Entry<String, String> e = it.next();
+                        for (Map.Entry<String, String> entry : 
editClient.getHomeRealms().entrySet()) {
                                        %>
-                                       <option 
value="<%=e.getKey()%>"><%=e.getValue()%></option>
+                                       <option value="<%=entry.getKey()%>" <%= 
c.getHomeRealm().equals(entry.getKey()) ? "selected=\"selected\"" : "" 
%>><%=entry.getValue()%></option>
                                        <%
-                                               }
-                                               }
+                        }
                                        %>
                                </select>
                        </div>
@@ -122,10 +118,10 @@ input, select, button {
                                <input type="hidden" value="<%=csrfToken%>" 
name="client_csrfToken" />
                        </div>
                        <div data-type="control_button" class="form-line">
-                               <button name="submit_button" 
class="form-submit-button" type="submit">Register API Client</button>
+                               <button name="submit_button" 
class="form-submit-button" type="submit">Update API Client</button>
                        </div>
                </div>
        </form>
-       <p>Return to <a href="<%=basePath%>console/clients">registered 
Clients</a></p>
+       <p>Return to <a href="<%= basePath + "console/clients/" + 
c.getClientId() %>">Client details</a></p>
 </body>
 </html>
diff --git a/services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp 
b/services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp
index ffe0541..870e01a 100644
--- a/services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp
+++ b/services/oidc/src/main/webapp/WEB-INF/views/registerClient.jsp
@@ -1,5 +1,5 @@
 <%@ page
-       
import="javax.servlet.http.HttpServletRequest,java.util.Map,java.util.Iterator,org.apache.cxf.fediz.service.oidc.clients.RegisterClient,
+       import="javax.servlet.http.HttpServletRequest, java.util.Map, 
org.apache.cxf.fediz.service.oidc.clients.RegisterClient,
        org.apache.cxf.fediz.service.oidc.CSRFUtils"
 %>
 <%
@@ -104,17 +104,13 @@ input, select, button {
                        <div class="form-line">
                                <label for="client_homeRealm" 
id="label_homeRealm" class="form-label"> Home Realm </label>
                                <select name="client_homeRealm" 
id="input_homeRealm">
-                                       <option value="" selected>Default - 
User selection at login</option>
+                                       <option value="" 
selected="selected">Default - User selection at login</option>
                                        <%
-                                           if 
(!reg.getHomeRealms().entrySet().isEmpty()) {
-                                                       
Iterator<Map.Entry<String, String>> it = 
reg.getHomeRealms().entrySet().iterator();
-                                               while (it.hasNext()) {
-                                                               
Map.Entry<String, String> e = it.next();
+                        for (Map.Entry<String, String> entry : 
reg.getHomeRealms().entrySet()) {
                                        %>
-                                       <option 
value="<%=e.getKey()%>"><%=e.getValue()%></option>
+                                       <option 
value="<%=entry.getKey()%>"><%=entry.getValue()%></option>
                                        <%
-                                               }
-                                               }
+                        }
                                        %>
                                </select>
                        </div>
diff --git a/services/oidc/src/main/webapp/WEB-INF/views/registeredClients.jsp 
b/services/oidc/src/main/webapp/WEB-INF/views/registeredClients.jsp
index 3339030..33cd123 100644
--- a/services/oidc/src/main/webapp/WEB-INF/views/registeredClients.jsp
+++ b/services/oidc/src/main/webapp/WEB-INF/views/registeredClients.jsp
@@ -61,7 +61,7 @@
                Date date = new Date(client.getRegisteredAt() * 1000);
                String created = dateFormat.format(date);
                   %>
-           <%=    created %><br/>
+           <%=    created %>
            </td>
            <td>
            <% if(client.getRedirectUris() != null) {
diff --git 
a/systests/oidc/src/test/java/org/apache/cxf/fediz/systests/oidc/AbstractOIDCTest.java
 
b/systests/oidc/src/test/java/org/apache/cxf/fediz/systests/oidc/AbstractOIDCTest.java
index 36f2bef..a17bf39 100644
--- 
a/systests/oidc/src/test/java/org/apache/cxf/fediz/systests/oidc/AbstractOIDCTest.java
+++ 
b/systests/oidc/src/test/java/org/apache/cxf/fediz/systests/oidc/AbstractOIDCTest.java
@@ -371,7 +371,7 @@ abstract class AbstractOIDCTest {
             assertNotNull(clientId);
 
             // Check the Date
-            String date = table.getCellAt(1, 2).asText().trim(); // <br/>
+            String date = table.getCellAt(1, 2).asText();
             SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMM yyyy", 
Locale.US);
             dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
             assertEquals(dateFormat.format(new Date()), date);
@@ -382,6 +382,47 @@ abstract class AbstractOIDCTest {
         }
     }
 
+    @org.junit.Test
+    public void testEditClient() throws Exception {
+        try (WebClient webClient = setupWebClientIDP("alice", "ecila")) {
+            HtmlPage registeredClientPage = 
login(oidcEndpointBuilder("/console/clients/" + publicClientId),
+                webClient);
+
+            final HtmlPage editClientPage = 
registeredClientPage.getAnchorByText("public-client").click();
+
+            final HtmlForm form = editClientPage.getForms().get(0);
+
+            // Set new client values
+            final HtmlTextInput clientNameInput = 
form.getInputByName("client_name");
+            final String newClientName = "public-client-modified";
+            clientNameInput.setValueAttribute(newClientName);
+            final HtmlSelect clientTypeSelect = 
form.getSelectByName("client_type");
+            assertTrue(clientTypeSelect.isDisabled());
+            final HtmlTextInput redirectURIInput = 
form.getInputByName("client_redirectURI");
+            assertEquals(REDIRECT_URL, redirectURIInput.getText());
+            final HtmlTextInput clientAudienceURIInput = 
form.getInputByName("client_audience");
+            assertEquals("https://ws.apache.org";, 
clientAudienceURIInput.getText());
+            final HtmlTextInput clientLogoutURI = 
form.getInputByName("client_logoutURI");
+            assertEquals(LOGOUT_URL, clientLogoutURI.getText());
+
+            registeredClientPage = 
form.getButtonByName("submit_button").click();
+            assertNotNull(registeredClientPage.getAnchorByText(newClientName));
+
+            final HtmlPage registeredClientsPage = 
registeredClientPage.getAnchorByText("registered Clients").click();
+
+            HtmlTable table = 
registeredClientsPage.getHtmlElementById("registered_clients");
+            assertEquals("2 clients", table.getRows().size(), 3);
+            boolean updatedClientFound = false;
+            for (final HtmlTableRow row : table.getRows()) {
+                if (newClientName.equals(row.getCell(0).asText())) {
+                    updatedClientFound = true;
+                    break;
+                }
+            }
+            assertTrue(updatedClientFound);
+        }
+    }
+
     // Test that "bob" can't see the clients created by "alice"
     @org.junit.Test
     public void testRegisteredClientsAsBob() throws Exception {

Reply via email to