keycloak-memoizeit

user panels and query

8/12/2013 10:41:55 AM

Details

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 6afcfed..ca23826 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
@@ -55,11 +55,8 @@ module.config([ '$routeProvider', function($routeProvider) {
 		resolve : {
 			realm : function(RealmLoader) {
 				return RealmLoader();
-			},
-			users : function(UserListLoader) {
-				return UserListLoader();
 			}
-		},
+        },
 		controller : 'UserListCtrl'
 	})
 
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 8680990..edfa8d9 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
@@ -181,15 +181,39 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $ht
 });
 
 
-module.controller('UserListCtrl', function($scope, realm, users) {
+module.controller('UserListCtrl', function($scope, realm, User) {
 	$scope.realm = realm;
-	$scope.users = users;
+    $scope.users = [];
+    $scope.query = "*";
+    $scope.attribute = {};
+    var params = {};
+
+    $scope.addAttribute = function() {
+        console.log('queryAttribute');
+        params[$scope.attribute.name] = $scope.attribute.value;
+        for (var key in params) {
+            $scope.query = " " + key + "=" +params[key];
+        }
+    };
+
+    $scope.executeQuery = function() {
+        console.log('executeQuery');
+        var parameters = angular.copy(params);
+        parameters["realm"] = realm.id;
+        $scope.users = User.query(parameters);
+    };
+
+    $scope.clearQuery = function() {
+        params = {};
+        $scopre.query = "*";
+        $scope.users = [];
+    };
 });
 
 module.controller('UserDetailCtrl', function($scope, realm, user, User, $location, Dialog, Notifications) {
 	$scope.realm = realm;
 	$scope.user = angular.copy(user);
-	$scope.create = !user.userId;
+	$scope.create = !user.username;
 
 	$scope.changed = $scope.create;
 
@@ -201,23 +225,28 @@ module.controller('UserDetailCtrl', function($scope, realm, user, User, $locatio
 
 	$scope.save = function() {
 		if ($scope.userForm.$valid) {
+            if ($scope.create) {
+                User.save({
+                    realm: realm.id
+                }, $scope.user, function () {
+                    $scope.changed = false;
+                    user = angular.copy($scope.user);
 
+                    $location.url("/realms/" + realm.id + "/users/" + $scope.user.username);
+                    Notifications.success("Created user");
+                });
+            } else {
+                User.update({
+                    realm: realm.id,
+                    userId: $scope.user.username
+                }, $scope.user, function () {
+                    $scope.changed = false;
+                    user = angular.copy($scope.user);
+                    Notifications.success("Saved changes to user");
+                });
 
-
-			User.save({
-				realm : realm.id
-			}, $scope.user, function() {
-				$scope.changed = false;
-				user = angular.copy($scope.user);
-
-				if ($scope.create) {
-					$location.url("/realms/" + realm.id + "/users/" + $scope.user.userId);
-					Notifications.success("Created user");
-				} else {
-					Notifications.success("Saved changes to user");
-				}
-			});
-		} else {
+            }
+        } else {
 			$scope.userForm.showErrors = true;
 		}
 	};
@@ -236,7 +265,7 @@ module.controller('UserDetailCtrl', function($scope, realm, user, User, $locatio
 		Dialog.confirmDelete($scope.user.userId, 'user', function() {
 			$scope.user.$remove({
 				realm : realm.id,
-				userId : $scope.user.userId
+				userId : $scope.user.username
 			}, function() {
 				$location.url("/realms/" + realm.id + "/users");
 				Notifications.success("Deleted user");
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 b3cd88f..1b70951 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
@@ -110,11 +110,11 @@ module.factory('RoleMapping', function($resource) {
 });
 
 module.factory('User', function($resource) {
-	return $resource('/keycloak-server/ui/api/realms/:realm/users/:userId', {
+	return $resource('/auth-server/rest/saas/admin/realms/:realm/users/:userId', {
 		realm : '@realm',
 		userId : '@userId'
 	}, {
-		save : {
+		update : {
 			method : 'PUT'
 		}
 	});
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/realm-menu.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/realm-menu.html
index fc10132..ae5217a 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/realm-menu.html
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/realm-menu.html
@@ -6,7 +6,7 @@
                     <li data-ng-class="path[0] == 'create' && path[1] == 'user' && 'active'"><a
                             href="#/create/user/{{realm.id}}">New User</a></li>
                     <li data-ng-class="path[0] == 'find' && path[1] == 'user' && 'active'"><a
-                            href="#/find/user/{{realm.id}}">Find User</a></li>
+                            href="#/realms/{{realm.id}}/users">Find User</a></li>
                 </ul>
             </li>
             <li data-ng-class="path[2] == 'roles' && 'active'"><a href="#/realms/{{realm.id}}/roles">Roles</a>
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-detail.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-detail.html
index a2ea839..0c68075 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-detail.html
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-detail.html
@@ -13,13 +13,13 @@
             <div data-ng-show="roleForm.showErrors && roleForm.$error.required" class="alert alert-error">Please fill in
                 all required fields
             </div>
-            <p class="subtitle subtitle-right"><span class="required">*</span> Required fields</p>
+            <p class="subtitle subtitle-right" data-ng-show="create"><span class="required">*</span> Required fields</p>
 
             <form class="form-horizontal" name="roleForm" novalidate>
                 <fieldset>
                     <legend>Details</legend>
                     <div class="control-group">
-                        <label class="control-label" for="name">Role name <span class="required">*</span></label>
+                        <label class="control-label" for="name">Role name <span class="required" data-ng-show="create">*</span></label>
 
                         <div class="controls">
                             <input type="text" class="input-xlarge" id="name" name="name" data-ng-model="role.name"
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-list.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-list.html
index 107f6fd..7f27c7c 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-list.html
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/role-list.html
@@ -4,8 +4,6 @@
         <div id="actions-bg"></div>
 
         <div id="container-right" class="span9">
-            <a class="btn btn-small pull-right" href="#/create/role/{{realm.id}}">Add Role</a>
-
             <h1>
                 <span class="gray">Realm Roles</span>
             </h1>
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/user-detail.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/user-detail.html
index 67af006..bcd7d20 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/user-detail.html
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/user-detail.html
@@ -7,27 +7,36 @@
             <h1 data-ng-show="create"><span class="gray">New User</span></h1>
 
             <h1 data-ng-hide="create">
-                <span class="gray">{{user.userId}}</span> configuration
+                <span class="gray">User {{user.username}}</span>
             </h1>
 
             <div data-ng-show="userForm.showErrors && userForm.$error.required" class="alert alert-error">Please fill in
                 all required fields
             </div>
-            <p class="subtitle subtitle-right"><span class="required">*</span> Required fields</p>
+            <p class="subtitle subtitle-right" data-ng-show="create"><span class="required">*</span> Required fields</p>
 
             <form class="form-horizontal" name="userForm" novalidate>
                 <fieldset>
                     <legend>Details</legend>
                     <div class="control-group">
-                        <label class="control-label" for="name">Username <span class="required">*</span></label>
+                        <label class="control-label" for="name">Username <span class="required" data-ng-show="create">*</span></label>
 
                         <div class="controls">
-                            <input type="text" class="input-xlarge" id="name" name="name" data-ng-model="user.userId"
+                            <input type="text" class="input-xlarge" id="name" name="name" data-ng-model="user.username"
                                    autofocus required data-ng-readonly="!create">
                         </div>
                     </div>
 
                     <div class="control-group">
+                        <label class="control-label">Enabled</label>
+
+                        <div class="controls">
+                            <input class="input-xlarge" type="checkbox" name="enabled"
+                                   data-ng-model="realm.enabled">
+                        </div>
+                    </div>
+
+                    <div class="control-group">
                         <label class="control-label" for="email">Email </label>
 
                         <div class="controls">
@@ -52,15 +61,6 @@
                             <input type="text" class="input-xlarge" id="lastName" data-ng-model="user.lastName">
                         </div>
                     </div>
-
-                    <div class="control-group">
-                        <label class="control-label" for="password">Password <span class="required">*</span></label>
-
-                        <div class="controls">
-                            <input type="password" class="input-xlarge" id="password" name="password"
-                                   data-ng-model="user.password" data-ng-required="create">
-                        </div>
-                    </div>
                 </fieldset>
 
                 <fieldset data-ng-show="user.attributes.length > 0">
@@ -94,7 +94,6 @@
                     </button>
                     <button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes
                     </button>
-                    <a href="#/realms/{{realm.id}}/users" data-ng-hide="changed">View users &#187;</a>
                     <button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">
                         Delete
                     </button>
diff --git a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/user-list.html b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/user-list.html
index 43957a7..59dd555 100755
--- a/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/user-list.html
+++ b/examples/as7-eap-demo/server/src/main/webapp/saas/admin/partials/user-list.html
@@ -3,13 +3,42 @@
         <aside class="span3" data-ng-include data-src="'partials/realm-menu.html'"></aside>
         <div id="actions-bg"></div>
 
+
         <div id="container-right" class="span9">
-            <a class="btn btn-small pull-right" href="#/create/user/{{realm.id}}">Add User</a>
+            <form class="form-horizontal" name="queryForm" novalidate>
+                <div class="control-group">
+                    <label class="control-label">Query </label>
+
+                    <div class="controls">
+                        <input type="text" class="input-xlarge" id="query" name="query" data-ng-model="query"
+                               autofocus required readonly>
+                        <button type="submit" data-ng-click="executeQuery()" class="btn btn-primary">Execute Query
+                        </button>
+                    </div>
+                </div>
+            </form>
 
-            <h1>
-                <span class="gray">{{realm.name}}</span> users
-            </h1>
+            <form class="form-horizontal" name="queryAttribute" novalidate>
+                <fieldset>
+                    <div class="control-group">
+                        <label class="control-label">Predefined Attribute</label>
 
+                        <div class="controls">
+                            <select style="width: auto;" name="name"
+                                    data-ng-model="attribute.name">
+                                <option value="loginName">Login name</option>
+                                <option value="lastName">Last name</option>
+                                <option value="firstName">First name</option>
+                                <option value="email">Email</option>
+                            </select>
+                            <input class="input-small" type="text" name="value"
+                                   data-ng-model="attribute.value">
+                            <button type="submit" data-ng-click="addAttribute()" class="btn btn-primary">Add Attribute
+                            </button>
+                        </div>
+                    </div>
+                </fieldset>
+            </form>
             <table class="table table-striped table-bordered">
                 <thead>
                 <tr>
@@ -20,7 +49,7 @@
                 </tr>
                 </thead>
                 <tr data-ng-repeat="user in users">
-                    <td><a href="#/realms/{{realm.id}}/users/{{user.userId}}">{{user.userId}}</a></td>
+                    <td><a href="#/realms/{{realm.id}}/users/{{user.username}}">{{user.username}}</a></td>
                     <td>{{user.firstName}}</td>
                     <td>{{user.lastName}}</td>
                     <td>{{user.email}}</td>
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 524fb88..7c149f6 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -131,10 +131,10 @@ public class RealmManager {
         }
 
 
-
+        UserManager userManager = new UserManager();
         if (rep.getUsers() != null) {
             for (UserRepresentation userRep : rep.getUsers()) {
-                UserModel user = createUser(newRealm, userRep);
+                UserModel user = userManager.createUser(newRealm, userRep);
                 userMap.put(user.getLoginName(), user);
             }
         }
@@ -182,24 +182,6 @@ public class RealmManager {
         if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
     }
 
-    public UserModel createUser(RealmModel newRealm, UserRepresentation userRep) {
-        UserModel user = newRealm.addUser(userRep.getUsername());
-        user.setEnabled(userRep.isEnabled());
-        if (userRep.getAttributes() != null) {
-            for (Map.Entry<String, String> entry : userRep.getAttributes().entrySet()) {
-                user.setAttribute(entry.getKey(), entry.getValue());
-            }
-        }
-        if (userRep.getCredentials() != null) {
-            for (CredentialRepresentation cred : userRep.getCredentials()) {
-                UserCredentialModel credential = new UserCredentialModel();
-                credential.setType(cred.getType());
-                credential.setValue(cred.getValue());
-                newRealm.updateCredential(user, credential);
-            }
-        }
-        return user;
-    }
 
     public void addRequiredCredential(RealmModel newRealm, String requiredCred) {
         newRealm.addRequiredCredential(requiredCred);
diff --git a/services/src/main/java/org/keycloak/services/managers/UserManager.java b/services/src/main/java/org/keycloak/services/managers/UserManager.java
new file mode 100755
index 0000000..6773016
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/managers/UserManager.java
@@ -0,0 +1,89 @@
+package org.keycloak.services.managers;
+
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.services.models.RealmModel;
+import org.keycloak.services.models.UserCredentialModel;
+import org.keycloak.services.models.UserModel;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class UserManager {
+
+    public static UserRepresentation toRepresentation(UserModel user) {
+        UserRepresentation rep = new UserRepresentation();
+        rep.setEmail(user.getEmail());
+        rep.setLastName(user.getLastName());
+        rep.setFirstName(user.getFirstName());
+        rep.setEnabled(user.isEnabled());
+        rep.setUsername(user.getLoginName());
+        for (Map.Entry<String, String> entry : user.getAttributes().entrySet()) {
+            rep.attribute(entry.getKey(), entry.getValue());
+        }
+        return rep;
+    }
+
+    public UserModel createUser(RealmModel newRealm, UserRepresentation userRep) {
+        UserModel user = newRealm.addUser(userRep.getUsername());
+        user.setEnabled(userRep.isEnabled());
+        user.setEmail(userRep.getEmail());
+        user.setFirstName(userRep.getFirstName());
+        user.setLastName(userRep.getLastName());
+        if (userRep.getAttributes() != null) {
+            for (Map.Entry<String, String> entry : userRep.getAttributes().entrySet()) {
+                user.setAttribute(entry.getKey(), entry.getValue());
+            }
+        }
+        if (userRep.getCredentials() != null) {
+            for (CredentialRepresentation cred : userRep.getCredentials()) {
+                UserCredentialModel credential = new UserCredentialModel();
+                credential.setType(cred.getType());
+                credential.setValue(cred.getValue());
+                newRealm.updateCredential(user, credential);
+            }
+        }
+        return user;
+    }
+
+    /**
+     * Doesn't allow you to change loginname.
+     *
+     * @param user
+     * @param userRep
+     */
+    public void updateUserAsAdmin(UserModel user, UserRepresentation userRep) {
+        user.setEnabled(userRep.isEnabled());
+        user.setEmail(userRep.getEmail());
+        user.setFirstName(userRep.getFirstName());
+        user.setLastName(userRep.getLastName());
+        if (userRep.getAttributes() != null) {
+            for (Map.Entry<String, String> entry : userRep.getAttributes().entrySet()) {
+                user.setAttribute(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+    /**
+     * Doesn't allow you to change loginname.
+     * Doesn't allow you to change enable
+     *
+     * @param user
+     * @param userRep
+     */
+    public void updateUserAsUser(UserModel user, UserRepresentation userRep) {
+        user.setEmail(userRep.getEmail());
+        user.setFirstName(userRep.getFirstName());
+        user.setLastName(userRep.getLastName());
+        if (userRep.getAttributes() != null) {
+            for (Map.Entry<String, String> entry : userRep.getAttributes().entrySet()) {
+                user.setAttribute(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+
+}
diff --git a/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java b/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java
index 2e7371a..4e014ff 100755
--- a/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java
+++ b/services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java
@@ -25,6 +25,7 @@ import org.picketlink.idm.credential.TOTPCredential;
 import org.picketlink.idm.credential.TOTPCredentials;
 import org.picketlink.idm.credential.UsernamePasswordCredentials;
 import org.picketlink.idm.credential.X509CertificateCredentials;
+import org.picketlink.idm.model.AttributedType;
 import org.picketlink.idm.model.IdentityType;
 import org.picketlink.idm.model.annotation.AttributeProperty;
 import org.picketlink.idm.model.sample.Grant;
@@ -477,6 +478,21 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
+    public List<UserModel> queryUsers(Map<String, String> parameters) {
+        IdentityQuery<User> userQuery = getIdm().createIdentityQuery(User.class);
+        for (Map.Entry<String, String> entry : parameters.entrySet()) {
+            userQuery.setParameter(AttributedType.QUERY_ATTRIBUTE.byName(entry.getKey()), entry.getValue());
+        }
+        List<User> users = userQuery.getResultList();
+        List<UserModel> userModels = new ArrayList<UserModel>();
+        for (User user : users) {
+            userModels.add(new UserAdapter(user, getIdm()));
+        }
+        return userModels;
+
+    }
+
+    @Override
     public RoleAdapter getRole(String name) {
         Role role = SampleModel.getRole(getIdm(), name);
         if (role == null) return null;
diff --git a/services/src/main/java/org/keycloak/services/models/RealmModel.java b/services/src/main/java/org/keycloak/services/models/RealmModel.java
index 605de11..1d7b3fd 100755
--- a/services/src/main/java/org/keycloak/services/models/RealmModel.java
+++ b/services/src/main/java/org/keycloak/services/models/RealmModel.java
@@ -124,4 +124,6 @@ public interface RealmModel {
     boolean isSocial();
 
     void setSocial(boolean social);
+
+    List<UserModel> queryUsers(Map<String, String> parameters);
 }
diff --git a/services/src/main/java/org/keycloak/services/models/UserModel.java b/services/src/main/java/org/keycloak/services/models/UserModel.java
index f6eccf2..83585de 100755
--- a/services/src/main/java/org/keycloak/services/models/UserModel.java
+++ b/services/src/main/java/org/keycloak/services/models/UserModel.java
@@ -7,6 +7,10 @@ import java.util.Map;
  * @version $Revision: 1 $
  */
 public interface UserModel {
+    public static final String LAST_NAME = "lastName";
+    public static final String FIRST_NAME = "firstName";
+    public static final String EMAIL = "email";
+
     String getLoginName();
 
     boolean isEnabled();
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 539d34b..e5fc7ac 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
@@ -6,25 +6,21 @@ import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.services.managers.RealmManager;
+import org.keycloak.services.managers.UserManager;
 import org.keycloak.services.models.RealmModel;
 import org.keycloak.services.models.RoleModel;
 import org.keycloak.services.models.UserModel;
 import org.keycloak.services.resources.Transaction;
 
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.InternalServerErrorException;
-import javax.ws.rs.NotFoundException;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
+import javax.ws.rs.*;
 import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -62,7 +58,7 @@ public class RealmAdminResource {
     @GET
     @NoCache
     @Produces("application/json")
-    public List<RoleRepresentation> getRoles() {
+    public List<RoleRepresentation> queryRoles() {
         return new Transaction() {
             @Override
             protected List<RoleRepresentation> callImpl() {
@@ -70,6 +66,7 @@ public class RealmAdminResource {
                 List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
                 for (RoleModel roleModel : roleModels) {
                     RoleRepresentation role = new RoleRepresentation(roleModel.getName(), roleModel.getDescription());
+                    role.setId(roleModel.getId());
                     roles.add(role);
                 }
                 return roles;
@@ -154,11 +151,86 @@ public class RealmAdminResource {
     @GET
     @NoCache
     @Produces("application/json")
-    public List<UserRepresentation> getUsers() {
-        return null;
+    public List<UserRepresentation> queryUsers(final @Context UriInfo uriInfo) {
+        return new Transaction() {
+            @Override
+            protected List<UserRepresentation> callImpl() {
+                logger.info("queryUsers");
+                Map<String, String> params = new HashMap<String, String>();
+                MultivaluedMap<String,String> queryParameters = uriInfo.getQueryParameters();
+                for (String key : queryParameters.keySet()) {
+                    logger.info("   " + key + "=" + queryParameters.getFirst(key));
+                    params.put(key, queryParameters.getFirst(key));
+                }
+                List<UserModel> userModels = realm.queryUsers(params);
+                List<UserRepresentation> users = new ArrayList<UserRepresentation>();
+                for (UserModel userModel : userModels) {
+                    users.add(UserManager.toRepresentation(userModel));
+                }
+                logger.info("   resultSet: " + users.size());
+                return users;
+            }
+        }.call();
+    }
+
+    @Path("users/{loginName}")
+    @GET
+    @NoCache
+    @Produces("application/json")
+    public UserRepresentation getUser(final @PathParam("loginName") String loginName) {
+        return new Transaction() {
+            @Override
+            protected UserRepresentation callImpl() {
+                UserModel userModel = realm.getUser(loginName);
+                if (userModel == null) {
+                    throw new NotFoundException();
+                }
+                return UserManager.toRepresentation(userModel);
+            }
+        }.call();
+    }
+
+    @Path("users")
+    @POST
+    @NoCache
+    @Consumes("application/json")
+    public Response createUser(final @Context UriInfo uriInfo, final UserRepresentation rep) {
+        return new Transaction() {
+            @Override
+            protected Response callImpl() {
+                if (realm.getUser(rep.getUsername()) != null) {
+                    return Response.status(Response.Status.FOUND).build();
+                }
+                rep.setCredentials(null); // don't allow credential creation
+                UserManager userManager = new UserManager();
+                UserModel userModel = userManager.createUser(realm, rep);
+                return Response.created(uriInfo.getAbsolutePathBuilder().path(userModel.getLoginName()).build()).build();
+            }
+        }.call();
+    }
+
+    @Path("users/{loginName}")
+    @PUT
+    @NoCache
+    @Consumes("application/json")
+    public void updateUser(final @PathParam("loginName") String loginName, final UserRepresentation rep) {
+        new Transaction() {
+            @Override
+            protected void runImpl() {
+                UserModel userModel = realm.getUser(loginName);
+                if (userModel == null) {
+                    throw new NotFoundException();
+                }
+                UserManager userManager = new UserManager();
+                userManager.updateUserAsAdmin(userModel, rep);
+            }
+        }.run();
     }
 
 
 
 
+
+
+
 }