keycloak-aplcache

Merge pull request #757 from patriot1burke/master use id

10/10/2014 5:56:47 PM

Details

diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js
index dfd93d3..87dece9 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js
@@ -17,7 +17,7 @@ module.controller('OAuthClientClaimsCtrl', function($scope, realm, oauth, claims
     $scope.save = function () {
         OAuthClientClaims.update({
             realm: realm.realm,
-            oauth: oauth.name
+            oauth: oauth.id
         }, $scope.claims, function () {
             $scope.changed = false;
             claims = angular.copy($scope.claims);
@@ -27,7 +27,7 @@ module.controller('OAuthClientClaimsCtrl', function($scope, realm, oauth, claims
     };
 
     $scope.reset = function () {
-        $location.url("/realms/" + realm.realm + "/oauth-clients/" + oauth.name + "/claims");
+        $location.url("/realms/" + realm.realm + "/oauth-clients/" + oauth.id + "/claims");
     };
 
 });
@@ -36,14 +36,14 @@ module.controller('OAuthClientCredentialsCtrl', function($scope, $location, real
     $scope.realm = realm;
     $scope.oauth = oauth;
 
-    var secret = OAuthClientCredentials.get({ realm : realm.realm, oauth : oauth.name },
+    var secret = OAuthClientCredentials.get({ realm : realm.realm, oauth : oauth.id },
         function() {
             $scope.secret = secret.value;
         }
     );
 
     $scope.changePassword = function() {
-        var secret = OAuthClientCredentials.update({ realm : realm.realm,  oauth : oauth.name  },
+        var secret = OAuthClientCredentials.update({ realm : realm.realm,  oauth : oauth.id  },
             function() {
                 Notifications.success('The secret has been changed.');
                 $scope.secret = secret.value;
@@ -148,11 +148,11 @@ module.controller('OAuthClientDetailCtrl', function($scope, realm, oauth, OAuthC
             } else {
                 OAuthClient.update({
                     realm : realm.realm,
-                    oauth : oauth.name
+                    oauth : oauth.id
                 }, $scope.oauth, function() {
                     $scope.changed = false;
                     oauth = angular.copy($scope.oauth);
-                    $location.url("/realms/" + realm.realm + "/oauth-clients/" + oauth.name);
+                    $location.url("/realms/" + realm.realm + "/oauth-clients/" + oauth.id);
                     Notifications.success("Your changes have been saved to the oauth client.");
                 });
             }
@@ -169,10 +169,10 @@ module.controller('OAuthClientDetailCtrl', function($scope, realm, oauth, OAuthC
     };
 
     $scope.remove = function() {
-        Dialog.confirmDelete($scope.oauth.name, 'oauth', function() {
+        Dialog.confirmDelete($scope.oauth.id, 'oauth', function() {
             $scope.oauth.$remove({
                 realm : realm.realm,
-                oauth : $scope.oauth.name
+                oauth : $scope.oauth.id
             }, function() {
                 $location.url("/realms/" + realm.realm + "/oauth-clients");
                 Notifications.success("The oauth client has been deleted.");
@@ -205,7 +205,7 @@ module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, 
         console.log('change full scope');
         OAuthClient.update({
             realm : realm.realm,
-            oauth : oauth.name
+            oauth : oauth.id
         }, $scope.oauth, function() {
             $scope.changed = false;
             oauth = angular.copy($scope.oauth);
@@ -216,17 +216,17 @@ module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, 
 
 
     function updateRealmRoles() {
-        $scope.realmRoles = OAuthClientAvailableRealmScopeMapping.query({realm : realm.realm, oauth : oauth.name});
-        $scope.realmMappings = OAuthClientRealmScopeMapping.query({realm : realm.realm, oauth : oauth.name});
-        $scope.realmComposite = OAuthClientCompositeRealmScopeMapping.query({realm : realm.realm, oauth : oauth.name});
+        $scope.realmRoles = OAuthClientAvailableRealmScopeMapping.query({realm : realm.realm, oauth : oauth.id});
+        $scope.realmMappings = OAuthClientRealmScopeMapping.query({realm : realm.realm, oauth : oauth.id});
+        $scope.realmComposite = OAuthClientCompositeRealmScopeMapping.query({realm : realm.realm, oauth : oauth.id});
     }
 
     function updateAppRoles() {
         if ($scope.targetApp) {
             console.debug($scope.targetApp.name);
-            $scope.applicationRoles = OAuthClientAvailableApplicationScopeMapping.query({realm : realm.realm, oauth : oauth.name, targetApp : $scope.targetApp.id});
-            $scope.applicationMappings = OAuthClientApplicationScopeMapping.query({realm : realm.realm, oauth : oauth.name, targetApp : $scope.targetApp.id});
-            $scope.applicationComposite = OAuthClientCompositeApplicationScopeMapping.query({realm : realm.realm, oauth : oauth.name, targetApp : $scope.targetApp.id});
+            $scope.applicationRoles = OAuthClientAvailableApplicationScopeMapping.query({realm : realm.realm, oauth : oauth.id, targetApp : $scope.targetApp.id});
+            $scope.applicationMappings = OAuthClientApplicationScopeMapping.query({realm : realm.realm, oauth : oauth.id, targetApp : $scope.targetApp.id});
+            $scope.applicationComposite = OAuthClientCompositeApplicationScopeMapping.query({realm : realm.realm, oauth : oauth.id, targetApp : $scope.targetApp.id});
         } else {
             $scope.applicationRoles = null;
             $scope.applicationMappings = null;
@@ -239,7 +239,7 @@ module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, 
     };
 
     $scope.addRealmRole = function() {
-        $http.post(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients/' + oauth.name + '/scope-mappings/realm',
+        $http.post(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients-by-id/' + oauth.id + '/scope-mappings/realm',
             $scope.selectedRealmRoles).success(function () {
                 updateRealmRoles();
                 Notifications.success("Scope mappings updated.");
@@ -247,7 +247,7 @@ module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, 
     };
 
     $scope.deleteRealmRole = function() {
-        $http.delete(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients/' + oauth.name +  '/scope-mappings/realm',
+        $http.delete(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients-by-id/' + oauth.id +  '/scope-mappings/realm',
             {data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).success(function () {
                 updateRealmRoles();
                 Notifications.success("Scope mappings updated.");
@@ -256,7 +256,7 @@ module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, 
     };
 
     $scope.addApplicationRole = function() {
-        $http.post(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients/' + oauth.name +  '/scope-mappings/applications-by-id/' + $scope.targetApp.id,
+        $http.post(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients-by-id/' + oauth.id +  '/scope-mappings/applications-by-id/' + $scope.targetApp.id,
             $scope.selectedApplicationRoles).success(function () {
                 updateAppRoles();
                 Notifications.success("Scope mappings updated.");
@@ -265,7 +265,7 @@ module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, 
     };
 
     $scope.deleteApplicationRole = function() {
-        $http.delete(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients/' + oauth.name +  '/scope-mappings/applications-by-id/' + $scope.targetApp.id,
+        $http.delete(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients-by-id/' + oauth.id +  '/scope-mappings/applications-by-id/' + $scope.targetApp.id,
             {data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function () {
                 updateAppRoles();
                 Notifications.success("Scope mappings updated.");
@@ -300,7 +300,7 @@ module.controller('OAuthClientRevocationCtrl', function($scope, realm, oauth, OA
     setNotBefore();
 
     var refresh = function() {
-        OAuthClient.get({ realm : realm.realm, oauth: $scope.oauth.name }, function(updated) {
+        OAuthClient.get({ realm : realm.realm, oauth: $scope.oauth.id }, function(updated) {
             $scope.oauth = updated;
             setNotBefore();
         })
@@ -309,7 +309,7 @@ module.controller('OAuthClientRevocationCtrl', function($scope, realm, oauth, OA
 
     $scope.clear = function() {
         $scope.oauth.notBefore = 0;
-        OAuthClient.update({ realm : realm.realm, oauth: $scope.oauth.name}, $scope.oauth, function () {
+        OAuthClient.update({ realm : realm.realm, oauth: $scope.oauth.id}, $scope.oauth, function () {
             $scope.notBefore = "None";
             Notifications.success('Not Before cleared for application.');
             refresh();
@@ -317,7 +317,7 @@ module.controller('OAuthClientRevocationCtrl', function($scope, realm, oauth, OA
     }
     $scope.setNotBeforeNow = function() {
         $scope.oauth.notBefore = new Date().getTime()/1000;
-        OAuthClient.update({ realm : realm.realm, oauth: $scope.oauth.name}, $scope.oauth, function () {
+        OAuthClient.update({ realm : realm.realm, oauth: $scope.oauth.id}, $scope.oauth, function () {
             Notifications.success('Not Before cleared for application.');
             refresh();
         });
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
index 3fafb68..fec1e99 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js
@@ -749,7 +749,7 @@ module.factory('ApplicationOrigins', function($resource) {
 });
 
 module.factory('OAuthClient', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients/:oauth', {
+    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth', {
         realm : '@realm',
         oauth : '@oauth'
     },  {
@@ -760,7 +760,7 @@ module.factory('OAuthClient', function($resource) {
 });
 
 module.factory('OAuthClientClaims', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients/:oauth/claims', {
+    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/claims', {
         realm : '@realm',
         oauth : "@oauth"
     },  {
@@ -772,7 +772,7 @@ module.factory('OAuthClientClaims', function($resource) {
 
 
 module.factory('OAuthClientCredentials', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients/:oauth/client-secret', {
+    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/client-secret', {
         realm : '@realm',
         oauth : '@oauth'
     },  {
@@ -784,28 +784,28 @@ module.factory('OAuthClientCredentials', function($resource) {
 });
 
 module.factory('OAuthClientRealmScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients/:oauth/scope-mappings/realm', {
+    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/realm', {
         realm : '@realm',
         oauth : '@oauth'
     });
 });
 
 module.factory('OAuthClientCompositeRealmScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients/:oauth/scope-mappings/realm/composite', {
+    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/realm/composite', {
         realm : '@realm',
         oauth : '@oauth'
     });
 });
 
 module.factory('OAuthClientAvailableRealmScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients/:oauth/scope-mappings/realm/available', {
+    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/realm/available', {
         realm : '@realm',
         oauth : '@oauth'
     });
 });
 
 module.factory('OAuthClientApplicationScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients/:oauth/scope-mappings/applications-by-id/:targetApp', {
+    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/applications-by-id/:targetApp', {
         realm : '@realm',
         oauth : '@oauth',
         targetApp : '@targetApp'
@@ -813,7 +813,7 @@ module.factory('OAuthClientApplicationScopeMapping', function($resource) {
 });
 
 module.factory('OAuthClientCompositeApplicationScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients/:oauth/scope-mappings/applications-by-id/:targetApp/composite', {
+    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/applications-by-id/:targetApp/composite', {
         realm : '@realm',
         oauth : '@oauth',
         targetApp : '@targetApp'
@@ -821,7 +821,7 @@ module.factory('OAuthClientCompositeApplicationScopeMapping', function($resource
 });
 
 module.factory('OAuthClientAvailableApplicationScopeMapping', function($resource) {
-    return $resource(authUrl + '/admin/realms/:realm/oauth-clients/:oauth/scope-mappings/applications-by-id/:targetApp/available', {
+    return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/scope-mappings/applications-by-id/:targetApp/available', {
         realm : '@realm',
         oauth : '@oauth',
         targetApp : '@targetApp'
@@ -831,8 +831,8 @@ module.factory('OAuthClientAvailableApplicationScopeMapping', function($resource
 
 
 module.factory('OAuthClientInstallation', function($resource) {
-    var url = authUrl + '/admin/realms/:realm/oauth-clients/:oauth/installation';
-    var resource = $resource(authUrl + '/admin/realms/:realm/oauth-clients/:oauth/installation', {
+    var url = authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/installation';
+    var resource = $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/installation', {
         realm : '@realm',
         oauth : '@oauth'
     },  {
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-installation.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-installation.html
index a2df72b..15ba1de 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-installation.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-installation.html
@@ -4,7 +4,7 @@
     <div id="content">
         <ol class="breadcrumb" data-ng-hide="create">
             <li><a href="#/realms/{{realm.realm}}/oauth-clients">OAuth Clients</a></li>
-            <li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.name}}">{{oauth.name}}</a></li>
+            <li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}">{{oauth.name}}</a></li>
             <li class="active">Installation</li>
         </ol>
         <h2>{{oauth.name}} Adapter Installation <span tooltip-placement="right" tooltip="Helper utility for generating various client adapter configuration formats which you can download or cut and paste to configure your client applications." class="fa fa-info-circle"></span></h2>
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-list.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-list.html
index f6ffbbf..f5638b4 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-list.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-list.html
@@ -43,7 +43,7 @@
             -->
             <tbody>
             <tr ng-repeat="client in oauthClients | filter:search">
-                <td><a href="#/realms/{{realm.realm}}/oauth-clients/{{client.name}}">{{client.name}}</a></td>
+                <td><a href="#/realms/{{realm.realm}}/oauth-clients/{{client.id}}">{{client.name}}</a></td>
                 <td>{{client.enabled}}</td>
             </tr>
             <tr data-ng-show="oauthClients.length == 0">
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-revocation.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-revocation.html
index 8d378a5..b36082f 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-revocation.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-revocation.html
@@ -4,7 +4,7 @@
     <div id="content">
         <ol class="breadcrumb">
             <li><a href="#/realms/{{realm.realm}}/oauth-clients">OAuth Clients</a></li>
-            <li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.name}}">{{oauth.name}}</a></li>
+            <li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}">{{oauth.name}}</a></li>
             <li class="active">Revocation</li>
         </ol>
         <h2 data-ng-hide="create"><span>{{oauth.name}}</span> Revocation Policies</h2>
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-scope-mappings.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-scope-mappings.html
index e28dc56..788525c 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-scope-mappings.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-scope-mappings.html
@@ -4,7 +4,7 @@
     <div id="content">
         <ol class="breadcrumb" data-ng-hide="create">
             <li><a href="#/realms/{{realm.realm}}/oauth-clients">OAuth Clients</a></li>
-            <li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.name}}">{{oauth.name}}</a></li>
+            <li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}">{{oauth.name}}</a></li>
             <li class="active">Scope</li>
         </ol>
         <h2><span>{{oauth.name}}</span> Scope Mappings <span tooltip-placement="right" tooltip="Scope mappings allow you to restrict which user role mappings are included within the access token requested by the client." class="fa fa-info-circle"></span></h2>
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-oauth-client.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-oauth-client.html
old mode 100644
new mode 100755
index 4853bef..ffca271
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-oauth-client.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-oauth-client.html
@@ -1,8 +1,8 @@
 <ul class="nav nav-tabs nav-tabs-pf" data-ng-show="!create">
-    <li ng-class="{active: !path[4]}"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.name}}">Settings</a></li>
-    <li ng-class="{active: path[4] == 'credentials'}" data-ng-show="!oauth.publicClient"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.name}}/credentials">Credentials</a></li>
-    <li ng-class="{active: path[4] == 'claims'}"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.name}}/claims">Claims</a></li>
-    <li ng-class="{active: path[4] == 'scope-mappings'}"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.name}}/scope-mappings">Scope</a></li>
-    <li ng-class="{active: path[4] == 'revocation'}"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.name}}/revocation">Revocation</a></li>
-    <li ng-class="{active: path[4] == 'installation'}"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.name}}/installation">Installation</a></li>
+    <li ng-class="{active: !path[4]}"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}">Settings</a></li>
+    <li ng-class="{active: path[4] == 'credentials'}" data-ng-show="!oauth.publicClient"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/credentials">Credentials</a></li>
+    <li ng-class="{active: path[4] == 'claims'}"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/claims">Claims</a></li>
+    <li ng-class="{active: path[4] == 'scope-mappings'}"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/scope-mappings">Scope</a></li>
+    <li ng-class="{active: path[4] == 'revocation'}"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/revocation">Revocation</a></li>
+    <li ng-class="{active: path[4] == 'installation'}"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/installation">Installation</a></li>
 </ul>
\ No newline at end of file
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsByIdResource.java
new file mode 100755
index 0000000..e479827
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsByIdResource.java
@@ -0,0 +1,42 @@
+package org.keycloak.services.resources.admin;
+
+import org.jboss.logging.Logger;
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.NotFoundException;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ModelDuplicateException;
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.ModelToRepresentation;
+import org.keycloak.models.utils.RepresentationToModel;
+import org.keycloak.representations.idm.OAuthClientRepresentation;
+import org.keycloak.services.resources.flows.Flows;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class OAuthClientsByIdResource extends OAuthClientsResource {
+    public OAuthClientsByIdResource(RealmModel realm, RealmAuth auth, KeycloakSession session) {
+        super(realm, auth, session);
+    }
+
+    protected OAuthClientModel getOAuthClientModel(String id) {
+        return realm.getOAuthClientById(id);
+    }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
index 612f539..0f15347 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
@@ -106,7 +106,7 @@ public class OAuthClientsResource {
     public OAuthClientResource getOAuthClient(final @PathParam("clientId") String clientId) {
         auth.requireView();
 
-        OAuthClientModel oauth = realm.getOAuthClient(clientId);
+        OAuthClientModel oauth = getOAuthClientModel(clientId);
         if (oauth == null) {
             throw new NotFoundException("OAuth Client not found");
         }
@@ -116,4 +116,8 @@ public class OAuthClientsResource {
         return oAuthClientResource;
     }
 
+    protected OAuthClientModel getOAuthClientModel(String clientId) {
+        return realm.getOAuthClient(clientId);
+    }
+
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
index 9c6047a..1a45769 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java
@@ -99,7 +99,7 @@ public class RealmAdminResource {
     }
 
     /**
-     * base path for managing oauth clients in this realm
+     * base path for managing oauth clients in this realm uses name of client
      *
      * @return
      */
@@ -112,6 +112,19 @@ public class RealmAdminResource {
     }
 
     /**
+     * base path for managing oauth clients in this realm uses ids
+     *
+     * @return
+     */
+    @Path("oauth-clients-by-id")
+    public OAuthClientsByIdResource getOAuthClientsById() {
+        OAuthClientsByIdResource oauth = new OAuthClientsByIdResource(realm, auth, session);
+        ResteasyProviderFactory.getInstance().injectProperties(oauth);
+        //resourceContext.initResource(oauth);
+        return oauth;
+    }
+
+    /**
      * base path for managing realm-level roles of this realm
      *
      * @return
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginConfigTotpPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginConfigTotpPage.java
old mode 100644
new mode 100755
index 5b1613a..edb8cc5
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginConfigTotpPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginConfigTotpPage.java
@@ -48,7 +48,7 @@ public class LoginConfigTotpPage extends AbstractPage {
     }
 
     public boolean isCurrent() {
-        return driver.getTitle().equals("Google Authenticator Setup");
+        return driver.getTitle().equals("FreeOTP Authenticator Setup");
     }
 
     public void open() {