keycloak-uncached

app password

10/6/2013 7:41:35 PM

Changes

Details

diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
index 0e83bb6..6689e1d 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
@@ -12,6 +12,7 @@ public class ApplicationRepresentation {
     protected String id;
     protected String name;
     protected String adminUrl;
+    protected String baseUrl;
     protected boolean surrogateAuthRequired;
     protected boolean useRealmMappings;
     protected boolean enabled;
@@ -113,6 +114,14 @@ public class ApplicationRepresentation {
         this.adminUrl = adminUrl;
     }
 
+    public String getBaseUrl() {
+        return baseUrl;
+    }
+
+    public void setBaseUrl(String baseUrl) {
+        this.baseUrl = baseUrl;
+    }
+
     public List<CredentialRepresentation> getCredentials() {
         return credentials;
     }
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/app.js b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/app.js
index 19e6f97..cd96e48 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/app.js
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/app.js
@@ -156,6 +156,17 @@ module.config([ '$routeProvider', function($routeProvider) {
                 }
             },
             controller : 'ApplicationRoleDetailCtrl'
+        }).when('/realms/:realm/applications/:application/credentials', {
+            templateUrl : 'partials/application-credentials.html',
+            resolve : {
+                realm : function(RealmLoader) {
+                    return RealmLoader();
+                },
+                application : function(ApplicationLoader) {
+                    return ApplicationLoader();
+                }
+            },
+            controller : 'ApplicationCredentialsCtrl'
         }).when('/realms/:realm/applications/:application/roles', {
             templateUrl : 'partials/application-role-list.html',
             resolve : {
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/controllers.js b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/controllers.js
index 0ec3308..9bb6e9b 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/controllers.js
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/controllers.js
@@ -42,9 +42,6 @@ module.controller('RealmListCtrl', function($scope, Realm, Current) {
 module.controller('RealmDropdownCtrl', function($scope, Realm, Current, Auth, $location) {
 //    Current.realms = Realm.get();
     $scope.current = Current;
-    if (Current.realms.length > 0) {
-        console.log('[0]: ' + current.realms[0].realm);
-    }
     $scope.changeRealm = function() {
         $location.url("/realms/" + $scope.current.realm.id);
     };
@@ -478,6 +475,92 @@ module.controller('ApplicationRoleListCtrl', function($scope, $location, realm, 
     });
 });
 
+function randomString(len) {
+    var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+    var randomString = '';
+    for (var i = 0; i < len; i++) {
+        var randomPoz = Math.floor(Math.random() * charSet.length);
+        randomString += charSet.substring(randomPoz,randomPoz+1);
+    }
+    return randomString;
+}
+
+module.controller('ApplicationCredentialsCtrl', function($scope, $location, realm, application, ApplicationCredentials, Notifications) {
+    $scope.realm = realm;
+    $scope.application = application;
+
+    var required = realm.requiredApplicationCredentials;
+
+    for (var i = 0; i < required.length; i++) {
+        if (required[i] == 'password') {
+            $scope.passwordRequired = true;
+        } else if (required[i] == 'totp') {
+            $scope.totpRequired = true;
+        } else if (required[i] == 'cert') {
+            $scope.certRequired = true;
+        }
+    }
+
+    $scope.generateTotp = function() {
+        $scope.totp = randomString(5) + '-' + randomString(5) + '-' + randomString(5);
+    }
+
+    $scope.changePassword = function() {
+        if ($scope.password != $scope.confirmPassword) {
+           Notifications.error("Password not confirmed");
+           $scope.password = "";
+           $scope.confirmPassword = "";
+           return;
+        }
+        var creds = [
+           {
+              type : "password",
+              value : $scope.password
+           }
+        ];
+
+        ApplicationCredentials.update({ realm : realm.id, application : application.id }, creds,
+            function() {
+                Notifications.success('Change password successful');
+                $scope.password = null;
+                $scope.confirmPassword = null;
+            },
+            function() {
+                Notifications.error("Change password failed");
+                $scope.password = null;
+                $scope.confirmPassword = null;
+            }
+        );
+    };
+
+    $scope.changeTotp = function() {
+        var creds = [
+            {
+                type : "totp",
+                value : $scope.totp
+            }
+        ];
+
+        ApplicationCredentials.update({ realm : realm.id, application : application.id }, creds,
+            function() {
+                Notifications.success('Change totp successful');
+                $scope.totp = null;
+            },
+            function() {
+                Notifications.error("Change totp failed");
+                $scope.totp = null;
+            }
+        );
+    };
+    $scope.$watch(function() {
+        return $location.path();
+    }, function() {
+        $scope.path = $location.path().substring(1).split("/");
+    });
+});
+
+
+
 
 
 module.controller('ApplicationRoleDetailCtrl', function($scope, realm, application, role, ApplicationRole, $location, Dialog, Notifications) {
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/services.js b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/services.js
index 9636d46..4614635 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/services.js
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/js/services.js
@@ -111,6 +111,8 @@ module.factory('RealmRoleMapping', function($resource) {
     });
 });
 
+
+
 module.factory('ApplicationRoleMapping', function($resource) {
     return $resource('/auth-server/rest/saas/admin/realms/:realm/users/:userId/role-mappings/applications/:application', {
         realm : '@realm',
@@ -164,6 +166,19 @@ module.factory('Application', function($resource) {
     });
 });
 
+module.factory('ApplicationCredentials', function($resource) {
+    return $resource('/auth-server/rest/saas/admin/realms/:realm/applications/:application/credentials', {
+        realm : '@realm',
+        application : '@application'
+    },  {
+        update : {
+            method : 'PUT',
+            isArray : true
+        }
+    });
+});
+
+
 
 module.factory('Current', function($resource) {
     return {
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-credentials.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-credentials.html
new file mode 100755
index 0000000..6be1cb0
--- /dev/null
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-credentials.html
@@ -0,0 +1,64 @@
+<div id="wrapper" class="container">
+    <div class="row">
+        <div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
+        <div id="content-area" class="col-md-9" role="main">
+            <div class="top-nav">
+                <ul class="rcue-tabs">
+                    <li><a href="#/create/application/{{realm.id}}">New Application</a></li>
+                    <li><a href="#/realms/{{realm.id}}/applications">Applications</a></li>
+                    <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
+                    <li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
+                    <li><a href="#">Installation</a></li>
+                    <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
+                    <li><a href="#">Scope</a></li>
+                    <li><a href="#">Sessions</a></li>
+                </ul>
+            </div>
+            <div id="content">
+                <h2 class="pull-left" data-ng-hide="create">Application <span>{{application.name}}</span> Credentials</h2>
+                <p class="subtitle"></p>
+                <form name="credentialForm" novalidate >
+                    <fieldset data-ng-show="passwordRequired">
+                        <legend uncollapsed><span class="text">Change Password</span></legend>
+                        <div class="form-group">
+                            <label for="password">New Password</label>
+                            <div class="controls">
+                            <input type="password" id="password" name="password" data-ng-model="password" autofocus
+                                   required>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label for="password">Confirm New Password</label>
+                            <div class="controls">
+                                <input type="password" id="confirmPassword" name="confirmPassword" data-ng-model="confirmPassword" autofocus
+                                       required>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <button type="submit" data-ng-click="changePassword()" class="primary" ng-show="password != null">Save
+                            </button>
+                        </div>
+                    </fieldset>
+                    <fieldset data-ng-show="totpRequired">
+                        <legend uncollapsed><span class="text">Change TOTP Key</span></legend>
+                        <div class="form-group">
+                            <label for="totp">New Key</label>
+                            <div class="controls">
+                                <input type="text" id="totp" name="totp" data-ng-model="totp" autofocus
+                                       required>
+                                <button type="submit" data-ng-click="generateTotp()">Generate
+                                </button>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label></label>
+                            <button type="submit" data-ng-click="changeTotp()" class="primary" ng-show="totp != null">Save
+                            </button>
+                        </div>
+                    </fieldset>
+                </form>
+            </div>
+        </div>
+        <div id="container-right-bg"></div>
+    </div>
+</div>
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-detail.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-detail.html
index 1503ac1..a1035f3 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-detail.html
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/application-detail.html
@@ -7,7 +7,7 @@
                     <li><a href="#/create/application/{{realm.id}}">New Application</a></li>
                     <li><a href="#/realms/{{realm.id}}/applications">Applications</a></li>
                     <li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
-                    <li><a href="#">Credentials</a></li>
+                    <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
                     <li><a href="#">Installation</a></li>
                     <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
                     <li><a href="#">Scope</a></li>
@@ -50,6 +50,14 @@
                             </div>
                         </div>
                         <div class="form-group">
+                            <label for="adminUrl" class="control-label">Base URL</label>
+
+                            <div class="controls">
+                                <input class="input-small" type="text" name="baseUrl" id="baseUrl"
+                                       data-ng-model="application.baseUrl">
+                            </div>
+                        </div>
+                        <div class="form-group">
                             <label for="adminUrl" class="control-label">Admin URL</label>
 
                             <div class="controls">
diff --git a/model/api/src/main/java/org/keycloak/models/ApplicationModel.java b/model/api/src/main/java/org/keycloak/models/ApplicationModel.java
index 433d392..9dd08d3 100755
--- a/model/api/src/main/java/org/keycloak/models/ApplicationModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ApplicationModel.java
@@ -8,9 +8,9 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public interface ApplicationModel {
-    void updateResource();
+    void updateApplication();
 
-    UserModel getResourceUser();
+    UserModel getApplicationUser();
 
     String getId();
 
@@ -30,6 +30,10 @@ public interface ApplicationModel {
 
     void setManagementUrl(String url);
 
+    String getBaseUrl();
+
+    void setBaseUrl(String url);
+
     RoleModel getRole(String name);
 
     RoleModel addRole(String name);
@@ -38,11 +42,11 @@ public interface ApplicationModel {
 
     Set<String> getRoleMappingValues(UserModel user);
 
-    void addScope(UserModel agent, String roleName);
+    void addScopeMapping(UserModel agent, String roleName);
 
-    void addScope(UserModel agent, RoleModel role);
+    void addScopeMapping(UserModel agent, RoleModel role);
 
-    Set<String> getScope(UserModel agent);
+    Set<String> getScopeMapping(UserModel agent);
 
     List<RoleModel> getRoleMappings(UserModel user);
 
diff --git a/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java b/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java
new file mode 100755
index 0000000..2b25f46
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java
@@ -0,0 +1,17 @@
+package org.keycloak.models;
+
+import org.keycloak.models.UserModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface OAuthClientModel {
+    String getId();
+
+    UserModel getOAuthAgent();
+
+    String getBaseUrl();
+
+    void setBaseUrl(String base);
+}
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index 43d1d87..d6d0a1a 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -97,7 +97,7 @@ public interface RealmModel {
     
     void updateDefaultRoles(String[] defaultRoles);
 
-    Map<String, ApplicationModel> getResourceNameMap();
+    Map<String, ApplicationModel> getApplicationNameMap();
 
     List<ApplicationModel> getApplications();
 
@@ -109,9 +109,9 @@ public interface RealmModel {
 
     Set<String> getRoleMappingValues(UserModel user);
 
-    void addScope(UserModel agent, String roleName);
+    void addScopeMapping(UserModel agent, String roleName);
 
-    Set<String> getScope(UserModel agent);
+    Set<String> getScopeMapping(UserModel agent);
 
     boolean isRealmAdmin(UserModel agent);
 
@@ -160,4 +160,8 @@ public interface RealmModel {
     List<RoleModel> getRoleMappings(UserModel user);
 
     void deleteRoleMapping(UserModel user, RoleModel role);
+
+    OAuthClientModel addOAuthClient(String name);
+
+    OAuthClientModel getOAuthClient(String name);
 }
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
index eb2fad7..f5a413c 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java
@@ -25,20 +25,20 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public class ApplicationAdapter implements ApplicationModel {
-    protected ApplicationData resource;
+    protected ApplicationData applicationData;
     protected RealmAdapter realm;
     protected IdentityManager idm;
     protected PartitionManager partitionManager;
     protected RelationshipManager relationshipManager;
 
-    public ApplicationAdapter(ApplicationData resource, RealmAdapter realm, PartitionManager partitionManager) {
-        this.resource = resource;
+    public ApplicationAdapter(ApplicationData applicationData, RealmAdapter realm, PartitionManager partitionManager) {
+        this.applicationData = applicationData;
         this.realm = realm;
         this.partitionManager = partitionManager;
     }
 
     protected IdentityManager getIdm() {
-        if (idm == null) idm = partitionManager.createIdentityManager(resource);
+        if (idm == null) idm = partitionManager.createIdentityManager(applicationData);
         return idm;
     }
 
@@ -48,59 +48,69 @@ public class ApplicationAdapter implements ApplicationModel {
     }
 
     @Override
-    public void updateResource() {
-        partitionManager.update(resource);
+    public void updateApplication() {
+        partitionManager.update(applicationData);
     }
 
     @Override
-    public UserAdapter getResourceUser() {
-        return new UserAdapter(resource.getResourceUser(), realm.getIdm());
+    public UserAdapter getApplicationUser() {
+        return new UserAdapter(applicationData.getResourceUser(), realm.getIdm());
     }
 
     @Override
     public String getId() {
         // for some reason picketlink queries by name when finding partition, don't know what ID is used for now
-        return resource.getName();
+        return applicationData.getName();
     }
 
     @Override
     public String getName() {
-        return resource.getResourceName();
+        return applicationData.getResourceName();
     }
 
     @Override
     public void setName(String name) {
-        resource.setResourceName(name);
+        applicationData.setResourceName(name);
     }
 
     @Override
     public boolean isEnabled() {
-        return resource.isEnabled();
+        return applicationData.isEnabled();
     }
 
     @Override
     public void setEnabled(boolean enabled) {
-        resource.setEnabled(enabled);
+        applicationData.setEnabled(enabled);
     }
 
     @Override
     public boolean isSurrogateAuthRequired() {
-        return resource.isSurrogateAuthRequired();
+        return applicationData.isSurrogateAuthRequired();
     }
 
     @Override
     public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
-        resource.setSurrogateAuthRequired(surrogateAuthRequired);
+        applicationData.setSurrogateAuthRequired(surrogateAuthRequired);
     }
 
     @Override
     public String getManagementUrl() {
-        return resource.getManagementUrl();
+        return applicationData.getManagementUrl();
     }
 
     @Override
     public void setManagementUrl(String url) {
-        resource.setManagementUrl(url);
+        applicationData.setManagementUrl(url);
+    }
+
+    @Override
+    public String getBaseUrl() {
+        return applicationData.getBaseUrl();
+    }
+
+    @Override
+    public void setBaseUrl(String url) {
+        applicationData.setBaseUrl(url);
     }
 
     @Override
@@ -136,7 +146,7 @@ public class ApplicationAdapter implements ApplicationModel {
     @Override
     public List<RoleModel> getRoles() {
         IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
-        query.setParameter(Role.PARTITION, resource);
+        query.setParameter(Role.PARTITION, applicationData);
         List<Role> roles = query.getResultList();
         List<RoleModel> roleModels = new ArrayList<RoleModel>();
         for (Role role : roles) {
@@ -152,7 +162,7 @@ public class ApplicationAdapter implements ApplicationModel {
         List<Grant> grants = query.getResultList();
         HashSet<String> set = new HashSet<String>();
         for (Grant grant : grants) {
-            if (grant.getRole().getPartition().getId().equals(resource.getId())) set.add(grant.getRole().getName());
+            if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(grant.getRole().getName());
         }
         return set;
     }
@@ -164,7 +174,7 @@ public class ApplicationAdapter implements ApplicationModel {
         List<Grant> grants = query.getResultList();
         List<RoleModel> set = new ArrayList<RoleModel>();
         for (Grant grant : grants) {
-            if (grant.getRole().getPartition().getId().equals(resource.getId())) set.add(new RoleAdapter(grant.getRole(), getIdm()));
+            if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(new RoleAdapter(grant.getRole(), getIdm()));
         }
         return set;
     }
@@ -184,16 +194,16 @@ public class ApplicationAdapter implements ApplicationModel {
 
 
     @Override
-    public void addScope(UserModel agent, String roleName) {
+    public void addScopeMapping(UserModel agent, String roleName) {
         IdentityManager idm = getIdm();
         Role role = SampleModel.getRole(idm,roleName);
         if (role == null) throw new RuntimeException("role not found");
-        addScope(agent, new RoleAdapter(role, idm));
+        addScopeMapping(agent, new RoleAdapter(role, idm));
 
     }
 
     @Override
-    public void addScope(UserModel agent, RoleModel role) {
+    public void addScopeMapping(UserModel agent, RoleModel role) {
         ScopeRelationship scope = new ScopeRelationship();
         scope.setClient(((UserAdapter)agent).getUser());
         scope.setScope(((RoleAdapter)role).getRole());
@@ -201,13 +211,13 @@ public class ApplicationAdapter implements ApplicationModel {
     }
 
     @Override
-    public Set<String> getScope(UserModel agent) {
+    public Set<String> getScopeMapping(UserModel agent) {
         RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
         query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
         List<ScopeRelationship> scope = query.getResultList();
         HashSet<String> set = new HashSet<String>();
         for (ScopeRelationship rel : scope) {
-            if (rel.getScope().getPartition().getId().equals(resource.getId())) set.add(rel.getScope().getName());
+            if (rel.getScope().getPartition().getId().equals(applicationData.getId())) set.add(rel.getScope().getName());
         }
         return set;
     }
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/ApplicationData.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/ApplicationData.java
index 418e801..8d5594a 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/ApplicationData.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/ApplicationData.java
@@ -13,6 +13,7 @@ public class ApplicationData extends AbstractPartition {
     private boolean enabled;
     private boolean surrogateAuthRequired;
     private String managementUrl;
+    private String baseUrl;
     private User resourceUser;
 
     public ApplicationData() {
@@ -65,4 +66,14 @@ public class ApplicationData extends AbstractPartition {
     public void setManagementUrl(String managementUrl) {
         this.managementUrl = managementUrl;
     }
+
+    @AttributeProperty
+    public String getBaseUrl() {
+        return baseUrl;
+    }
+
+    public void setBaseUrl(String baseUrl) {
+        this.baseUrl = baseUrl;
+    }
+
 }
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/ApplicationEntity.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/ApplicationEntity.java
index ccfdf3d..0eddf7e 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/ApplicationEntity.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/ApplicationEntity.java
@@ -31,6 +31,8 @@ public class ApplicationEntity implements Serializable {
     private boolean surrogateAuthRequired;
     @AttributeValue
     private String managementUrl;
+    @AttributeValue
+    private String baseUrl;
 
     @OneToOne
     @AttributeValue
@@ -77,6 +79,14 @@ public class ApplicationEntity implements Serializable {
         this.managementUrl = managementUrl;
     }
 
+    public String getBaseUrl() {
+        return baseUrl;
+    }
+
+    public void setBaseUrl(String baseUrl) {
+        this.baseUrl = baseUrl;
+    }
+
     public AccountTypeEntity getResourceUser() {
         return resourceUser;
     }
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/OAuthClientAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/OAuthClientAdapter.java
new file mode 100755
index 0000000..310b4ce
--- /dev/null
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/OAuthClientAdapter.java
@@ -0,0 +1,44 @@
+package org.keycloak.models.picketlink;
+
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.picketlink.relationships.OAuthClientRelationship;
+import org.picketlink.idm.IdentityManager;
+import org.picketlink.idm.RelationshipManager;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class OAuthClientAdapter implements OAuthClientModel {
+    protected OAuthClientRelationship delegate;
+    protected IdentityManager idm;
+    protected RelationshipManager relationshipManager;
+
+    public OAuthClientAdapter(OAuthClientRelationship delegate, IdentityManager idm, RelationshipManager relationshipManager) {
+        this.delegate = delegate;
+        this.idm = idm;
+        this.relationshipManager = relationshipManager;
+    }
+
+    @Override
+    public String getId() {
+        return delegate.getId();
+    }
+
+    @Override
+    public UserModel getOAuthAgent() {
+       return new UserAdapter(delegate.getOauthAgent(), idm);
+    }
+
+    @Override
+    public String getBaseUrl() {
+        return delegate.getBaseUrl();
+    }
+
+    @Override
+    public void setBaseUrl(String base) {
+        delegate.setBaseUrl(base);
+        relationshipManager.update(delegate);
+    }
+}
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
index e7d8642..5746908 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
@@ -553,7 +553,7 @@ public class RealmAdapter implements RealmModel {
      * @return
      */
     @Override
-    public Map<String, ApplicationModel> getResourceNameMap() {
+    public Map<String, ApplicationModel> getApplicationNameMap() {
         Map<String, ApplicationModel> resourceMap = new HashMap<String, ApplicationModel>();
         for (ApplicationModel resource : getApplications()) {
             resourceMap.put(resource.getName(), resource);
@@ -568,10 +568,10 @@ public class RealmAdapter implements RealmModel {
      */
     @Override
     public ApplicationModel getApplicationById(String id) {
-        RelationshipQuery<ResourceRelationship> query = getRelationshipManager().createRelationshipQuery(ResourceRelationship.class);
-        query.setParameter(ResourceRelationship.REALM, realm.getName());
-        query.setParameter(ResourceRelationship.RESOURCE, id);
-        List<ResourceRelationship> results = query.getResultList();
+        RelationshipQuery<ApplicationRelationship> query = getRelationshipManager().createRelationshipQuery(ApplicationRelationship.class);
+        query.setParameter(ApplicationRelationship.REALM, realm.getName());
+        query.setParameter(ApplicationRelationship.APPLICATION, id);
+        List<ApplicationRelationship> results = query.getResultList();
         if (results.size() == 0) return null;
         ApplicationData resource = partitionManager.getPartition(ApplicationData.class, id);
         ApplicationModel model = new ApplicationAdapter(resource, this, partitionManager);
@@ -581,12 +581,12 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public List<ApplicationModel> getApplications() {
-        RelationshipQuery<ResourceRelationship> query = getRelationshipManager().createRelationshipQuery(ResourceRelationship.class);
-        query.setParameter(ResourceRelationship.REALM, realm.getName());
-        List<ResourceRelationship> results = query.getResultList();
+        RelationshipQuery<ApplicationRelationship> query = getRelationshipManager().createRelationshipQuery(ApplicationRelationship.class);
+        query.setParameter(ApplicationRelationship.REALM, realm.getName());
+        List<ApplicationRelationship> results = query.getResultList();
         List<ApplicationModel> resources = new ArrayList<ApplicationModel>();
-        for (ResourceRelationship relationship : results) {
-            ApplicationData resource = partitionManager.getPartition(ApplicationData.class, relationship.getResource());
+        for (ApplicationRelationship relationship : results) {
+            ApplicationData resource = partitionManager.getPartition(ApplicationData.class, relationship.getApplication());
             ApplicationModel model = new ApplicationAdapter(resource, this, partitionManager);
             resources.add(model);
         }
@@ -603,13 +603,13 @@ public class RealmAdapter implements RealmModel {
         applicationData.setResourceName(name);
         applicationData.setResourceUser(resourceUser);
         partitionManager.add(applicationData);
-        ResourceRelationship resourceRelationship = new ResourceRelationship();
+        ApplicationRelationship resourceRelationship = new ApplicationRelationship();
         resourceRelationship.setRealm(realm.getName());
-        resourceRelationship.setResource(applicationData.getName());
+        resourceRelationship.setApplication(applicationData.getName());
         getRelationshipManager().add(resourceRelationship);
         ApplicationModel resource = new ApplicationAdapter(applicationData, this, partitionManager);
         resource.addRole("*");
-        resource.addScope(new UserAdapter(resourceUser, idm), "*");
+        resource.addScopeMapping(new UserAdapter(resourceUser, idm), "*");
         return resource;
     }
 
@@ -667,7 +667,7 @@ public class RealmAdapter implements RealmModel {
 
 
     @Override
-    public void addScope(UserModel agent, String roleName) {
+    public void addScopeMapping(UserModel agent, String roleName) {
         IdentityManager idm = getIdm();
         Role role = SampleModel.getRole(idm, roleName);
         if (role == null) throw new RuntimeException("role not found");
@@ -677,9 +677,31 @@ public class RealmAdapter implements RealmModel {
         getRelationshipManager().add(scope);
     }
 
+    @Override
+    public OAuthClientModel addOAuthClient(String name) {
+        User client = new User(name);
+        getIdm().add(client);
+        OAuthClientRelationship rel = new OAuthClientRelationship();
+        rel.setOauthAgent(client);
+        rel.setRealm(realm.getName());
+        getRelationshipManager().add(rel);
+        return new OAuthClientAdapter(rel, getIdm(), getRelationshipManager());
+    }
+
+    @Override
+    public OAuthClientModel getOAuthClient(String name) {
+        User user = findPicketlinkUser(name);
+        if (user == null) return null;
+        RelationshipQuery<OAuthClientRelationship> query = getRelationshipManager().createRelationshipQuery(OAuthClientRelationship.class);
+        query.setParameter(OAuthClientRelationship.OAUTH_AGENT, user);
+        List<OAuthClientRelationship> results = query.getResultList();
+        if (results.size() == 0) return null;
+        return new OAuthClientAdapter(results.get(0), getIdm(), getRelationshipManager());
+    }
+
 
     @Override
-    public Set<String> getScope(UserModel agent) {
+    public Set<String> getScopeMapping(UserModel agent) {
         RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
         query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
         List<ScopeRelationship> scope = query.getResultList();
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/OAuthClientRelationship.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/OAuthClientRelationship.java
new file mode 100755
index 0000000..a42536e
--- /dev/null
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/OAuthClientRelationship.java
@@ -0,0 +1,57 @@
+package org.keycloak.models.picketlink.relationships;
+
+import org.picketlink.idm.model.AbstractAttributedType;
+import org.picketlink.idm.model.Attribute;
+import org.picketlink.idm.model.Relationship;
+import org.picketlink.idm.model.annotation.AttributeProperty;
+import org.picketlink.idm.model.sample.User;
+import org.picketlink.idm.query.AttributeParameter;
+import org.picketlink.idm.query.RelationshipQueryParameter;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class OAuthClientRelationship extends AbstractAttributedType implements Relationship {
+    private static final long serialVersionUID = 1L;
+
+    public static final AttributeParameter REALM = new AttributeParameter("realm");
+    public static final RelationshipQueryParameter OAUTH_AGENT = new RelationshipQueryParameter() {
+
+        @Override
+        public String getName() {
+            return "oauthAgent";
+        }
+    };
+    protected User oauthAgent;
+
+
+    public OAuthClientRelationship() {
+    }
+
+    public String getRealm() {
+        return (String)getAttribute("realm").getValue();
+    }
+
+    public void setRealm(String realm) {
+        setAttribute(new Attribute<String>("realm", realm));
+    }
+
+    public User getOauthAgent() {
+        return oauthAgent;
+    }
+
+    public void setOauthAgent(User oauthAgent) {
+        this.oauthAgent = oauthAgent;
+    }
+
+    @AttributeProperty
+    public String getBaseUrl() {
+        return (String)getAttribute("baseUrl").getValue();
+    }
+
+    public void setBaseUrl(String base) {
+        setAttribute(new Attribute<String>("baseUrl", base));
+    }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index 6192e0f..00893f9 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -211,7 +211,7 @@ public class AuthenticationManager {
         Set<String> types = new HashSet<String>();
 
         List<RequiredCredentialModel> requiredCredentials = null;
-        if (realm.hasRole(user, RealmManager.RESOURCE_ROLE)) {
+        if (realm.hasRole(user, RealmManager.APPLICATION_ROLE)) {
             requiredCredentials = realm.getRequiredApplicationCredentials();
         } else if (realm.hasRole(user, RealmManager.IDENTITY_REQUESTER_ROLE)) {
             requiredCredentials = realm.getRequiredOAuthClientCredentials();
diff --git a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
new file mode 100755
index 0000000..0efd2a9
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
@@ -0,0 +1,24 @@
+package org.keycloak.services.managers;
+
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class OAuthClientManager {
+    protected RealmModel realm;
+
+    public OAuthClientManager(RealmModel realm) {
+        this.realm = realm;
+    }
+
+    public OAuthClientModel createOAuthClient(String name) {
+        OAuthClientModel model = realm.addOAuthClient(name);
+        RoleModel role = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
+        realm.grantRole(model.getOAuthAgent(), role);
+        return model;
+    }
+}
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index cc5cb2f..cb66e43 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -20,7 +20,7 @@ import java.util.concurrent.atomic.AtomicLong;
 public class RealmManager {
     protected static final Logger logger = Logger.getLogger(RealmManager.class);
     private static AtomicLong counter = new AtomicLong(1);
-    public static final String RESOURCE_ROLE = "KEYCLOAK_RESOURCE";
+    public static final String APPLICATION_ROLE = "KEYCLOAK_APPLICATION";
     public static final String IDENTITY_REQUESTER_ROLE = "KEYCLOAK_IDENTITY_REQUESTER";
     public static final String WILDCARD_ROLE = "*";
 
@@ -50,7 +50,7 @@ public class RealmManager {
         RealmModel realm = identitySession.createRealm(id, name);
         realm.setName(name);
         realm.addRole(WILDCARD_ROLE);
-        realm.addRole(RESOURCE_ROLE);
+        realm.addRole(APPLICATION_ROLE);
         realm.addRole(IDENTITY_REQUESTER_ROLE);
         return realm;
     }
@@ -74,10 +74,12 @@ public class RealmManager {
         if (rep.isRegistrationAllowed() != null) realm.setRegistrationAllowed(rep.isRegistrationAllowed());
         if (rep.isVerifyEmail() != null) realm.setVerifyEmail(rep.isVerifyEmail());
         if (rep.isResetPasswordAllowed() != null) realm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
-        if (rep.isAutomaticRegistrationAfterSocialLogin() != null) realm.setAutomaticRegistrationAfterSocialLogin(rep.isAutomaticRegistrationAfterSocialLogin());
+        if (rep.isAutomaticRegistrationAfterSocialLogin() != null)
+            realm.setAutomaticRegistrationAfterSocialLogin(rep.isAutomaticRegistrationAfterSocialLogin());
         if (rep.isSslNotRequired() != null) realm.setSslNotRequired((rep.isSslNotRequired()));
         if (rep.getAccessCodeLifespan() != null) realm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
-        if (rep.getAccessCodeLifespanUserAction() != null) realm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
+        if (rep.getAccessCodeLifespanUserAction() != null)
+            realm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
         if (rep.getTokenLifespan() != null) realm.setTokenLifespan(rep.getTokenLifespan());
         if (rep.getRequiredOAuthClientCredentials() != null) {
             realm.updateRequiredOAuthClientCredentials(rep.getRequiredOAuthClientCredentials());
@@ -113,7 +115,8 @@ public class RealmManager {
         if (rep.getAccessCodeLifespan() != null) newRealm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
         else newRealm.setAccessCodeLifespan(60);
 
-        if (rep.getAccessCodeLifespanUserAction() != null) newRealm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
+        if (rep.getAccessCodeLifespanUserAction() != null)
+            newRealm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
         else newRealm.setAccessCodeLifespanUserAction(300);
 
         if (rep.isSslNotRequired() != null) newRealm.setSslNotRequired(rep.isSslNotRequired());
@@ -121,7 +124,8 @@ public class RealmManager {
         if (rep.isRegistrationAllowed() != null) newRealm.setRegistrationAllowed(rep.isRegistrationAllowed());
         if (rep.isVerifyEmail() != null) newRealm.setVerifyEmail(rep.isVerifyEmail());
         if (rep.isResetPasswordAllowed() != null) newRealm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
-        if (rep.isAutomaticRegistrationAfterSocialLogin() != null) newRealm.setAutomaticRegistrationAfterSocialLogin(rep.isAutomaticRegistrationAfterSocialLogin());
+        if (rep.isAutomaticRegistrationAfterSocialLogin() != null)
+            newRealm.setAutomaticRegistrationAfterSocialLogin(rep.isAutomaticRegistrationAfterSocialLogin());
         if (rep.getPrivateKey() == null || rep.getPublicKey() == null) {
             generateRealmKeys(newRealm);
         } else {
@@ -175,7 +179,7 @@ public class RealmManager {
         }
 
         if (rep.getApplications() != null) {
-            createResources(rep, newRealm);
+            createApplications(rep, newRealm);
         }
 
         if (rep.getRoleMappings() != null) {
@@ -199,7 +203,7 @@ public class RealmManager {
                         role = newRealm.addRole(roleString.trim());
                     }
                     UserModel user = userMap.get(scope.getUsername());
-                    newRealm.addScope(user, role.getName());
+                    newRealm.addScopeMapping(user, role.getName());
                 }
 
             }
@@ -237,18 +241,23 @@ public class RealmManager {
         }
         if (userRep.getCredentials() != null) {
             for (CredentialRepresentation cred : userRep.getCredentials()) {
-                UserCredentialModel credential = new UserCredentialModel();
-                credential.setType(cred.getType());
-                credential.setValue(cred.getValue());
+                UserCredentialModel credential = fromRepresentation(cred);
                 newRealm.updateCredential(user, credential);
             }
         }
         return user;
     }
 
+    public static UserCredentialModel fromRepresentation(CredentialRepresentation cred) {
+        UserCredentialModel credential = new UserCredentialModel();
+        credential.setType(cred.getType());
+        credential.setValue(cred.getValue());
+        return credential;
+    }
+
     /**
      * Query users based on a search string:
-     *
+     * <p/>
      * "Bill Burke" first and last name
      * "bburke@redhat.com" email
      * "Burke" lastname or username
@@ -291,7 +300,7 @@ public class RealmManager {
             List<UserModel> results = new ArrayList<UserModel>();
             results.addAll(usernameQuery);
             for (UserModel lastnameUser : lastnameQuery) {
-               boolean found = false;
+                boolean found = false;
                 for (UserModel usernameUser : usernameQuery) {
                     if (usernameUser.getLoginName().equals(lastnameUser.getLoginName())) {
                         found = true;
@@ -309,20 +318,21 @@ public class RealmManager {
     public void addRequiredCredential(RealmModel newRealm, String requiredCred) {
         newRealm.addRequiredCredential(requiredCred);
     }
+
     public void addResourceRequiredCredential(RealmModel newRealm, String requiredCred) {
         newRealm.addRequiredResourceCredential(requiredCred);
     }
+
     public void addOAuthClientRequiredCredential(RealmModel newRealm, String requiredCred) {
         newRealm.addRequiredOAuthClientCredential(requiredCred);
     }
 
 
-
-     protected void createResources(RealmRepresentation rep, RealmModel realm) {
-        RoleModel loginRole = realm.getRole(RealmManager.RESOURCE_ROLE);
-        ResourceManager manager = new ResourceManager(this);
+    protected void createApplications(RealmRepresentation rep, RealmModel realm) {
+        RoleModel loginRole = realm.getRole(RealmManager.APPLICATION_ROLE);
+        ApplicationManager manager = new ApplicationManager(this);
         for (ApplicationRepresentation resourceRep : rep.getApplications()) {
-            manager.createResource(realm, loginRole, resourceRep);
+            manager.createApplication(realm, loginRole, resourceRep);
         }
     }
 
diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
index 60e3a98..2d04d8a 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -50,7 +50,7 @@ public class TokenManager {
         Set<String> realmMapping = realm.getRoleMappingValues(user);
 
         if (realmMapping != null && realmMapping.size() > 0 && (scopeMap == null || scopeMap.containsKey("realm"))) {
-            Set<String> scope = realm.getScope(client);
+            Set<String> scope = realm.getScopeMapping(client);
             if (scope.size() > 0) {
                 Set<String> scopeRequest = null;
                 if (scopeMap != null) {
@@ -69,7 +69,7 @@ public class TokenManager {
         for (ApplicationModel resource : realm.getApplications()) {
             Set<String> mapping = resource.getRoleMappingValues(user);
             if (mapping != null && mapping.size() > 0 && (scopeMap == null || scopeMap.containsKey(resource.getName()))) {
-                Set<String> scope = resource.getScope(client);
+                Set<String> scope = resource.getScopeMapping(client);
                 if (scope.size() > 0) {
                     Set<String> scopeRequest = null;
                     if (scopeMap != null) {
@@ -131,7 +131,7 @@ public class TokenManager {
         }
 
         if (accessCodeEntry.getResourceRolesRequested().size() > 0) {
-            Map<String, ApplicationModel> resourceMap = realm.getResourceNameMap();
+            Map<String, ApplicationModel> resourceMap = realm.getApplicationNameMap();
             for (String resourceName : accessCodeEntry.getResourceRolesRequested().keySet()) {
                 ApplicationModel resource = resourceMap.get(resourceName);
                 SkeletonKeyToken.Access access = token.addAccess(resourceName).verifyCaller(resource.isSurrogateAuthRequired());
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
index cb73b0c..2117cb2 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
@@ -4,9 +4,10 @@ import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
 import org.keycloak.models.*;
 import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.services.managers.ApplicationManager;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.managers.ResourceManager;
 
 import javax.ws.rs.*;
 import javax.ws.rs.core.Context;
@@ -38,17 +39,17 @@ public class ApplicationResource {
     @PUT
     @Consumes(MediaType.APPLICATION_JSON)
     public void update(final ApplicationRepresentation rep) {
-        ResourceManager resourceManager = new ResourceManager(new RealmManager(session));
-        resourceManager.updateResource(rep, application);
+        ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
+        applicationManager.updateApplication(rep, application);
     }
 
 
     @GET
     @NoCache
     @Produces(MediaType.APPLICATION_JSON)
-    public ApplicationRepresentation getResource(final @PathParam("id") String id) {
-        ResourceManager resourceManager = new ResourceManager(new RealmManager(session));
-        return resourceManager.toRepresentation(application);
+    public ApplicationRepresentation getApplication() {
+        ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
+        return applicationManager.toRepresentation(application);
     }
 
     @Path("roles")
@@ -104,4 +105,18 @@ public class ApplicationResource {
         return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getId()).build()).build();
     }
 
+    @Path("credentials")
+    @PUT
+    @Consumes("application/json")
+    public void updateCredentials(List<CredentialRepresentation> credentials) {
+        logger.info("updateCredentials");
+        if (credentials == null) return;
+
+        for (CredentialRepresentation rep : credentials) {
+            UserCredentialModel cred = RealmManager.fromRepresentation(rep);
+            realm.updateCredential(application.getApplicationUser(), cred);
+        }
+
+    }
+
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
index a8a8afe..1f5138e 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
@@ -3,8 +3,8 @@ package org.keycloak.services.resources.admin;
 import org.jboss.resteasy.annotations.cache.NoCache;
 import org.jboss.resteasy.logging.Logger;
 import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.services.managers.ApplicationManager;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.managers.ResourceManager;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
@@ -45,7 +45,7 @@ public class ApplicationsResource {
     public List<ApplicationRepresentation> getResources() {
         List<ApplicationRepresentation> rep = new ArrayList<ApplicationRepresentation>();
         List<ApplicationModel> applicationModels = realm.getApplications();
-        ResourceManager resourceManager = new ResourceManager(new RealmManager(session));
+        ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session));
         for (ApplicationModel applicationModel : applicationModels) {
             rep.add(resourceManager.toRepresentation(applicationModel));
         }
@@ -55,8 +55,8 @@ public class ApplicationsResource {
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     public Response createResource(final @Context UriInfo uriInfo, final ApplicationRepresentation rep) {
-        ResourceManager resourceManager = new ResourceManager(new RealmManager(session));
-        ApplicationModel applicationModel = resourceManager.createResource(realm, rep);
+        ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session));
+        ApplicationModel applicationModel = resourceManager.createApplication(realm, rep);
         return Response.created(uriInfo.getAbsolutePathBuilder().path(applicationModel.getId()).build()).build();
     }
 
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index dec1721..3008b92 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -322,4 +322,22 @@ public class UsersResource {
             }
         }
     }
+
+    @Path("{username}/credentials")
+    @PUT
+    @Consumes("application/json")
+    public void updateCredentials(@PathParam("username") String username, List<CredentialRepresentation> credentials) {
+        UserModel user = realm.getUser(username);
+        if (user == null) {
+            throw new NotFoundException();
+        }
+        if (credentials == null) return;
+
+        for (CredentialRepresentation rep : credentials) {
+            UserCredentialModel cred = RealmManager.fromRepresentation(rep);
+            realm.updateCredential(user, cred);
+        }
+
+    }
+
 }
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
index dafc11a..16cc933 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
@@ -81,7 +81,7 @@ public class OAuthFlows {
     }
 
     public Response processAccessCode(String scopeParam, String state, String redirect, UserModel client, UserModel user) {
-        RoleModel resourceRole = realm.getRole(RealmManager.RESOURCE_ROLE);
+        RoleModel resourceRole = realm.getRole(RealmManager.APPLICATION_ROLE);
         RoleModel identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
         boolean isResource = realm.hasRole(client, resourceRole);
         if (!isResource && !realm.hasRole(client, identityRequestRole)) {
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index 0a80d02..c168962 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -451,7 +451,7 @@ public class TokenService {
             return null;
         }
 
-        RoleModel resourceRole = realm.getRole(RealmManager.RESOURCE_ROLE);
+        RoleModel resourceRole = realm.getRole(RealmManager.APPLICATION_ROLE);
         RoleModel identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
         boolean isResource = realm.hasRole(client, resourceRole);
         if (!isResource && !realm.hasRole(client, identityRequestRole)) {
diff --git a/services/src/test/java/org/keycloak/test/AdapterTest.java b/services/src/test/java/org/keycloak/test/AdapterTest.java
index ec92f41..aa2767a 100755
--- a/services/src/test/java/org/keycloak/test/AdapterTest.java
+++ b/services/src/test/java/org/keycloak/test/AdapterTest.java
@@ -6,15 +6,10 @@ import org.junit.Before;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
+import org.keycloak.models.*;
 import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.services.managers.OAuthClientManager;
 import org.keycloak.services.managers.RealmManager;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RequiredCredentialModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.services.resources.KeycloakApplication;
 
@@ -136,6 +131,19 @@ public class AdapterTest {
     }
 
     @Test
+    public void testOAuthClient() throws Exception {
+        test1CreateRealm();
+
+        OAuthClientModel oauth = new OAuthClientManager(realmModel).createOAuthClient("oauth-client");
+        oauth.setBaseUrl("/foo/bar");
+        oauth = realmModel.getOAuthClient("oauth-client");
+        Assert.assertEquals("/foo/bar", oauth.getBaseUrl());
+        Assert.assertTrue(realmModel.hasRole(oauth.getOAuthAgent(), RealmManager.IDENTITY_REQUESTER_ROLE));
+
+
+    }
+
+    @Test
     public void testUserSearch() throws Exception {
         test1CreateRealm();
         {
diff --git a/services/src/test/java/org/keycloak/test/ImportTest.java b/services/src/test/java/org/keycloak/test/ImportTest.java
index 4b77a62..30c8190 100755
--- a/services/src/test/java/org/keycloak/test/ImportTest.java
+++ b/services/src/test/java/org/keycloak/test/ImportTest.java
@@ -86,7 +86,7 @@ public class ImportTest {
 
         UserModel user = realm.getUser("loginclient");
         Assert.assertNotNull(user);
-        Set<String> scopes = realm.getScope(user);
+        Set<String> scopes = realm.getScopeMapping(user);
         System.out.println("Scopes size: " + scopes.size());
         Assert.assertTrue(scopes.contains("*"));
         Assert.assertEquals(0, realm.getSocialLinks(user).size());
@@ -97,11 +97,11 @@ public class ImportTest {
         Assert.assertEquals(1, realms.size());
 
         // Test scope relationship
-        ApplicationModel application = realm.getResourceNameMap().get("Application");
+        ApplicationModel application = realm.getApplicationNameMap().get("Application");
         UserModel oauthClient = realm.getUser("oauthclient");
         Assert.assertNotNull(application);
         Assert.assertNotNull(oauthClient);
-        Set<String> appScopes = application.getScope(oauthClient);
+        Set<String> appScopes = application.getScopeMapping(oauthClient);
         Assert.assertTrue(appScopes.contains("user"));
 
         // Test social linking