commit
a1893e4ea5
11 changed files with 453 additions and 205 deletions
|
@ -184,30 +184,14 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, $ht
|
||||||
module.controller('UserListCtrl', function($scope, realm, User) {
|
module.controller('UserListCtrl', function($scope, realm, User) {
|
||||||
$scope.realm = realm;
|
$scope.realm = realm;
|
||||||
$scope.users = [];
|
$scope.users = [];
|
||||||
$scope.query = "*";
|
//$scope.search = "Search...";
|
||||||
$scope.attribute = {};
|
|
||||||
var params = {};
|
|
||||||
|
|
||||||
$scope.addAttribute = function() {
|
$scope.searchQuery = function() {
|
||||||
console.log('queryAttribute');
|
console.log('search: ' + $scope.search);
|
||||||
params[$scope.attribute.name] = $scope.attribute.value;
|
var parameters = { search : $scope.search };
|
||||||
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;
|
parameters["realm"] = realm.id;
|
||||||
$scope.users = User.query(parameters);
|
$scope.users = User.query(parameters);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.clearQuery = function() {
|
|
||||||
params = {};
|
|
||||||
$scopre.query = "*";
|
|
||||||
$scope.users = [];
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.controller('UserDetailCtrl', function($scope, realm, user, User, $location, Dialog, Notifications) {
|
module.controller('UserDetailCtrl', function($scope, realm, user, User, $location, Dialog, Notifications) {
|
||||||
|
@ -224,37 +208,32 @@ module.controller('UserDetailCtrl', function($scope, realm, user, User, $locatio
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
$scope.save = function() {
|
$scope.save = function() {
|
||||||
if ($scope.userForm.$valid) {
|
if ($scope.create) {
|
||||||
if ($scope.create) {
|
User.save({
|
||||||
User.save({
|
realm: realm.id
|
||||||
realm: realm.id
|
}, $scope.user, function () {
|
||||||
}, $scope.user, function () {
|
$scope.changed = false;
|
||||||
$scope.changed = false;
|
user = angular.copy($scope.user);
|
||||||
user = angular.copy($scope.user);
|
|
||||||
|
|
||||||
$location.url("/realms/" + realm.id + "/users/" + $scope.user.username);
|
$location.url("/realms/" + realm.id + "/users/" + $scope.user.username);
|
||||||
Notifications.success("Created user");
|
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");
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$scope.userForm.showErrors = true;
|
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");
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.reset = function() {
|
$scope.reset = function() {
|
||||||
$scope.user = angular.copy(user);
|
$scope.user = angular.copy(user);
|
||||||
$scope.changed = false;
|
$scope.changed = false;
|
||||||
$scope.userForm.showErrors = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.cancel = function() {
|
$scope.cancel = function() {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<caption>Table of realm applications</caption>
|
<caption>Table of realm applications</caption>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="rcue-table-actions" colspan="4">
|
<th class="rcue-table-actions" colspan="3">
|
||||||
<div class="search-comp clearfix">
|
<div class="search-comp clearfix">
|
||||||
<input type="text" placeholder="Search..." class="search">
|
<input type="text" placeholder="Search..." class="search">
|
||||||
<button class="icon-search tooltipRightTrigger"
|
<button class="icon-search tooltipRightTrigger"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<ul data-ng-hide="createRealm">
|
<ul data-ng-hide="createRealm">
|
||||||
<li data-ng-class="!path[2] && 'active'"><a href="#/realms/{{realm.id}}">Realm Settings</a></li>
|
<li data-ng-class="!path[2] && 'active'"><a href="#/realms/{{realm.id}}">Realm Settings</a></li>
|
||||||
<li data-ng-class="path[2] == 'users' && 'active'"><a href="#/realms/{{realm.id}}/users">Users</a>
|
<li data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.id}}/users">Users</a>
|
||||||
</li>
|
</li>
|
||||||
<li data-ng-class="(path[2] == 'applications' || path[1] == 'application') && 'active'"><a href="#/realms/{{realm.id}}/applications">Applications</a></li>
|
<li data-ng-class="(path[2] == 'applications' || path[1] == 'application') && 'active'"><a href="#/realms/{{realm.id}}/applications">Applications</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,106 +1,83 @@
|
||||||
<div id="wrapper" class="container">
|
<div id="wrapper" class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<aside class="span3" data-ng-include data-src="'partials/realm-menu.html'"></aside>
|
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
|
||||||
<div id="actions-bg"></div>
|
<div id="content-area" class="col-md-9" role="main">
|
||||||
|
<div class="top-nav" data-ng-show="create">
|
||||||
<div id="container-right" class="span9">
|
<ul class="rcue-tabs" >
|
||||||
<h1 data-ng-show="create"><span class="gray">New User</span></h1>
|
<li class="active"><a href="#">New User</a></li>
|
||||||
|
<li><a href="#">Users</a></li>
|
||||||
<h1 data-ng-hide="create">
|
</ul>
|
||||||
<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>
|
</div>
|
||||||
<p class="subtitle subtitle-right" data-ng-show="create"><span class="required">*</span> Required fields</p>
|
<div class="top-nav" data-ng-show="!create">
|
||||||
|
<ul class="rcue-tabs" >
|
||||||
<form class="form-horizontal" name="userForm" novalidate>
|
<li class="active"><a href="#">Attributes</a></li>
|
||||||
<fieldset>
|
<li><a href="#">Credentials</a></li>
|
||||||
<legend>Details</legend>
|
<li><a href="#">Role Mappings</a></li>
|
||||||
<div class="control-group">
|
</ul>
|
||||||
<label class="control-label" for="name">Username <span class="required" data-ng-show="create">*</span></label>
|
</div>
|
||||||
|
<div id="content">
|
||||||
<div class="controls">
|
<h2 class="pull-left" data-ng-show="create">New User</h2>
|
||||||
<input type="text" class="input-xlarge" id="name" name="name" data-ng-model="user.username"
|
<h2 class="pull-left" data-ng-hide="create">User <span>{{user.username}}</span></h2>
|
||||||
autofocus required data-ng-readonly="!create">
|
<p class="subtitle"><span class="required">*</span> Required fields</p>
|
||||||
|
<form name="applicationForm" novalidate>
|
||||||
|
<fieldset>
|
||||||
|
<legend uncollapsed><span class="text">Attributes</span></legend>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">Username </label><span class="required" data-ng-show="create">*</span>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="username" name="username" data-ng-model="user.username" autofocus
|
||||||
|
required data-ng-readonly="!create">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email" class="control-label">Email</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<input class="input-small" type="text" name="email" id="email"
|
||||||
|
data-ng-model="user.email">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="firstName" class="control-label">First Name</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<input class="input-small" type="text" name="firstName" id="firstName"
|
||||||
|
data-ng-model="user.firstName">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="lastName" class="control-label">Last Name</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<input class="input-small" type="text" name="lastName" id="lastName"
|
||||||
|
data-ng-model="user.lastName">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<div class="form-actions" data-ng-show="create">
|
||||||
|
<button type="submit" data-ng-click="save()" class="primary">Save
|
||||||
|
</button>
|
||||||
|
<button type="submit" data-ng-click="cancel()" data-ng-click="cancel()"
|
||||||
|
data-ng-show="changed">Cancel
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="form-actions" data-ng-show="!create">
|
||||||
<label class="control-label">Enabled</label>
|
<button type="submit" data-ng-click="save()" class="primary" data-ng-show="changed">Save
|
||||||
|
changes
|
||||||
<div class="controls">
|
</button>
|
||||||
<input class="input-xlarge" type="checkbox" name="enabled"
|
<button type="submit" data-ng-click="reset()" data-ng-show="changed">Clear changes
|
||||||
data-ng-model="realm.enabled">
|
</button>
|
||||||
</div>
|
<button type="submit" data-ng-click="remove()" class="danger">
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
</form>
|
||||||
<label class="control-label" for="email">Email </label>
|
</div>
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<input type="email" class="input-xlarge" id="email" name="email" data-ng-model="user.email">
|
|
||||||
<span class="help-inline error"
|
|
||||||
data-ng-show="userForm.showErrors && userForm.email.$invalid">Invalid email</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="firstName">Firstname </label>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<input type="text" class="input-xlarge" id="firstName" data-ng-model="user.firstName">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="lastName">Lastname </label>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<input type="text" class="input-xlarge" id="lastName" data-ng-model="user.lastName">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset data-ng-show="user.attributes.length > 0">
|
|
||||||
<legend>Attributes</legend>
|
|
||||||
|
|
||||||
<table class="table table-striped table-bordered margin-top">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Value</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr data-ng-repeat="attribute in user.attributes">
|
|
||||||
<td><input type="text" placeholder="Name" value="{{attribute.name}}" readonly></td>
|
|
||||||
<td><input type="text" placeholder="Value" value="{{attribute.value}}" readonly></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<div class="form-actions" data-ng-show="create">
|
|
||||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
|
|
||||||
</button>
|
|
||||||
<button type="submit" data-ng-click="cancel()" class="btn" data-ng-click="cancel()"
|
|
||||||
data-ng-show="changed">Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-actions" data-ng-show="!create">
|
|
||||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
|
|
||||||
changes
|
|
||||||
</button>
|
|
||||||
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes
|
|
||||||
</button>
|
|
||||||
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="container-right-bg"></div>
|
<div id="container-right-bg"></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -1,60 +1,61 @@
|
||||||
<div id="wrapper" class="container">
|
<div id="wrapper" class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<aside class="span3" data-ng-include data-src="'partials/realm-menu.html'"></aside>
|
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
|
||||||
<div id="actions-bg"></div>
|
<div id="content-area" class="col-md-9" role="main">
|
||||||
|
<div class="top-nav" data-ng-hide="createRealm">
|
||||||
|
<ul class="rcue-tabs">
|
||||||
<div id="container-right" class="span9">
|
<li class="active"><a href="#">Users</a></li>
|
||||||
<form class="form-horizontal" name="queryForm" novalidate>
|
<li><a href="#/create/user/{{realm.id}}">New User</a></li>
|
||||||
<div class="control-group">
|
</ul>
|
||||||
<label class="control-label">Query </label>
|
</div>
|
||||||
|
<div id="content">
|
||||||
<div class="controls">
|
<h2 class="pull-left">Query Users</h2>
|
||||||
<input type="text" class="input-xlarge" id="query" name="query" data-ng-model="query"
|
<table>
|
||||||
autofocus required readonly>
|
<caption>Table of realm users</caption>
|
||||||
<button type="submit" data-ng-click="executeQuery()" class="btn btn-primary">Execute Query
|
<thead>
|
||||||
</button>
|
<tr>
|
||||||
</div>
|
<th class="rcue-table-actions" colspan="4">
|
||||||
</div>
|
<div class="search-comp clearfix">
|
||||||
</form>
|
<input type="text" placeholder="Search..." data-ng-model="search" class="search">
|
||||||
|
<button data-ng-click="searchQuery()"
|
||||||
<form class="form-horizontal" name="queryAttribute" novalidate>
|
class="icon-search tooltipRightTrigger"
|
||||||
<fieldset>
|
data-original-title="Search by full name, last name, email, or username.">
|
||||||
<div class="control-group">
|
Icon: search
|
||||||
<label class="control-label">Predefined Attribute</label>
|
</button>
|
||||||
|
</div>
|
||||||
<div class="controls">
|
</th>
|
||||||
<select style="width: auto;" name="name"
|
</tr>
|
||||||
data-ng-model="attribute.name">
|
<tr>
|
||||||
<option value="loginName">Login name</option>
|
<tr>
|
||||||
<option value="lastName">Last name</option>
|
<th>Username</th>
|
||||||
<option value="firstName">First name</option>
|
<th>Last Name</th>
|
||||||
<option value="email">Email</option>
|
<th>First Name</th>
|
||||||
</select>
|
<th>Email</th>
|
||||||
<input class="input-small" type="text" name="value"
|
</tr>
|
||||||
data-ng-model="attribute.value">
|
</tr>
|
||||||
<button type="submit" data-ng-click="addAttribute()" class="btn btn-primary">Add Attribute
|
</thead>
|
||||||
</button>
|
<tfoot>
|
||||||
</div>
|
<tr>
|
||||||
</div>
|
<td colspan="4">
|
||||||
</fieldset>
|
<div class="table-nav">
|
||||||
</form>
|
<a href="#" class="first disabled">First page</a><a href="#" class="prev disabled">Previous
|
||||||
<table class="table table-striped table-bordered">
|
page</a><span><strong>1-8</strong> of <strong>10</strong></span><a href="#"
|
||||||
<thead>
|
class="next">Next
|
||||||
<tr>
|
page</a><a href="#" class="last">Last page</a>
|
||||||
<th>Username</th>
|
</div>
|
||||||
<th>Firstname</th>
|
</td>
|
||||||
<th>Lastname</th>
|
</tr>
|
||||||
<th>Email</th>
|
</tfoot>
|
||||||
</tr>
|
<tbody class="selectable-rows">
|
||||||
</thead>
|
<tr ng-repeat="user in users">
|
||||||
<tr data-ng-repeat="user in users">
|
<td><a href="#/realms/{{realm.id}}/users/{{user.username}}">{{user.username}}</a></td>
|
||||||
<td><a href="#/realms/{{realm.id}}/users/{{user.username}}">{{user.username}}</a></td>
|
<td>{{user.lastName</td>
|
||||||
<td>{{user.firstName}}</td>
|
<td>{{user.firstName</td>
|
||||||
<td>{{user.lastName}}</td>
|
<td>{{user.email</td>
|
||||||
<td>{{user.email}}</td>
|
</tr>
|
||||||
</tr>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="container-right-bg"></div>
|
<div id="container-right-bg"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,10 +8,7 @@ import org.keycloak.services.models.UserModel.RequiredAction;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.KeyPairGenerator;
|
import java.security.KeyPairGenerator;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,6 +231,66 @@ public class RealmManager {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query users based on a search string:
|
||||||
|
*
|
||||||
|
* "Bill Burke" first and last name
|
||||||
|
* "bburke@redhat.com" email
|
||||||
|
* "Burke" lastname or username
|
||||||
|
*
|
||||||
|
* @param searchString
|
||||||
|
* @param realmModel
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<UserModel> searchUsers(String searchString, RealmModel realmModel) {
|
||||||
|
if (searchString == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
String search = searchString.trim();
|
||||||
|
if (search.contains(" ")) { //first and last name
|
||||||
|
String[] split = search.split(" ");
|
||||||
|
if (split.length != 2) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
Map<String, String> attributes = new HashMap<String, String>();
|
||||||
|
attributes.put(UserModel.FIRST_NAME, split[0]);
|
||||||
|
attributes.put(UserModel.LAST_NAME, split[1]);
|
||||||
|
return realmModel.searchForUserByAttributes(attributes);
|
||||||
|
} else if (search.contains("@")) { // email
|
||||||
|
Map<String, String> attributes = new HashMap<String, String>();
|
||||||
|
attributes.put(UserModel.EMAIL, search);
|
||||||
|
return realmModel.searchForUserByAttributes(attributes);
|
||||||
|
} else { // username and lastname
|
||||||
|
Map<String, String> attributes = new HashMap<String, String>();
|
||||||
|
attributes.put(UserModel.LOGIN_NAME, search);
|
||||||
|
List<UserModel> usernameQuery = realmModel.searchForUserByAttributes(attributes);
|
||||||
|
attributes.clear();
|
||||||
|
attributes.put(UserModel.LAST_NAME, search);
|
||||||
|
List<UserModel> lastnameQuery = realmModel.searchForUserByAttributes(attributes);
|
||||||
|
if (usernameQuery.size() == 0) {
|
||||||
|
return lastnameQuery;
|
||||||
|
} else if (lastnameQuery.size() == 0) {
|
||||||
|
return usernameQuery;
|
||||||
|
}
|
||||||
|
List<UserModel> results = new ArrayList<UserModel>();
|
||||||
|
results.addAll(usernameQuery);
|
||||||
|
for (UserModel lastnameUser : lastnameQuery) {
|
||||||
|
boolean found = false;
|
||||||
|
for (UserModel usernameUser : usernameQuery) {
|
||||||
|
if (usernameUser.getLoginName().equals(lastnameUser.getLoginName())) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
results.add(lastnameUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addRequiredCredential(RealmModel newRealm, String requiredCred) {
|
public void addRequiredCredential(RealmModel newRealm, String requiredCred) {
|
||||||
newRealm.addRequiredCredential(requiredCred);
|
newRealm.addRequiredCredential(requiredCred);
|
||||||
}
|
}
|
||||||
|
@ -254,6 +311,18 @@ public class RealmManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UserRepresentation toRepresentation(UserModel user) {
|
||||||
|
UserRepresentation rep = new UserRepresentation();
|
||||||
|
rep.setUsername(user.getLoginName());
|
||||||
|
rep.setLastName(user.getLastName());
|
||||||
|
rep.setFirstName(user.getFirstName());
|
||||||
|
rep.setEmail(user.getEmail());
|
||||||
|
Map<String, String> attrs = new HashMap<String, String>();
|
||||||
|
attrs.putAll(user.getAttributes());
|
||||||
|
rep.setAttributes(attrs);
|
||||||
|
return rep;
|
||||||
|
}
|
||||||
|
|
||||||
public RoleRepresentation toRepresentation(RoleModel role) {
|
public RoleRepresentation toRepresentation(RoleModel role) {
|
||||||
RoleRepresentation rep = new RoleRepresentation();
|
RoleRepresentation rep = new RoleRepresentation();
|
||||||
rep.setId(role.getId());
|
rep.setId(role.getId());
|
||||||
|
|
|
@ -150,4 +150,6 @@ public interface RealmModel {
|
||||||
public boolean isAutomaticRegistrationAfterSocialLogin();
|
public boolean isAutomaticRegistrationAfterSocialLogin();
|
||||||
|
|
||||||
public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin);
|
public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin);
|
||||||
|
|
||||||
|
List<UserModel> searchForUserByAttributes(Map<String, String> attributes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,11 @@ import java.util.Map;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public interface UserModel {
|
public interface UserModel {
|
||||||
|
public static final String LOGIN_NAME = "username";
|
||||||
|
public static final String LAST_NAME = "lastName";
|
||||||
|
public static final String FIRST_NAME = "firstName";
|
||||||
|
public static final String EMAIL = "email";
|
||||||
|
|
||||||
String getLoginName();
|
String getLoginName();
|
||||||
|
|
||||||
boolean isEnabled();
|
boolean isEnabled();
|
||||||
|
|
|
@ -777,4 +777,28 @@ public class RealmAdapter implements RealmModel {
|
||||||
|
|
||||||
getRelationshipManager().remove(relationship);
|
getRelationshipManager().remove(relationship);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
|
||||||
|
IdentityQuery<User> query = getIdm().createIdentityQuery(User.class);
|
||||||
|
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
||||||
|
if (entry.getKey().equals(UserModel.LOGIN_NAME)) {
|
||||||
|
query.setParameter(User.LOGIN_NAME, entry.getValue());
|
||||||
|
} else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) {
|
||||||
|
query.setParameter(User.FIRST_NAME, entry.getValue());
|
||||||
|
|
||||||
|
} else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) {
|
||||||
|
query.setParameter(User.LAST_NAME, entry.getValue());
|
||||||
|
|
||||||
|
} else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) {
|
||||||
|
query.setParameter(User.EMAIL, entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<User> users = query.getResultList();
|
||||||
|
List<UserModel> userModels = new ArrayList<UserModel>();
|
||||||
|
for (User user : users) {
|
||||||
|
userModels.add(new UserAdapter(user, idm));
|
||||||
|
}
|
||||||
|
return userModels;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,9 @@ import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -117,16 +119,94 @@ public class RealmAdminResource {
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getId()).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getId()).build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Path("users/{username}")
|
||||||
|
@PUT
|
||||||
|
@Consumes("application/json")
|
||||||
|
public void updateUser(final @PathParam("username") String username, final UserRepresentation rep) {
|
||||||
|
UserModel user = realm.getUser(username);
|
||||||
|
if (user == null) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
user.setEmail(rep.getEmail());
|
||||||
|
user.setFirstName(rep.getFirstName());
|
||||||
|
user.setLastName(rep.getLastName());
|
||||||
|
for (Map.Entry<String, String> attr : rep.getAttributes().entrySet()) {
|
||||||
|
user.setAttribute(attr.getKey(), attr.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Path("users")
|
||||||
|
@POST
|
||||||
|
@Consumes("application/json")
|
||||||
|
public Response createUser(final @Context UriInfo uriInfo, final UserRepresentation rep) {
|
||||||
|
if (realm.getUser(rep.getUsername()) != null) {
|
||||||
|
throw new InternalServerErrorException(); // todo appropriate status here.
|
||||||
|
}
|
||||||
|
UserModel user = realm.addUser(rep.getUsername());
|
||||||
|
if (user == null) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
user.setEmail(rep.getEmail());
|
||||||
|
user.setFirstName(rep.getFirstName());
|
||||||
|
user.setLastName(rep.getLastName());
|
||||||
|
if (rep.getAttributes() != null) {
|
||||||
|
for (Map.Entry<String, String> attr : rep.getAttributes().entrySet()) {
|
||||||
|
user.setAttribute(attr.getKey(), attr.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(user.getLoginName()).build()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Path("users/{username}")
|
||||||
|
@GET
|
||||||
|
@NoCache
|
||||||
|
@Produces("application/json")
|
||||||
|
public UserRepresentation getUser(final @PathParam("username") String username) {
|
||||||
|
UserModel user = realm.getUser(username);
|
||||||
|
if (user == null) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
return new RealmManager(session).toRepresentation(user);
|
||||||
|
}
|
||||||
|
|
||||||
@Path("users")
|
@Path("users")
|
||||||
@GET
|
@GET
|
||||||
@NoCache
|
@NoCache
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public List<UserRepresentation> getUsers() {
|
public List<UserRepresentation> getUsers(@QueryParam("search") String search,
|
||||||
return null;
|
@QueryParam("lastName") String last,
|
||||||
|
@QueryParam("firstName") String first,
|
||||||
|
@QueryParam("email") String email,
|
||||||
|
@QueryParam("username") String username) {
|
||||||
|
RealmManager manager = new RealmManager(session);
|
||||||
|
List<UserRepresentation> results = new ArrayList<UserRepresentation>();
|
||||||
|
if (search != null) {
|
||||||
|
List<UserModel> userModels = manager.searchUsers(search, realm);
|
||||||
|
for (UserModel user : userModels) {
|
||||||
|
results.add(manager.toRepresentation(user));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Map<String, String> attributes = new HashMap<String, String>();
|
||||||
|
if (last != null) {
|
||||||
|
attributes.put(UserModel.LAST_NAME, last);
|
||||||
|
}
|
||||||
|
if (first != null) {
|
||||||
|
attributes.put(UserModel.FIRST_NAME, first);
|
||||||
|
}
|
||||||
|
if (email != null) {
|
||||||
|
attributes.put(UserModel.EMAIL, email);
|
||||||
|
}
|
||||||
|
if (username != null) {
|
||||||
|
attributes.put(UserModel.LOGIN_NAME, username);
|
||||||
|
}
|
||||||
|
List<UserModel> userModels = realm.searchForUserByAttributes(attributes);
|
||||||
|
for (UserModel user : userModels) {
|
||||||
|
results.add(manager.toRepresentation(user));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,8 +115,7 @@ public class AdapterTest {
|
||||||
if (cred.getType().equals(CredentialRepresentation.PASSWORD)) {
|
if (cred.getType().equals(CredentialRepresentation.PASSWORD)) {
|
||||||
password = true;
|
password = true;
|
||||||
Assert.assertTrue(cred.isSecret());
|
Assert.assertTrue(cred.isSecret());
|
||||||
}
|
} else if (cred.getType().equals(CredentialRepresentation.TOTP)) {
|
||||||
else if (cred.getType().equals(CredentialRepresentation.TOTP)) {
|
|
||||||
totp = true;
|
totp = true;
|
||||||
Assert.assertFalse(cred.isSecret());
|
Assert.assertFalse(cred.isSecret());
|
||||||
}
|
}
|
||||||
|
@ -136,6 +135,118 @@ public class AdapterTest {
|
||||||
Assert.assertTrue(realmModel.validatePassword(user, "geheim"));
|
Assert.assertTrue(realmModel.validatePassword(user, "geheim"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserSearch() throws Exception {
|
||||||
|
test1CreateRealm();
|
||||||
|
{
|
||||||
|
UserModel user = realmModel.addUser("bburke");
|
||||||
|
user.setLastName("Burke");
|
||||||
|
user.setFirstName("Bill");
|
||||||
|
user.setEmail("bburke@redhat.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
List<UserModel> userModels = adapter.searchUsers("total junk query", realmModel);
|
||||||
|
Assert.assertEquals(userModels.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
List<UserModel> userModels = adapter.searchUsers("Bill Burke", realmModel);
|
||||||
|
Assert.assertEquals(userModels.size(), 1);
|
||||||
|
UserModel bburke = userModels.get(0);
|
||||||
|
Assert.assertEquals(bburke.getFirstName(), "Bill");
|
||||||
|
Assert.assertEquals(bburke.getLastName(), "Burke");
|
||||||
|
Assert.assertEquals(bburke.getEmail(), "bburke@redhat.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
List<UserModel> userModels = adapter.searchUsers("bburke@redhat.com", realmModel);
|
||||||
|
Assert.assertEquals(userModels.size(), 1);
|
||||||
|
UserModel bburke = userModels.get(0);
|
||||||
|
Assert.assertEquals(bburke.getFirstName(), "Bill");
|
||||||
|
Assert.assertEquals(bburke.getLastName(), "Burke");
|
||||||
|
Assert.assertEquals(bburke.getEmail(), "bburke@redhat.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
List<UserModel> userModels = adapter.searchUsers("bburke", realmModel);
|
||||||
|
Assert.assertEquals(userModels.size(), 1);
|
||||||
|
UserModel bburke = userModels.get(0);
|
||||||
|
Assert.assertEquals(bburke.getFirstName(), "Bill");
|
||||||
|
Assert.assertEquals(bburke.getLastName(), "Burke");
|
||||||
|
Assert.assertEquals(bburke.getEmail(), "bburke@redhat.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
List<UserModel> userModels = adapter.searchUsers("Burke", realmModel);
|
||||||
|
Assert.assertEquals(userModels.size(), 1);
|
||||||
|
UserModel bburke = userModels.get(0);
|
||||||
|
Assert.assertEquals(bburke.getFirstName(), "Bill");
|
||||||
|
Assert.assertEquals(bburke.getLastName(), "Burke");
|
||||||
|
Assert.assertEquals(bburke.getEmail(), "bburke@redhat.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
UserModel user = realmModel.addUser("mburke");
|
||||||
|
user.setLastName("Burke");
|
||||||
|
user.setFirstName("Monica");
|
||||||
|
user.setEmail("mburke@redhat.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
UserModel user = realmModel.addUser("thor");
|
||||||
|
user.setLastName("Thorgersen");
|
||||||
|
user.setFirstName("Stian");
|
||||||
|
user.setEmail("thor@redhat.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
List<UserModel> userModels = adapter.searchUsers("Monica Burke", realmModel);
|
||||||
|
Assert.assertEquals(userModels.size(), 1);
|
||||||
|
UserModel bburke = userModels.get(0);
|
||||||
|
Assert.assertEquals(bburke.getFirstName(), "Monica");
|
||||||
|
Assert.assertEquals(bburke.getLastName(), "Burke");
|
||||||
|
Assert.assertEquals(bburke.getEmail(), "mburke@redhat.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
List<UserModel> userModels = adapter.searchUsers("mburke@redhat.com", realmModel);
|
||||||
|
Assert.assertEquals(userModels.size(), 1);
|
||||||
|
UserModel bburke = userModels.get(0);
|
||||||
|
Assert.assertEquals(bburke.getFirstName(), "Monica");
|
||||||
|
Assert.assertEquals(bburke.getLastName(), "Burke");
|
||||||
|
Assert.assertEquals(bburke.getEmail(), "mburke@redhat.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
List<UserModel> userModels = adapter.searchUsers("mburke", realmModel);
|
||||||
|
Assert.assertEquals(userModels.size(), 1);
|
||||||
|
UserModel bburke = userModels.get(0);
|
||||||
|
Assert.assertEquals(bburke.getFirstName(), "Monica");
|
||||||
|
Assert.assertEquals(bburke.getLastName(), "Burke");
|
||||||
|
Assert.assertEquals(bburke.getEmail(), "mburke@redhat.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
List<UserModel> userModels = adapter.searchUsers("Burke", realmModel);
|
||||||
|
Assert.assertEquals(userModels.size(), 2);
|
||||||
|
UserModel first = userModels.get(0);
|
||||||
|
UserModel second = userModels.get(1);
|
||||||
|
if (!first.getEmail().equals("bburke@redhat.com") && !second.getEmail().equals("bburke@redhat.com")) {
|
||||||
|
Assert.fail();
|
||||||
|
}
|
||||||
|
if (!first.getEmail().equals("mburke@redhat.com") && !second.getEmail().equals("mburke@redhat.com")) {
|
||||||
|
Assert.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRoles() throws Exception {
|
public void testRoles() throws Exception {
|
||||||
test1CreateRealm();
|
test1CreateRealm();
|
||||||
|
|
Loading…
Reference in a new issue