group membership ui
This commit is contained in:
parent
0d20e3c7ff
commit
d7ea66ad44
5 changed files with 158 additions and 1 deletions
|
@ -646,6 +646,18 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||||
},
|
},
|
||||||
controller : 'GroupDetailCtrl'
|
controller : 'GroupDetailCtrl'
|
||||||
})
|
})
|
||||||
|
.when('/realms/:realm/groups/:group/members', {
|
||||||
|
templateUrl : resourceUrl + '/partials/group-members.html',
|
||||||
|
resolve : {
|
||||||
|
realm : function(RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
},
|
||||||
|
group : function(GroupLoader) {
|
||||||
|
return GroupLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller : 'GroupMembersCtrl'
|
||||||
|
})
|
||||||
.when('/realms/:realm/groups/:group/role-mappings', {
|
.when('/realms/:realm/groups/:group/role-mappings', {
|
||||||
templateUrl : resourceUrl + '/partials/group-role-mappings.html',
|
templateUrl : resourceUrl + '/partials/group-role-mappings.html',
|
||||||
resolve : {
|
resolve : {
|
||||||
|
|
|
@ -319,3 +319,50 @@ module.controller('GroupRoleMappingCtrl', function($scope, $http, realm, group,
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.controller('GroupMembersCtrl', function($scope, realm, group, GroupMembership) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
$scope.page = 0;
|
||||||
|
|
||||||
|
|
||||||
|
$scope.query = {
|
||||||
|
realm: realm.realm,
|
||||||
|
groupId: group.id,
|
||||||
|
max : 5,
|
||||||
|
first : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$scope.firstPage = function() {
|
||||||
|
$scope.query.first = 0;
|
||||||
|
$scope.searchQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.previousPage = function() {
|
||||||
|
$scope.query.first -= parseInt($scope.query.max);
|
||||||
|
if ($scope.query.first < 0) {
|
||||||
|
$scope.query.first = 0;
|
||||||
|
}
|
||||||
|
$scope.searchQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.nextPage = function() {
|
||||||
|
$scope.query.first += parseInt($scope.query.max);
|
||||||
|
$scope.searchQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.searchQuery = function() {
|
||||||
|
console.log("query.search: " + $scope.query.search);
|
||||||
|
$scope.searchLoaded = false;
|
||||||
|
|
||||||
|
$scope.users = GroupMembership.query($scope.query, function() {
|
||||||
|
console.log('search loaded');
|
||||||
|
$scope.searchLoaded = true;
|
||||||
|
$scope.lastSearch = $scope.query.search;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.searchQuery();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -1512,6 +1512,14 @@ module.factory('GroupCompositeClientRoleMapping', function($resource) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.factory('GroupMembership', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/groups/:groupId/members', {
|
||||||
|
realm : '@realm',
|
||||||
|
groupId : '@groupId'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
module.factory('UserGroupMembership', function($resource) {
|
module.factory('UserGroupMembership', function($resource) {
|
||||||
return $resource(authUrl + '/admin/realms/:realm/users/:userId/groups', {
|
return $resource(authUrl + '/admin/realms/:realm/users/:userId/groups', {
|
||||||
realm : '@realm',
|
realm : '@realm',
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><a href="#/realms/{{realm.realm}}/groups">Groups</a></li>
|
||||||
|
<li>{{group.name}}</li>
|
||||||
|
</ol>
|
||||||
|
<kc-tabs-group></kc-tabs-group>
|
||||||
|
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<caption data-ng-show="users" class="hidden">Table of group members</caption>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<tr data-ng-show="searchLoaded && users.length > 0">
|
||||||
|
<th>Username</th>
|
||||||
|
<th>Last Name</th>
|
||||||
|
<th>First Name</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tfoot data-ng-show="users && (users.length >= query.max || query.first > 0)">
|
||||||
|
<tr>
|
||||||
|
<td colspan="7">
|
||||||
|
<div class="table-nav">
|
||||||
|
<button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">First page</button>
|
||||||
|
<button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">Previous page</button>
|
||||||
|
<button data-ng-click="nextPage()" class="next" ng-disabled="users.length < query.max">Next page</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="user in users">
|
||||||
|
<td><a href="#/realms/{{realm.realm}}/users/{{user.id}}">{{user.username}}</a></td>
|
||||||
|
<td>{{user.lastName}}</td>
|
||||||
|
<td>{{user.firstName}}</td>
|
||||||
|
<td>{{user.email}}</td>
|
||||||
|
<td class="kc-action-cell">
|
||||||
|
<button class="btn btn-default btn-block btn-sm" kc-open="/realms/{{realm.realm}}/users/{{user.id}}">Edit</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr data-ng-show="!users || users.length == 0">
|
||||||
|
<td class="text-muted" data-ng-show="searchLoaded && users.length == 0 && lastSearch != null">No group members</td>
|
||||||
|
<td class="text-muted" data-ng-show="searchLoaded && users.length == 0 && lastSearch == null">No group members</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<kc-menu></kc-menu>
|
|
@ -10,6 +10,7 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.ModelToRepresentation;
|
import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
import org.keycloak.representations.idm.GroupRepresentation;
|
import org.keycloak.representations.idm.GroupRepresentation;
|
||||||
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
|
@ -19,12 +20,15 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -256,6 +260,42 @@ public class GroupResource {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get users
|
||||||
|
*
|
||||||
|
* Returns a list of users, filtered according to query parameters
|
||||||
|
*
|
||||||
|
* @param firstResult Pagination offset
|
||||||
|
* @param maxResults Pagination size
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@NoCache
|
||||||
|
@Path("{id}/members")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public List<UserRepresentation> getMembers(@PathParam("id") String id,
|
||||||
|
@QueryParam("first") Integer firstResult,
|
||||||
|
@QueryParam("max") Integer maxResults) {
|
||||||
|
auth.requireView();
|
||||||
|
|
||||||
|
GroupModel group = session.realms().getGroupById(id, realm);
|
||||||
|
if (group == null) {
|
||||||
|
throw new NotFoundException("Group not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
firstResult = firstResult != null ? firstResult : -1;
|
||||||
|
maxResults = maxResults != null ? maxResults : -1;
|
||||||
|
|
||||||
|
List<UserRepresentation> results = new ArrayList<UserRepresentation>();
|
||||||
|
List<UserModel> userModels = session.users().getGroupMembers(realm, group, firstResult, maxResults);
|
||||||
|
|
||||||
|
for (UserModel user : userModels) {
|
||||||
|
results.add(ModelToRepresentation.toRepresentation(user));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue