Commit 7c5f5d5c authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Bugfix on permission removal; various small improvements

parent a4fb3285
......@@ -39,10 +39,7 @@ export default {
this.$store.commit('openGroup', result.id);
break;
case 'USER':
client.openUserSearchResult(result.id)
.then(model => {
this.$store.commit('displayUserSearchResults', [result.label, model]);
});
this.$store.dispatch('openUserPage', result.id);
break;
}
},
......
......@@ -54,6 +54,8 @@ export default {
}),
methods: {
tabChanged: function(tabIndex) {
// reset paginator
this.input.paginatorPage = 1;
switch (tabIndex) {
case 0:
client.fetchGroupsTab(this.input)
......
......@@ -2,9 +2,9 @@
<b-tab title="Members" v-if="model.permission === 'ADMIN' || model.permission === 'MANAGE_MEMBERS' || model.permission === 'VIEW_MEMBERS'">
<div v-if="model.membersPanel !== null">
<b-list-group v-for="member in model.membersPanel.items" id="members-list">
<b-list-group-item href="#">
<b-list-group-item href="#" @click="openUser(member)">
<div class="float-left">
<User v-bind:user="member" />
<User :user="member" :anchor="false" />
</div>
<span v-if="model.permission === 'ADMIN' || model.permission === 'MANAGE_MEMBERS'" class="float-right">
<a href="#" v-on:click.stop="openRemoveMemberModal(member)" class="text-danger" title="Remove member">
......@@ -52,6 +52,9 @@ export default {
.then(panel => {
this.$store.commit('updateMembersPanel', panel);
});
},
openUser(member) {
this.$store.dispatch('openUserPage', member.id);
}
}
}
......
......@@ -12,7 +12,7 @@
<tbody>
<tr v-for="up in model.permissionsPanel.items">
<td>
<User v-bind:user="up.user" />
<User :user="up.user" :anchor="true" />
</td>
<td>{{up.permission}}</td>
<td>
......
<template>
<div :id="'user-name-' + user.id">
<span>{{user.displayName}}</span>
<component :is="anchor ? 'a' : 'span'" :href="anchor ? '#' : false" @click="openUser">{{user.displayName}}</component>
<b-tooltip ref="user-tooltip" :target="'user-name-' + user.id" placement="bottom">
<div class="text-left">
<p><strong>User id</strong>: {{user.id}}</p>
<p><strong>Identities</strong>:</p>
<ul>
<li v-for="identity in user.identities">
<li v-for="identity in user.identities" v-bind:key="identity.typedId">
{{identity.email}} ({{identity.type}})
</li>
</ul>
......@@ -19,7 +19,13 @@
export default {
name: 'User',
props: {
user: Object
user: Object,
anchor: Boolean
},
methods: {
openUser() {
this.$store.dispatch('openUserPage', this.user.id);
}
}
}
</script>
<template>
<div class="mt-sm-3" v-if="userLabel !== null">
<div class="mt-sm-3" v-if="user !== null">
<b-button variant="primary" class="float-right" v-on:click="back()">Back</b-button>
<h5>Results for <strong>{{userLabel}}</strong>:</h5>
<h5><strong>{{user.displayName}}</strong>:</h5>
<b-container class="mt-sm-5">
<b-row>
</b-row>
<b-row>
<b-col class="text-left">
<h5>Is member of</h5>
......@@ -19,6 +22,24 @@
</li>
</ul>
</div>
<h5 class="mt-5 mb-3">User info</h5>
<p><strong>User id</strong>: {{user.id}}</p>
<p><strong>Identities ({{user.identities.length}})</strong>:</p>
<b-row>
<b-col lg="10">
<b-list-group>
<b-list-group-item v-for="identity in user.identities" v-bind:key="identity.typedId">
<dl class="mb-0 ml-0 row">
<dt class="col-3">Type</dt><dd class="col-9">{{identity.type}}</dd>
<dt class="col-3">Email</dt><dd class="col-9">{{identity.email}}</dd>
<dt class="col-3" v-if="identity.type === 'eduGAIN'"><abbr title="EduPerson Principal Name, an unique identifier used into federations.">EPPN</abbr></dt>
<dd class="col-9" v-if="identity.type === 'eduGAIN'">{{identity.typedId}}</dd>
</dl>
</b-list-group-item>
</b-list-group>
</b-col>
</b-row>
</b-col>
<b-col v-if="permissions.length > 0">
<h5>Permissions</h5>
......@@ -55,13 +76,13 @@ import {
export default {
name: 'UserSearchResult',
computed: mapState({
userLabel: state => state.model.userSearchResults.userLabel,
user: state => state.model.userSearchResults.user,
groups: state => state.model.userSearchResults.groups,
permissions: state => state.model.userSearchResults.permissions
}),
methods: {
back() {
this.$store.commit('displaySearchResults');
this.$store.commit('backFromUserPage');
},
openGroup(groupId) {
this.$store.commit('openGroup', groupId);
......
......@@ -38,6 +38,7 @@ export default new Vuex.Store({
}
},
loading: false,
previousPage: null,
page: 'main'
},
mutations: {
......@@ -100,11 +101,20 @@ export default new Vuex.Store({
updateSearchResults(state, results) {
this.state.model.genericSearchResults = results;
},
displayUserSearchResults(state, data) {
this.state.page = 'userSearch';
this.state.model.userSearchResults.userLabel = data[0];
this.state.model.userSearchResults.groups = data[1].groups;
this.state.model.userSearchResults.permissions = data[1].permissions;
backFromUserPage(state) {
state.page = state.previousPage;
}
},
actions: {
openUserPage({ state }, userId) {
state.previousPage = state.page;
client.openUserSearchResult(userId)
.then(model => {
state.page = 'userSearch';
state.model.userSearchResults.user = model.user;
state.model.userSearchResults.groups = model.groups;
state.model.userSearchResults.permissions = model.permissions;
});
}
},
getters: {
......
package it.inaf.ia2.gms.controller;
import it.inaf.ia2.gms.authn.SessionData;
import it.inaf.ia2.gms.manager.MembershipManager;
import it.inaf.ia2.gms.manager.PermissionsManager;
import it.inaf.ia2.gms.model.request.AddMemberRequest;
import it.inaf.ia2.gms.model.request.MemberRequest;
import it.inaf.ia2.gms.model.response.PaginatedData;
import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.model.RapUser;
import it.inaf.ia2.gms.model.request.PaginatedModelRequest;
import it.inaf.ia2.gms.model.request.RemoveMemberRequest;
import it.inaf.ia2.gms.model.request.TabRequest;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.service.GroupsService;
import java.util.Collections;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -36,18 +36,17 @@ public class MembersController {
@Autowired
private PermissionsManager permissionsManager;
@GetMapping(value = "/members", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@GetMapping(value = "/members", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<RapUser>> getMembersTab(TabRequest request) {
GroupEntity group = groupsService.getGroupById(request.getGroupId());
List<RapUser> members = membershipManager.getMembers(group);
PaginatedData<RapUser> membersPanel = new PaginatedData<>(members, request.getPaginatorPage(), request.getPaginatorPageSize());
PaginatedData<RapUser> membersPanel = getMembersPanel(group, request);
return ResponseEntity.ok(membersPanel);
}
@PostMapping(value = "/member", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@PostMapping(value = "/member", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<RapUser>> addMember(@Valid @RequestBody AddMemberRequest request) {
GroupEntity group = groupsService.getGroupById(request.getGroupId());
......@@ -64,10 +63,10 @@ public class MembersController {
permissionsManager.addPermission(group, request.getUserId(), request.getPermission());
}
return new ResponseEntity<>(getMembersPanel(request, group), HttpStatus.CREATED);
return new ResponseEntity<>(getMembersPanel(group, request), HttpStatus.CREATED);
}
@DeleteMapping(value = "/member", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@DeleteMapping(value = "/member", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<RapUser>> removeMember(@Valid RemoveMemberRequest request) {
GroupEntity group = groupsService.getGroupById(request.getGroupId());
......@@ -91,11 +90,14 @@ public class MembersController {
permissionsManager.removePermission(group, request.getUserId());
}
return ResponseEntity.ok(getMembersPanel(request, group));
return ResponseEntity.ok(getMembersPanel(group, request));
}
private PaginatedData<RapUser> getMembersPanel(MemberRequest request, GroupEntity group) {
private PaginatedData<RapUser> getMembersPanel(GroupEntity group, PaginatedModelRequest request) {
List<RapUser> members = membershipManager.getMembers(group);
Collections.sort(members, (m1, m2) -> {
return m1.getDisplayName().compareTo(m2.getDisplayName());
});
return new PaginatedData<>(members, request.getPaginatorPage(), request.getPaginatorPageSize());
}
}
......@@ -10,6 +10,7 @@ import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.model.UserPermission;
import it.inaf.ia2.gms.model.request.TabRequest;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -38,8 +39,7 @@ public class PermissionsController {
public ResponseEntity<PaginatedData<UserPermission>> getPermissionsTab(TabRequest request) {
GroupEntity group = groupsManager.getGroupById(request.getGroupId());
List<UserPermission> permissions = permissionsManager.getAllPermissions(group);
PaginatedData<UserPermission> permissionsPanel = new PaginatedData<>(permissions, request.getPaginatorPage(), request.getPaginatorPageSize());
PaginatedData<UserPermission> permissionsPanel = getPermissionsPanel(group, request);
return ResponseEntity.ok(permissionsPanel);
}
......@@ -79,6 +79,9 @@ public class PermissionsController {
private PaginatedData<UserPermission> getPermissionsPanel(GroupEntity group, PaginatedModelRequest request) {
List<UserPermission> permissions = permissionsManager.getAllPermissions(group);
Collections.sort(permissions, (p1, p2) -> {
return p1.getUser().getDisplayName().compareTo(p2.getUser().getDisplayName());
});
return new PaginatedData<>(permissions, request.getPaginatorPage(), request.getPaginatorPageSize());
}
}
package it.inaf.ia2.gms.controller;
import it.inaf.ia2.gms.authn.SessionData;
import it.inaf.ia2.gms.model.RapUser;
import it.inaf.ia2.gms.model.response.PaginatedData;
import it.inaf.ia2.gms.model.response.SearchResponseItem;
import it.inaf.ia2.gms.model.response.UserSearchResponse;
......@@ -22,7 +23,7 @@ public class SearchController {
@Autowired
private SearchService searchService;
@GetMapping(value = "/search", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@GetMapping(value = "/search", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedData<SearchResponseItem>> getSearchResults(@RequestParam("query") String query,
@RequestParam("page") int page, @RequestParam("pageSize") int pageSize) {
......@@ -30,7 +31,7 @@ public class SearchController {
return ResponseEntity.ok(response);
}
@GetMapping(value = "/search/user/{userId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@GetMapping(value = "/search/user/{userId}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<UserSearchResponse> getSearchResultUser(@PathVariable("userId") String userId) {
UserSearchResponse response = searchService.getUserSearchResult(sessionData.getUserId(), userId);
......
......@@ -16,7 +16,7 @@ public class UsersController {
@Autowired
private RapClient rapClient;
@GetMapping(value = "users", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@GetMapping(value = "users", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<RapUser>> searchUsers(@RequestParam("search") String searchText) {
return ResponseEntity.ok(rapClient.searchUsers(searchText));
}
......
......@@ -63,7 +63,7 @@ public class PermissionsManager extends UserAwareComponent {
public Permission getDirectUserPermission(GroupEntity group, String userId) {
verifyUserCanManagePermissions(group);
List<PermissionEntity> permissions = permissionsService.findUserPermissions(group, getCurrentUserId());
List<PermissionEntity> permissions = permissionsService.findUserPermissions(group, userId);
for (PermissionEntity permission : permissions) {
if (permission.getGroupId().equals(group.getId())) {
return permission.getPermission();
......@@ -74,7 +74,7 @@ public class PermissionsManager extends UserAwareComponent {
public Permission getUserPermission(GroupEntity group, String userId) {
verifyUserCanManagePermissions(group);
List<PermissionEntity> permissions = permissionsService.findUserPermissions(group, getCurrentUserId());
List<PermissionEntity> permissions = permissionsService.findUserPermissions(group, userId);
return PermissionUtils.getGroupPermission(group, permissions).orElse(null);
}
......
package it.inaf.ia2.gms.model.response;
import it.inaf.ia2.gms.model.RapUser;
import java.util.List;
public class UserSearchResponse {
private RapUser user;
private List<UserGroup> groups;
private List<UserPermission> permissions;
public RapUser getUser() {
return user;
}
public void setUser(RapUser user) {
this.user = user;
}
public List<UserGroup> getGroups() {
return groups;
}
......
......@@ -57,6 +57,16 @@ public class RapClient {
this.refreshTokenRestTemplate = new RestTemplate();
}
public RapUser getUser(String userId) {
String url = rapBaseUrl + "/user/" + userId;
return httpCall(entity -> {
return rapRestTemplate.exchange(url, HttpMethod.GET, entity, new ParameterizedTypeReference<RapUser>() {
}).getBody();
});
}
public List<RapUser> getUsers(Set<String> identifiers) {
if (identifiers.isEmpty()) {
......
......@@ -119,6 +119,8 @@ public class SearchService {
sortByGroupCompleteName(permissions);
response.setPermissions(permissions);
response.setUser(rapClient.getUser(targetUserId));
return response;
}
......
......@@ -16,7 +16,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.ArgumentMatchers.any;
......@@ -141,17 +140,15 @@ public class JWTWebServiceControllerTest {
}
@Test
@Ignore
public void testDeleteGroupByPath() throws Exception {
List<String> names = Arrays.asList("LBT", "INAF");
when(groupsService.findGroupByNames(names)).thenReturn(Optional.of(inaf));
when(groupsDAO.findGroupByParentAndName("", "LBT")).thenReturn(Optional.of(lbt));
when(groupsDAO.findGroupByParentAndName("lbt_id", "INAF")).thenReturn(Optional.of(inaf));
mockMvc.perform(delete("/ws/jwt/group/LBT.INAF"))
mockMvc.perform(delete("/ws/jwt/LBT.INAF"))
.andExpect(status().isNoContent());
verify(groupsService, times(1)).deleteGroup(eq(inaf));
verify(groupsDAO, times(1)).deleteGroupById(eq(inaf.getId()));
}
@Test
......@@ -176,19 +173,17 @@ public class JWTWebServiceControllerTest {
}
@Test
@Ignore
public void testRemoveMember() throws Exception {
List<String> names = Arrays.asList("LBT", "INAF");
GroupEntity inaf = getInafGroup();
when(groupsService.findGroupByNames(names)).thenReturn(Optional.of(inaf));
mockMvc.perform(delete("/ws/jwt/membership/LBT.INAF?userId=user_id"))
when(groupsDAO.findGroupByParentAndName("", "LBT")).thenReturn(Optional.of(lbt));
when(groupsDAO.findGroupByParentAndName("lbt_id", "INAF")).thenReturn(Optional.of(inaf));
mockMvc.perform(delete("/ws/jwt/membership/LBT.INAF?user_id=userId"))
.andExpect(status().isNoContent());
verify(membershipManager, times(1)).removeMember(eq(inaf), eq("user_id"));
verify(membershipManager, times(1)).removeMember(eq(inaf), eq("userId"));
}
@Test
......@@ -220,17 +215,18 @@ public class JWTWebServiceControllerTest {
}
@Test
@Ignore
public void testRemovePermission() throws Exception {
List<String> names = Arrays.asList("LBT", "INAF");
GroupEntity inaf = getInafGroup();
when(groupsService.findGroupByNames(names)).thenReturn(Optional.of(inaf));
//when(groupsService.findGroupByNames(names)).thenReturn(Optional.of(inaf));
when(groupsDAO.findGroupByParentAndName("", "LBT")).thenReturn(Optional.of(lbt));
when(groupsDAO.findGroupByParentAndName("lbt_id", "INAF")).thenReturn(Optional.of(inaf));
mockMvc.perform(delete("/ws/jwt/permission?LBT.INAF?userId=user_id&permission=ADMIN"))
mockMvc.perform(delete("/ws/jwt/permission/LBT.INAF?user_id=userId&permission=ADMIN"))
.andExpect(status().isNoContent());
verify(permissionsManager, times(1)).removePermission(eq(inaf), eq("user_id"));
verify(permissionsManager, times(1)).removePermission(eq(inaf), eq("userId"));
}
private GroupEntity getRoot() {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment