From 14f15a7035eff44f3a6c5f7170db4ef5e02ab9ce Mon Sep 17 00:00:00 2001 From: Sonia Zorba <sonia.zorba@inaf.it> Date: Wed, 14 Aug 2019 14:56:55 +0200 Subject: [PATCH] Added modal and completed API for members/permissions removal --- .../main/java/it/inaf/ia2/gms/cli/CLI.java | 14 ++-- .../it/inaf/ia2/gms/client/GmsClient.java | 7 +- .../it/inaf/ia2/gms/client/GmsClientTest.java | 8 +-- gms-ui/src/api/server/index.js | 68 ++++++++++++++++++- gms-ui/src/components/GroupsPanel.vue | 16 ++--- gms-ui/src/components/Main.vue | 15 ++-- gms-ui/src/components/MembersPanel.vue | 45 ++++++++---- gms-ui/src/components/PermissionsPanel.vue | 17 +++-- .../{NewGroupModal.vue => AddGroupModal.vue} | 6 +- .../src/components/modals/AddMemberModal.vue | 20 ++++-- .../components/modals/AddPermissionModal.vue | 4 -- .../modals/ConfirmDeleteGroupModal.vue | 31 --------- .../modals/ConfirmRemoveGroupModal.vue | 34 ++++++++++ .../modals/ConfirmRemoveMemberModal.vue | 44 ++++++++++++ .../modals/ConfirmRemovePermissionModal.vue | 38 +++++++++++ gms-ui/src/store.js | 3 + .../ia2/gms/controller/MembersController.java | 35 ++++++++-- .../gms/controller/PermissionsController.java | 32 +++++++-- .../gms/controller/WebServiceController.java | 5 +- .../inaf/ia2/gms/model/AddMemberRequest.java | 19 ++++++ ...Request.java => AddPermissionRequest.java} | 2 +- .../ia2/gms/model/RemoveMemberRequest.java | 14 ++++ .../ia2/gms/persistence/PermissionsDAO.java | 11 +-- .../ia2/gms/service/PermissionsService.java | 6 +- gms/src/main/resources/sql/init.sql | 2 +- .../gms/controller/MembersControllerTest.java | 4 +- .../controller/PermissionsControllerTest.java | 30 ++++++-- .../controller/WebServiceControllerTest.java | 4 +- .../NestedGroupsIntegrationTest.java | 11 ++- .../gms/persistence/PermissionsDAOTest.java | 8 ++- .../PermissionsServiceIntegrationTest.java | 4 +- 31 files changed, 422 insertions(+), 135 deletions(-) rename gms-ui/src/components/modals/{NewGroupModal.vue => AddGroupModal.vue} (92%) delete mode 100644 gms-ui/src/components/modals/ConfirmDeleteGroupModal.vue create mode 100644 gms-ui/src/components/modals/ConfirmRemoveGroupModal.vue create mode 100644 gms-ui/src/components/modals/ConfirmRemoveMemberModal.vue create mode 100644 gms-ui/src/components/modals/ConfirmRemovePermissionModal.vue create mode 100644 gms/src/main/java/it/inaf/ia2/gms/model/AddMemberRequest.java rename gms/src/main/java/it/inaf/ia2/gms/model/{PermissionRequest.java => AddPermissionRequest.java} (91%) create mode 100644 gms/src/main/java/it/inaf/ia2/gms/model/RemoveMemberRequest.java diff --git a/gms-client/gms-cli/src/main/java/it/inaf/ia2/gms/cli/CLI.java b/gms-client/gms-cli/src/main/java/it/inaf/ia2/gms/cli/CLI.java index 6794f49..c2f55e5 100644 --- a/gms-client/gms-cli/src/main/java/it/inaf/ia2/gms/cli/CLI.java +++ b/gms-client/gms-cli/src/main/java/it/inaf/ia2/gms/cli/CLI.java @@ -58,11 +58,11 @@ public class CLI implements CommandLineRunner { switch (args[0]) { case "create-group": - client.createGroup(getNames(args, 1)); + client.addGroup(getNames(args, 1)); System.out.println("Group created"); break; case "delete-group": - client.deleteGroup(getNames(args, 1)); + client.removeGroup(getNames(args, 1)); System.out.println("Group deleted"); break; case "add-member": @@ -90,8 +90,8 @@ public class CLI implements CommandLineRunner { if (args.length < 4) { displayUsage(); } - client.deletePermission(getNames(args, args.length - 3), args[args.length - 2], args[args.length - 1]); - System.out.println("Permission added"); + client.removePermission(getNames(args, args.length - 2), args[args.length - 1]); + System.out.println("Permission removed"); break; case "prepare-join": if (args.length != 3) { @@ -108,12 +108,12 @@ public class CLI implements CommandLineRunner { private void displayUsage() { System.out.println("java -jar gms-client.jar\n" - + " create-group <name1 name2 name3>\n" - + " delete-group <name1 name2 name3>\n" + + " add-group <name1 name2 name3>\n" + + " remove-group <name1 name2 name3>\n" + " add-member <name1 name2 name3> <user_id>\n" + " remove-member <name1 name2 name3> <user_id>\n" + " add-permission <name1 name2 name3> <user_id> <permission>\n" - + " delete-permission <name1 name2 name3> <user_id> <permission>\n" + + " remove-permission <name1 name2 name3> <user_id>\n" + " prepare-join <from_user_id> <to_user_id>"); System.exit(0); } diff --git a/gms-client/gms-client-lib/src/main/java/it/inaf/ia2/gms/client/GmsClient.java b/gms-client/gms-client-lib/src/main/java/it/inaf/ia2/gms/client/GmsClient.java index 634640f..abfbeb5 100644 --- a/gms-client/gms-client-lib/src/main/java/it/inaf/ia2/gms/client/GmsClient.java +++ b/gms-client/gms-client-lib/src/main/java/it/inaf/ia2/gms/client/GmsClient.java @@ -40,7 +40,7 @@ public class GmsClient { this.restTemplate = restTemplate; } - public Group createGroup(List<String> names) { + public Group addGroup(List<String> names) { String url = UriComponentsBuilder.fromHttpUrl(baseUrl) .pathSegment(WS, "group") @@ -51,7 +51,7 @@ public class GmsClient { return restTemplate.exchange(url, HttpMethod.POST, httpEntity, Group.class).getBody(); } - public void deleteGroup(List<String> names) { + public void removeGroup(List<String> names) { String url = UriComponentsBuilder.fromHttpUrl(baseUrl) .pathSegment(WS, "group") @@ -101,13 +101,12 @@ public class GmsClient { return restTemplate.exchange(url, HttpMethod.POST, httpEntity, Permission.class).getBody(); } - public void deletePermission(List<String> names, String userId, String permission) { + public void removePermission(List<String> names, String userId) { String url = UriComponentsBuilder.fromHttpUrl(baseUrl) .pathSegment(WS, "permission") .queryParam("names", names.toArray()) .queryParam("userId", userId) - .queryParam("permission", permission) .toUriString(); restTemplate.exchange(url, HttpMethod.DELETE, getEntity(), Void.class); diff --git a/gms-client/gms-client-lib/src/test/java/it/inaf/ia2/gms/client/GmsClientTest.java b/gms-client/gms-client-lib/src/test/java/it/inaf/ia2/gms/client/GmsClientTest.java index d18b185..7771a98 100644 --- a/gms-client/gms-client-lib/src/test/java/it/inaf/ia2/gms/client/GmsClientTest.java +++ b/gms-client/gms-client-lib/src/test/java/it/inaf/ia2/gms/client/GmsClientTest.java @@ -51,7 +51,7 @@ public class GmsClientTest { List<String> names = Arrays.asList("LBT", "INAF"); - client.createGroup(names); + client.addGroup(names); ArgumentCaptor<HttpEntity> entityCaptor = ArgumentCaptor.forClass(HttpEntity.class); verify(restTemplate, times(1)).exchange(eq(BASE_URL + "/ws/group"), @@ -67,7 +67,7 @@ public class GmsClientTest { List<String> names = Arrays.asList("LBT", "INAF"); - client.deleteGroup(names); + client.removeGroup(names); ArgumentCaptor<HttpEntity> entityCaptor = ArgumentCaptor.forClass(HttpEntity.class); verify(restTemplate, times(1)).exchange(eq(BASE_URL + "/ws/group?names=LBT&names=INAF"), @@ -140,10 +140,10 @@ public class GmsClientTest { List<String> names = Arrays.asList("LBT", "INAF"); - client.deletePermission(names, "user_id", "ADMIN"); + client.removePermission(names, "user_id"); ArgumentCaptor<HttpEntity> entityCaptor = ArgumentCaptor.forClass(HttpEntity.class); - verify(restTemplate, times(1)).exchange(eq(BASE_URL + "/ws/permission?names=LBT&names=INAF&userId=user_id&permission=ADMIN"), + verify(restTemplate, times(1)).exchange(eq(BASE_URL + "/ws/permission?names=LBT&names=INAF&userId=user_id"), eq(HttpMethod.DELETE), entityCaptor.capture(), eq(Void.class)); HttpEntity<?> entity = entityCaptor.getValue(); diff --git a/gms-ui/src/api/server/index.js b/gms-ui/src/api/server/index.js index b84d003..0e883d9 100644 --- a/gms-ui/src/api/server/index.js +++ b/gms-ui/src/api/server/index.js @@ -82,7 +82,7 @@ export default { }) }); }, - deleteGroup (groupId, input) { + removeGroup (groupId, input) { let url = BASE_API_URL + 'group/' + groupId + '?paginatorPageSize=' + input.paginatorPageSize + '&paginatorPage=' + input.paginatorPage; @@ -128,5 +128,71 @@ export default { paginatorPage: input.paginatorPage }) }); + }, + getPermission (groupId, userId) { + let url = BASE_API_URL + 'permission?groupId=' + groupId + '&userId=' + userId; + + return apiRequest(url, { + method: 'GET', + cache: 'no-cache', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + } + }); + }, + addMember (userId, permission, input) { + let url = BASE_API_URL + 'member'; + + return apiRequest(url, { + method: 'POST', + cache: 'no-cache', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + body: JSON.stringify({ + groupId: input.selectedGroupId, + userId: userId, + permission: permission, + paginatorPageSize: input.paginatorPageSize, + paginatorPage: input.paginatorPage + }) + }); + }, + removeMember (userId, removeAlsoPermission, input) { + let url = BASE_API_URL + 'member' + + '?groupId=' + input.selectedGroupId + + '&userId=' + userId + + '&removeAlsoPermission=' + removeAlsoPermission + + '&paginatorPageSize=' + input.paginatorPageSize + + '&paginatorPage=' + input.paginatorPage; + return apiRequest(url, { + method: 'DELETE', + cache: 'no-cache', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + } + }); + }, + removePermission (userId, input) { + let url = BASE_API_URL + 'permission' + + '?groupId=' + input.selectedGroupId + + '&userId=' + userId + + '&paginatorPageSize=' + input.paginatorPageSize + + '&paginatorPage=' + input.paginatorPage; + return apiRequest(url, { + method: 'DELETE', + cache: 'no-cache', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + } + }); } }; diff --git a/gms-ui/src/components/GroupsPanel.vue b/gms-ui/src/components/GroupsPanel.vue index 3ddfc6a..04b55fc 100644 --- a/gms-ui/src/components/GroupsPanel.vue +++ b/gms-ui/src/components/GroupsPanel.vue @@ -14,7 +14,7 @@ <font-awesome-icon icon="edit"></font-awesome-icon> </a> - <a href="#" v-on:click.stop="openDeleteGroupModal(group)" class="text-danger" title="Delete"> + <a href="#" v-on:click.stop="openRemoveGroupModal(group)" class="text-danger" title="Delete"> <font-awesome-icon icon="trash"></font-awesome-icon> </a> </span> @@ -48,20 +48,20 @@ <div class="text-center"> </div> <RenameGroupModal ref="renameGroupModal" /> - <ConfirmDeleteGroupModal ref="confirmDeleteGroupModal" /> + <ConfirmRemoveGroupModal ref="confirmRemoveGroupModal" /> </b-tab> </template> <script> -import RenameGroupModal from './modals/RenameGroupModal.vue' -import ConfirmDeleteGroupModal from './modals/ConfirmDeleteGroupModal.vue' -import { mapState, mapActions } from 'vuex' +import RenameGroupModal from './modals/RenameGroupModal.vue'; +import ConfirmRemoveGroupModal from './modals/ConfirmRemoveGroupModal.vue'; +import { mapState, mapActions } from 'vuex'; export default { name: 'GroupsPanel', components: { RenameGroupModal, - ConfirmDeleteGroupModal + ConfirmRemoveGroupModal }, computed: mapState({ model: state => state.model, @@ -85,8 +85,8 @@ export default { openRenameGroupModal: function(group) { this.$refs.renameGroupModal.openRenameGroupModal(group); }, - openDeleteGroupModal: function(group) { - this.$refs.confirmDeleteGroupModal.openDeleteGroupModal(group); + openRemoveGroupModal: function(group) { + this.$refs.confirmRemoveGroupModal.openRemoveGroupModal(group); }, setPage: function(page) { console.log('setPage ', page); diff --git a/gms-ui/src/components/Main.vue b/gms-ui/src/components/Main.vue index 0fc06eb..27862fd 100644 --- a/gms-ui/src/components/Main.vue +++ b/gms-ui/src/components/Main.vue @@ -8,13 +8,14 @@ <PermissionsPanel /> <template slot="tabs-end"> <b-button variant="primary" class="in-tabs-header-btn" v-if="showAddGroupBtn" v-on:click="openAddGroupModal">Add group</b-button> - <b-button variant="primary" class="in-tabs-header-btn" v-if="showAddMemberBtn">Add member</b-button> - <b-button variant="primary" class="in-tabs-header-btn" v-if="showAddCollaboratorBtn">Add collaborator</b-button> + <b-button variant="primary" class="in-tabs-header-btn" v-if="showAddMemberBtn" v-on:click="openAddMemberModal">Add member</b-button> + <b-button variant="primary" class="in-tabs-header-btn" v-if="showAddCollaboratorBtn" v-on:click="openAddMemberModal">Add collaborator</b-button> <b-button variant="primary" class="in-tabs-header-btn" v-if="showAddPermissionBtn" v-on:click="openAddPermissionModal">Add permission</b-button> </template> </b-tabs> </b-card> - <NewGroupModal /> + <AddGroupModal /> + <AddMemberModal /> <AddPermissionModal /> </div> </template> @@ -24,7 +25,7 @@ import GroupsBreadcrumb from './GroupsBreadcrumb.vue' import GroupsPanel from './GroupsPanel.vue' import MembersPanel from './MembersPanel.vue' import PermissionsPanel from './PermissionsPanel.vue' -import NewGroupModal from './modals/NewGroupModal.vue' +import AddGroupModal from './modals/AddGroupModal.vue' import AddMemberModal from './modals/AddMemberModal.vue' import AddPermissionModal from './modals/AddPermissionModal.vue' import { mapState } from 'vuex'; @@ -36,7 +37,7 @@ export default { GroupsPanel, MembersPanel, PermissionsPanel, - NewGroupModal, + AddGroupModal, AddMemberModal, AddPermissionModal }, @@ -67,10 +68,10 @@ export default { } }, openAddGroupModal: function() { - this.$bvModal.show('new-group-modal'); + this.$bvModal.show('add-group-modal'); }, openAddMemberModal: function() { - + this.$bvModal.show('add-member-modal'); }, openAddPermissionModal: function() { this.$bvModal.show('add-permission-modal'); diff --git a/gms-ui/src/components/MembersPanel.vue b/gms-ui/src/components/MembersPanel.vue index 3e28e93..d60a9e7 100644 --- a/gms-ui/src/components/MembersPanel.vue +++ b/gms-ui/src/components/MembersPanel.vue @@ -3,12 +3,11 @@ <div v-if="model.membersPanel !== null"> <b-list-group v-for="member in model.membersPanel.items" id="members-list"> <b-list-group-item href="#"> - {{member.label}} - <span v-if="model.permission === 'ADMIN'"> - <a href="#" v-on:click="changeMemberPermission(member)"> - <font-awesome-icon icon="edit"></font-awesome-icon> - </a> - <a href="#" v-on:click="deleteMember(member)"> + <div class="float-left"> + <User v-bind:user="member" /> + </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"> <font-awesome-icon icon="trash"></font-awesome-icon> </a> </span> @@ -25,27 +24,49 @@ v-on:change="setPage" ></b-pagination> </div> + <ConfirmRemoveMemberModal ref="confirmRemoveMemberModal" /> </b-tab> </template> <script> +import client from 'api-client'; +import User from './User.vue'; +import ConfirmRemoveMemberModal from './modals/ConfirmRemoveMemberModal.vue' import { mapState } from 'vuex'; export default { name: 'MembersPanel', + components: { + User, + ConfirmRemoveMemberModal + }, computed: mapState({ - model: state => state.model, + model: state => state.model }), methods: { - deleteMember: function(member) { - console.log('deleteMember ' + member.id); - }, - changeMemberPermission: function(member) { - console.log('changeMemberPermission ' + member.id); + openRemoveMemberModal: function(member) { + getMemberPermission(this, member) + .then(memberPermission => { + this.$refs.confirmRemoveMemberModal.openRemoveMemberModal(member, memberPermission); + }); }, setPage: function(page) { console.log('setPage ', page); } } } + +function getMemberPermission(self, member) { + return new Promise((resolve, reject) => { + if(self.model.permission === 'ADMIN') { + let groupId = self.$store.state.input.selectedGroupId; + client.getPermission(groupId, member.id) + .then(res => { + resolve(res.permission); + }); + } else { + resolve(null); + } + }); +} </script> diff --git a/gms-ui/src/components/PermissionsPanel.vue b/gms-ui/src/components/PermissionsPanel.vue index e4ee838..9c55583 100644 --- a/gms-ui/src/components/PermissionsPanel.vue +++ b/gms-ui/src/components/PermissionsPanel.vue @@ -15,7 +15,11 @@ <User v-bind:user="up.user" /> </td> <td>{{up.permission}}</td> - <td></td> + <td> + <a href="#" v-on:click.stop="openRemovePermissionModal(up.user)" class="text-danger" title="Remove permission"> + <font-awesome-icon icon="trash"></font-awesome-icon> + </a> + </td> </tr> </tbody> </table> @@ -30,24 +34,27 @@ v-on:change="setPage" ></b-pagination> </div> + <ConfirmRemovePermissionModal ref="confirmRemovePermissionModal" /> </b-tab> </template> <script> -import User from './User.vue' +import User from './User.vue'; +import ConfirmRemovePermissionModal from './modals/ConfirmRemovePermissionModal.vue' import { mapState } from 'vuex'; export default { name: 'PermissionsPanel', components: { - User + User, + ConfirmRemovePermissionModal }, computed: mapState({ model: state => state.model, }), methods: { - deletePermission: function(userPermission) { - + openRemovePermissionModal: function(user) { + this.$refs.confirmRemovePermissionModal.openRemovePermissionModal(user); }, setPage: function(page) { console.log('setPage ', page); diff --git a/gms-ui/src/components/modals/NewGroupModal.vue b/gms-ui/src/components/modals/AddGroupModal.vue similarity index 92% rename from gms-ui/src/components/modals/NewGroupModal.vue rename to gms-ui/src/components/modals/AddGroupModal.vue index e976b8c..6f5ba17 100644 --- a/gms-ui/src/components/modals/NewGroupModal.vue +++ b/gms-ui/src/components/modals/AddGroupModal.vue @@ -1,5 +1,5 @@ <template> - <b-modal id="new-group-modal" title="Add group" @show="resetModal" ok-title="Add" @ok="addGroup"> + <b-modal id="add-group-modal" title="Add group" @show="resetModal" ok-title="Add" @ok="addGroup"> <b-form inline> <label class="w-25" for="new-group-name-input">Group name:</label> <b-form-input v-model="newGroupName" @@ -18,7 +18,7 @@ import client from 'api-client'; export default { - name: 'NewGroupModal', + name: 'AddGroupModal', computed: { newGroupNameState() { if(this.newGroupNameError) { @@ -56,7 +56,7 @@ export default { this.newGroupNameError = res.message; } else { this.$store.commit('updateGroupsPanel', res); - this.$bvModal.hide('new-group-modal'); + this.$bvModal.hide('add-group-modal'); } }); } diff --git a/gms-ui/src/components/modals/AddMemberModal.vue b/gms-ui/src/components/modals/AddMemberModal.vue index 23d4795..db7c06a 100644 --- a/gms-ui/src/components/modals/AddMemberModal.vue +++ b/gms-ui/src/components/modals/AddMemberModal.vue @@ -1,26 +1,32 @@ <template> <b-modal id="add-member-modal" title="Add member" ok-title="Add" @ok="addMember"> - <SearchUser /> + <SearchUser ref="searchUser" /> </b-modal> </template> <script> import client from 'api-client'; import SearchUser from './SearchUser.vue' +import { mapState } from 'vuex'; export default { name: 'AddMemberModal', components: { SearchUser }, - data: function() { - return { - permission: 'VIEW_MEMBERS' - } - }, methods: { - addMember: function() { + addMember: function(event) { + // Prevent modal from closing + event.preventDefault(); + + let userId = this.$refs.searchUser.selectedUser; + let permission = this.$refs.searchUser.permission; + client.addMember(userId, permission, this.$store.state.input) + .then(res => { + this.$store.commit('updateMembersPanel', res); + this.$bvModal.hide('add-member-modal'); + }); } } }; diff --git a/gms-ui/src/components/modals/AddPermissionModal.vue b/gms-ui/src/components/modals/AddPermissionModal.vue index 7b792e9..9e1db36 100644 --- a/gms-ui/src/components/modals/AddPermissionModal.vue +++ b/gms-ui/src/components/modals/AddPermissionModal.vue @@ -13,10 +13,6 @@ export default { components: { SearchUser }, - data: function() { - return { - } - }, methods: { addPermission: function(event) { // Prevent modal from closing diff --git a/gms-ui/src/components/modals/ConfirmDeleteGroupModal.vue b/gms-ui/src/components/modals/ConfirmDeleteGroupModal.vue deleted file mode 100644 index e563c53..0000000 --- a/gms-ui/src/components/modals/ConfirmDeleteGroupModal.vue +++ /dev/null @@ -1,31 +0,0 @@ -<template> - <b-modal id="confirm-delete-group-modal" title="Confirm action" ok-title="Delete" @ok="deleteGroup" ok-variant="danger"> - <p v-if="groupToDelete">Are you sure that you want to delete the group <strong>{{groupToDelete.groupName}}</strong>?</p> - </b-modal> -</template> - -<script> -import client from 'api-client'; - -export default { - name: 'ConfirmDeleteGroupModal', - data: function() { - return { - groupToDelete: null - } - }, - methods: { - openDeleteGroupModal: function(group) { - this.groupToDelete = group; - this.$bvModal.show('confirm-delete-group-modal'); - }, - deleteGroup: function() { - client.deleteGroup(this.groupToDelete.groupId, this.$store.state.input) - .then(res => { - this.$store.commit('updateGroupsPanel', res); - this.$bvModal.hide('confirm-delete-group-modal'); - }) - } - } -} -</script> diff --git a/gms-ui/src/components/modals/ConfirmRemoveGroupModal.vue b/gms-ui/src/components/modals/ConfirmRemoveGroupModal.vue new file mode 100644 index 0000000..f22196a --- /dev/null +++ b/gms-ui/src/components/modals/ConfirmRemoveGroupModal.vue @@ -0,0 +1,34 @@ +<template> + <b-modal id="confirm-remove-group-modal" title="Confirm action" ok-title="Delete" @ok="removeGroup" ok-variant="danger"> + <p v-if="groupToRemove">Are you sure that you want to delete the group <strong>{{groupToRemove.groupName}}</strong>?</p> + </b-modal> +</template> + +<script> +import client from 'api-client'; + +export default { + name: 'ConfirmRemoveGroupModal', + data: function() { + return { + groupToRemove: null + } + }, + methods: { + openRemoveGroupModal: function(group) { + this.groupToRemove = group; + this.$bvModal.show('confirm-remove-group-modal'); + }, + removeGroup: function(event) { + // Prevent modal from closing + event.preventDefault(); + + client.removeGroup(this.groupToRemove.groupId, this.$store.state.input) + .then(res => { + this.$store.commit('updateGroupsPanel', res); + this.$bvModal.hide('confirm-remove-group-modal'); + }) + } + } +} +</script> diff --git a/gms-ui/src/components/modals/ConfirmRemoveMemberModal.vue b/gms-ui/src/components/modals/ConfirmRemoveMemberModal.vue new file mode 100644 index 0000000..48d2a8c --- /dev/null +++ b/gms-ui/src/components/modals/ConfirmRemoveMemberModal.vue @@ -0,0 +1,44 @@ +<template> + <b-modal id="confirm-remove-member-modal" title="Confirm action" ok-title="Remove" @ok="removeMember" ok-variant="danger"> + <p v-if="memberToRemove">Are you sure that you want to remove the user {{memberToRemove.displayName}} from this group?</p> + <b-form inline v-if="model.permission === 'ADMIN' && memberPermission"> + <b-form-checkbox v-model="removeAlsoPermission">Remove also permission ({{memberPermission}})</b-form-checkbox> + </b-form> + </b-modal> +</template> + +<script> +import client from 'api-client'; +import { mapState, mapActions } from 'vuex'; + +export default { + name: 'ConfirmRemoveGroupModal', + data: function() { + return { + memberToRemove: null, + memberPermission: null, + removeAlsoPermission: true + } + }, + computed: mapState({ + model: state => state.model + }), + methods: { + openRemoveMemberModal: function(member, memberPermission) { + this.memberToRemove = member; + this.memberPermission = memberPermission; + this.$bvModal.show('confirm-remove-member-modal'); + }, + removeMember: function(event) { + // Prevent modal from closing + event.preventDefault(); + + client.removeMember(this.memberToRemove.id, this.removeAlsoPermission, this.$store.state.input) + .then(res => { + this.$store.commit('updateMembersPanel', res); + this.$bvModal.hide('confirm-remove-member-modal'); + }); + } + } +} +</script> diff --git a/gms-ui/src/components/modals/ConfirmRemovePermissionModal.vue b/gms-ui/src/components/modals/ConfirmRemovePermissionModal.vue new file mode 100644 index 0000000..4964e08 --- /dev/null +++ b/gms-ui/src/components/modals/ConfirmRemovePermissionModal.vue @@ -0,0 +1,38 @@ +<template> + <b-modal id="confirm-remove-permission-modal" title="Confirm action" ok-title="Remove" @ok="removePermission" ok-variant="danger"> + <p v-if="user">Are you sure that you want to remove the permission for the user {{user.displayName}}?</p> + </b-modal> +</template> + +<script> +import client from 'api-client'; +import { mapState, mapActions } from 'vuex'; + +export default { + name: 'ConfirmRemovePermissionModal', + data: function() { + return { + user: null + } + }, + computed: mapState({ + model: state => state.model + }), + methods: { + openRemovePermissionModal: function(user) { + this.user = user; + this.$bvModal.show('confirm-remove-permission-modal'); + }, + removePermission: function(event) { + // Prevent modal from closing + event.preventDefault(); + + client.removePermission(this.user.id, this.$store.state.input) + .then(res => { + this.$store.commit('updatePermissionsPanel', res); + this.$bvModal.hide('confirm-remove-permission-modal'); + }); + } + } +} +</script> diff --git a/gms-ui/src/store.js b/gms-ui/src/store.js index 44ce164..ddfed3b 100644 --- a/gms-ui/src/store.js +++ b/gms-ui/src/store.js @@ -31,6 +31,9 @@ export default new Vuex.Store({ }, updatePermissionsPanel(state, permissionsPanel) { this.state.model.permissionsPanel = permissionsPanel; + }, + updateMembersPanel(state, membersPanel) { + this.state.model.membersPanel = membersPanel; } }, getters: { diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/MembersController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/MembersController.java index 3aef326..d6069b1 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/controller/MembersController.java +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/MembersController.java @@ -2,10 +2,12 @@ package it.inaf.ia2.gms.controller; import it.inaf.ia2.gms.authn.SessionData; import it.inaf.ia2.gms.exception.UnauthorizedException; +import it.inaf.ia2.gms.model.AddMemberRequest; import it.inaf.ia2.gms.model.MemberRequest; import it.inaf.ia2.gms.model.PaginatedData; import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.model.RapUser; +import it.inaf.ia2.gms.model.RemoveMemberRequest; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.gms.service.MembersService; @@ -37,32 +39,55 @@ public class MembersController { private MembersService membersService; @PostMapping(value = "/member", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) - public ResponseEntity<PaginatedData<RapUser>> addMember(@Valid @RequestBody MemberRequest request) { + public ResponseEntity<PaginatedData<RapUser>> addMember(@Valid @RequestBody AddMemberRequest request) { GroupEntity group = groupsService.getGroupById(request.getGroupId()); - verifyCurrentUserCanManageMembers(group); + Permission currentUserPermission = verifyCurrentUserCanManageMembers(group); membersService.addMember(request.getGroupId(), request.getUserId()); + if (currentUserPermission == Permission.MANAGE_MEMBERS) { + // Automatically assign the VIEW_MEMBERS permission ("Add collaborator" feature) + permissionsService.addPermission(group, request.getUserId(), Permission.VIEW_MEMBERS); + } else if (request.getPermission() != null) { + // Admin users can specify a permission + permissionsService.addPermission(group, request.getUserId(), request.getPermission()); + } return new ResponseEntity<>(getMembersPanel(request), HttpStatus.CREATED); } @DeleteMapping(value = "/member", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) - public ResponseEntity<PaginatedData<RapUser>> removeMember(@Valid MemberRequest request) { + public ResponseEntity<PaginatedData<RapUser>> removeMember(@Valid RemoveMemberRequest request) { GroupEntity group = groupsService.getGroupById(request.getGroupId()); - verifyCurrentUserCanManageMembers(group); + Permission currentUserPermission = verifyCurrentUserCanManageMembers(group); membersService.removeMember(group.getId(), request.getUserId()); + // For users having the MANAGE_MEMBERS permission, the VIEW_MEMBERS permission + // is automatically assigned when they add a member ("Add collaborator" feature). + // We want to keep also the reverse behavior. + // If the member permission is not VIEW_MEMBERS that means that it has been + // changed by an ADMIN user, so we don't remove it. + boolean removeCollaborator = currentUserPermission == Permission.MANAGE_MEMBERS + && permissionsService.getUserPermissionForGroup(group, request.getUserId()) == Permission.VIEW_MEMBERS; + + // ADMIN users can choose if delete also the permission or not. + boolean adminRemovePermission = currentUserPermission == Permission.ADMIN && request.isRemoveAlsoPermission(); + + if (removeCollaborator || adminRemovePermission) { + permissionsService.removePermission(group, request.getUserId()); + } + return ResponseEntity.ok(getMembersPanel(request)); } - private void verifyCurrentUserCanManageMembers(GroupEntity group) { + private Permission verifyCurrentUserCanManageMembers(GroupEntity group) { Permission currentNodePermission = permissionsService.getUserPermissionForGroup(group, session.getUserId()); if (currentNodePermission != Permission.ADMIN && currentNodePermission != Permission.MANAGE_MEMBERS) { throw new UnauthorizedException("Missing admin or manage members permissions"); } + return currentNodePermission; } private PaginatedData<RapUser> getMembersPanel(MemberRequest request) { diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java index 53582bb..cd9ba1e 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java @@ -2,22 +2,28 @@ package it.inaf.ia2.gms.controller; import it.inaf.ia2.gms.authn.SessionData; import it.inaf.ia2.gms.exception.UnauthorizedException; -import it.inaf.ia2.gms.model.PermissionRequest; +import it.inaf.ia2.gms.model.AddPermissionRequest; +import it.inaf.ia2.gms.model.MemberRequest; import it.inaf.ia2.gms.model.PaginatedData; +import it.inaf.ia2.gms.model.PaginatedModelRequest; import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.model.UserPermission; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.gms.service.PermissionsService; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -32,8 +38,24 @@ public class PermissionsController { @Autowired private PermissionsService permissionsService; + @GetMapping(value = "/permission") + public ResponseEntity<Map<String, Permission>> getUserPermission(@RequestParam("groupId") String groupId, @RequestParam("userId") String userId) { + + GroupEntity group = groupsService.getGroupById(groupId); + verifyCurrentUserCanManagePermissions(group); + + Permission permission = permissionsService.getUserPermissionForGroup(group, userId); + if (permission == null) { + return ResponseEntity.notFound().build(); + } else { + Map<String, Permission> response = new HashMap<>(); + response.put("permission", permission); + return ResponseEntity.ok(response); + } + } + @PostMapping(value = "/permission", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE) - public ResponseEntity<PaginatedData<UserPermission>> addPermission(@Valid @RequestBody PermissionRequest request) { + public ResponseEntity<PaginatedData<UserPermission>> addPermission(@Valid @RequestBody AddPermissionRequest request) { GroupEntity group = groupsService.getGroupById(request.getGroupId()); verifyCurrentUserCanManagePermissions(group); @@ -44,12 +66,12 @@ public class PermissionsController { } @DeleteMapping(value = "/permission", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) - public ResponseEntity<PaginatedData<UserPermission>> deletePermission(@Valid PermissionRequest request) { + public ResponseEntity<PaginatedData<UserPermission>> deletePermission(@Valid MemberRequest request) { GroupEntity group = groupsService.getGroupById(request.getGroupId()); verifyCurrentUserCanManagePermissions(group); - permissionsService.deletePermission(group, request.getUserId(), request.getPermission()); + permissionsService.removePermission(group, request.getUserId()); return ResponseEntity.ok(getPermissionsPanel(group, request)); } @@ -61,7 +83,7 @@ public class PermissionsController { } } - private PaginatedData<UserPermission> getPermissionsPanel(GroupEntity group, PermissionRequest request) { + private PaginatedData<UserPermission> getPermissionsPanel(GroupEntity group, PaginatedModelRequest request) { List<UserPermission> permissions = permissionsService.getAllPermissions(group); return new PaginatedData<>(permissions, request.getPaginatorPage(), request.getPaginatorPageSize()); } diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/WebServiceController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/WebServiceController.java index 04c067c..b57df94 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/controller/WebServiceController.java +++ b/gms/src/main/java/it/inaf/ia2/gms/controller/WebServiceController.java @@ -101,12 +101,11 @@ public class WebServiceController { } @DeleteMapping("/permission") - public ResponseEntity<?> deletePermission(@RequestParam("names") String[] names, - @RequestParam("userId") String userId, @RequestParam("permission") Permission permission) { + public ResponseEntity<?> deletePermission(@RequestParam("names") String[] names, @RequestParam("userId") String userId) { GroupEntity group = getGroupByNames(Arrays.asList(names)); - permissionsService.deletePermission(group, userId, permission); + permissionsService.removePermission(group, userId); return ResponseEntity.noContent().build(); } diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/AddMemberRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/AddMemberRequest.java new file mode 100644 index 0000000..6f55c0a --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/model/AddMemberRequest.java @@ -0,0 +1,19 @@ +package it.inaf.ia2.gms.model; + +public class AddMemberRequest extends MemberRequest { + + /** + * When adding a member it is possible to assign also a permission. This + * field can be null (in that case the user is member of the group but + * he/she can't do nothing (not even seeing him/her group membership). + */ + private Permission permission; + + public Permission getPermission() { + return permission; + } + + public void setPermission(Permission permission) { + this.permission = permission; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/PermissionRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/AddPermissionRequest.java similarity index 91% rename from gms/src/main/java/it/inaf/ia2/gms/model/PermissionRequest.java rename to gms/src/main/java/it/inaf/ia2/gms/model/AddPermissionRequest.java index 1776453..e4b2037 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/model/PermissionRequest.java +++ b/gms/src/main/java/it/inaf/ia2/gms/model/AddPermissionRequest.java @@ -3,7 +3,7 @@ package it.inaf.ia2.gms.model; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -public class PermissionRequest extends PaginatedModelRequest { +public class AddPermissionRequest extends PaginatedModelRequest { @NotEmpty private String groupId; diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/RemoveMemberRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/RemoveMemberRequest.java new file mode 100644 index 0000000..ff22515 --- /dev/null +++ b/gms/src/main/java/it/inaf/ia2/gms/model/RemoveMemberRequest.java @@ -0,0 +1,14 @@ +package it.inaf.ia2.gms.model; + +public class RemoveMemberRequest extends MemberRequest { + + private boolean removeAlsoPermission; + + public boolean isRemoveAlsoPermission() { + return removeAlsoPermission; + } + + public void setRemoveAlsoPermission(boolean removeAlsoPermission) { + this.removeAlsoPermission = removeAlsoPermission; + } +} diff --git a/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsDAO.java b/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsDAO.java index 6246031..2aee489 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsDAO.java +++ b/gms/src/main/java/it/inaf/ia2/gms/persistence/PermissionsDAO.java @@ -23,9 +23,11 @@ public class PermissionsDAO { jdbcTemplate = new JdbcTemplate(dataSource); } - public PermissionEntity createPermission(PermissionEntity userPermission) { + public PermissionEntity createOrUpdatePermission(PermissionEntity userPermission) { - String sql = "INSERT INTO gms_permission(group_id, user_id, permission, group_path) VALUES(?, ?, ?, ?)"; + String sql = "INSERT INTO gms_permission(group_id, user_id, permission, group_path) VALUES(?, ?, ?, ?)\n" + + "ON CONFLICT (group_id, user_id) DO UPDATE\n" + + "SET permission = EXCLUDED.permission"; jdbcTemplate.update(conn -> { PreparedStatement ps = conn.prepareStatement(sql); @@ -131,15 +133,14 @@ public class PermissionsDAO { }); } - public void deletePermission(String groupId, String userId, Permission permission) { + public void deletePermission(String groupId, String userId) { - String sql = "DELETE FROM gms_permission WHERE group_id = ? AND user_id = ? AND permission = ?"; + String sql = "DELETE FROM gms_permission WHERE group_id = ? AND user_id = ?"; jdbcTemplate.update(conn -> { PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, groupId); ps.setString(2, userId); - ps.setObject(3, permission.toString(), Types.OTHER); return ps; }); } diff --git a/gms/src/main/java/it/inaf/ia2/gms/service/PermissionsService.java b/gms/src/main/java/it/inaf/ia2/gms/service/PermissionsService.java index ea9761d..667e3fe 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/service/PermissionsService.java +++ b/gms/src/main/java/it/inaf/ia2/gms/service/PermissionsService.java @@ -60,8 +60,8 @@ public class PermissionsService { return PermissionUtils.getGroupPermission(group, permissions).orElse(null); } - public void deletePermission(GroupEntity group, String userId, Permission permission) { - permissionsDAO.deletePermission(group.getId(), userId, permission); + public void removePermission(GroupEntity group, String userId) { + permissionsDAO.deletePermission(group.getId(), userId); } public PermissionEntity addPermission(GroupEntity group, String userId, Permission permission) { @@ -72,7 +72,7 @@ public class PermissionsService { permissionEntity.setPermission(permission); permissionEntity.setGroupPath(group.getPath()); - return permissionsDAO.createPermission(permissionEntity); + return permissionsDAO.createOrUpdatePermission(permissionEntity); } public Optional<PermissionEntity> findPermissionEntity(String groupId, String userId, Permission permission) { diff --git a/gms/src/main/resources/sql/init.sql b/gms/src/main/resources/sql/init.sql index 55d7def..7c5a397 100644 --- a/gms/src/main/resources/sql/init.sql +++ b/gms/src/main/resources/sql/init.sql @@ -25,7 +25,7 @@ CREATE TABLE gms_permission ( user_id varchar NOT NULL, permission permission_type NOT NULL, group_path ltree NOT NULL, -- group_path is copied here for performance reasons - primary key (group_id, user_id, permission), + primary key (group_id, user_id), -- we can have 1 permission for each group foreign key (group_id) references gms_group(id), foreign key (group_path) references gms_group(path) ); diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/MembersControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/MembersControllerTest.java index 8d1a436..b18fc5a 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/controller/MembersControllerTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/controller/MembersControllerTest.java @@ -2,7 +2,7 @@ package it.inaf.ia2.gms.controller; import com.fasterxml.jackson.databind.ObjectMapper; import it.inaf.ia2.gms.authn.SessionData; -import it.inaf.ia2.gms.model.MemberRequest; +import it.inaf.ia2.gms.model.AddMemberRequest; import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.service.GroupsService; @@ -67,7 +67,7 @@ public class MembersControllerTest { @Test public void testAddMember() throws Exception { - MemberRequest request = new MemberRequest(); + AddMemberRequest request = new AddMemberRequest(); request.setGroupId("group_id"); request.setUserId("user_id"); request.setPaginatorPage(1); diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/PermissionsControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/PermissionsControllerTest.java index 7aa612e..4b635eb 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/controller/PermissionsControllerTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/controller/PermissionsControllerTest.java @@ -3,7 +3,7 @@ package it.inaf.ia2.gms.controller; import com.fasterxml.jackson.databind.ObjectMapper; import it.inaf.ia2.gms.authn.SessionData; import it.inaf.ia2.gms.model.Permission; -import it.inaf.ia2.gms.model.PermissionRequest; +import it.inaf.ia2.gms.model.AddPermissionRequest; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.gms.service.PermissionsService; @@ -21,6 +21,7 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -62,10 +63,29 @@ public class PermissionsControllerTest { when(permissionsService.getUserPermissionForGroup(eq(group), eq("admin_id"))).thenReturn(Permission.ADMIN); } + @Test + public void testGetPermission() throws Exception { + + when(permissionsService.getUserPermissionForGroup(eq(group), eq("user_id"))).thenReturn(Permission.MANAGE_MEMBERS); + + mockMvc.perform(get("/permission?groupId=group_id&userId=user_id") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.permission", is("MANAGE_MEMBERS"))); + } + + @Test + public void testGetInexistentPermission() throws Exception { + + mockMvc.perform(get("/permission?groupId=group_id&userId=user_id") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(status().isNotFound()); + } + @Test public void testAddPermission() throws Exception { - PermissionRequest request = new PermissionRequest(); + AddPermissionRequest request = new AddPermissionRequest(); request.setGroupId("group_id"); request.setUserId("user_id"); request.setPermission(Permission.ADMIN); @@ -82,12 +102,12 @@ public class PermissionsControllerTest { } @Test - public void testDeletePermission() throws Exception { + public void testRemovePermission() throws Exception { - mockMvc.perform(delete("/permission?groupId=group_id&userId=user_id&permission=ADMIN&paginatorPage=1&paginatorPageSize=10")) + mockMvc.perform(delete("/permission?groupId=group_id&userId=user_id&paginatorPage=1&paginatorPageSize=10")) .andExpect(status().isOk()) .andExpect(jsonPath("$.currentPage", is(1))); - verify(permissionsService, times(1)).deletePermission(eq(group), eq("user_id"), eq(Permission.ADMIN)); + verify(permissionsService, times(1)).removePermission(eq(group), eq("user_id")); } } diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/WebServiceControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/WebServiceControllerTest.java index ee1d3f1..422b915 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/controller/WebServiceControllerTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/controller/WebServiceControllerTest.java @@ -181,7 +181,7 @@ public class WebServiceControllerTest { } @Test - public void testDeletePermission() throws Exception { + public void testRemovePermission() throws Exception { List<String> names = Arrays.asList("LBT", "INAF"); GroupEntity inaf = getInafGroup(); @@ -190,7 +190,7 @@ public class WebServiceControllerTest { mockMvc.perform(delete("/ws/permission?names=LBT&names=INAF&userId=user_id&permission=ADMIN")) .andExpect(status().isNoContent()); - verify(permissionsService, times(1)).deletePermission(eq(inaf), eq("user_id"), eq(Permission.ADMIN)); + verify(permissionsService, times(1)).removePermission(eq(inaf), eq("user_id")); } @Test diff --git a/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java b/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java index 88f1808..0b79415 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java @@ -43,7 +43,7 @@ public class NestedGroupsIntegrationTest { superAdminPermission.setGroupId(GroupsService.ROOT); superAdminPermission.setPermission(Permission.ADMIN); superAdminPermission.setGroupPath(""); - permissionsDAO.createPermission(superAdminPermission); + permissionsDAO.createOrUpdatePermission(superAdminPermission); // Setup groups GroupEntity root = groupsService.getRoot(); @@ -95,29 +95,28 @@ public class NestedGroupsIntegrationTest { assertFalse(p2.isHasChildren()); // Setup lower permissions - permissionsDAO.deletePermission(superAdminPermission.getGroupId(), - superAdminPermission.getUserId(), superAdminPermission.getPermission()); + permissionsDAO.deletePermission(superAdminPermission.getGroupId(), superAdminPermission.getUserId()); PermissionEntity p1Permission = new PermissionEntity(); p1Permission.setUserId(userId); p1Permission.setGroupId(lbtInafProgram1.getId()); p1Permission.setPermission(Permission.MANAGE_MEMBERS); p1Permission.setGroupPath(lbtInafProgram1.getPath()); - permissionsDAO.createPermission(p1Permission); + permissionsDAO.createOrUpdatePermission(p1Permission); PermissionEntity lbtPermission = new PermissionEntity(); lbtPermission.setUserId(userId); lbtPermission.setGroupId(lbtInaf.getId()); lbtPermission.setPermission(Permission.VIEW_MEMBERS); lbtPermission.setGroupPath(lbtInaf.getPath()); - permissionsDAO.createPermission(lbtPermission); + permissionsDAO.createOrUpdatePermission(lbtPermission); PermissionEntity radioPermission = new PermissionEntity(); radioPermission.setUserId(userId); radioPermission.setGroupId(radio.getId()); radioPermission.setPermission(Permission.VIEW_MEMBERS); radioPermission.setGroupPath(radio.getPath()); - permissionsDAO.createPermission(radioPermission); + permissionsDAO.createOrUpdatePermission(radioPermission); // Check level 0 (ROOT) groupNodes = groupsTreeBuilder.listSubGroups(root.getId(), userId, request).getItems(); diff --git a/gms/src/test/java/it/inaf/ia2/gms/persistence/PermissionsDAOTest.java b/gms/src/test/java/it/inaf/ia2/gms/persistence/PermissionsDAOTest.java index 6f411d8..0bffd30 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/persistence/PermissionsDAOTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/persistence/PermissionsDAOTest.java @@ -48,7 +48,7 @@ public class PermissionsDAOTest { permission.setPermission(Permission.ADMIN); permission.setGroupPath(root.getPath()); - permissionsDAO.createPermission(permission); + permissionsDAO.createOrUpdatePermission(permission); List<PermissionEntity> permissions = permissionsDAO.findUserPermissions(userId); @@ -62,7 +62,11 @@ public class PermissionsDAOTest { permissions = permissionsDAO.getGroupsPermissions(root.getId()); assertEquals(1, permissions.size()); - permissionsDAO.deletePermission(permission.getGroupId(), permission.getUserId(), permission.getPermission()); + // test upsert + permission.setPermission(Permission.MANAGE_MEMBERS); + permissionsDAO.createOrUpdatePermission(permission); + + permissionsDAO.deletePermission(permission.getGroupId(), permission.getUserId()); permissions = permissionsDAO.findUserPermissions(userId); assertTrue(permissions.isEmpty()); diff --git a/gms/src/test/java/it/inaf/ia2/gms/service/PermissionsServiceIntegrationTest.java b/gms/src/test/java/it/inaf/ia2/gms/service/PermissionsServiceIntegrationTest.java index 3d5c944..c296be9 100644 --- a/gms/src/test/java/it/inaf/ia2/gms/service/PermissionsServiceIntegrationTest.java +++ b/gms/src/test/java/it/inaf/ia2/gms/service/PermissionsServiceIntegrationTest.java @@ -59,7 +59,7 @@ public class PermissionsServiceIntegrationTest { superAdminPermission.setGroupId(root.getId()); superAdminPermission.setPermission(Permission.ADMIN); superAdminPermission.setGroupPath(root.getPath()); - permissionsDAO.createPermission(superAdminPermission); + permissionsDAO.createOrUpdatePermission(superAdminPermission); List<UserPermission> permissions = permissionsService.getAllPermissions(root); @@ -67,6 +67,6 @@ public class PermissionsServiceIntegrationTest { assertEquals(Permission.ADMIN, permissions.get(0).getPermission()); assertEquals(USER_ID, permissions.get(0).getUser().getId()); - permissionsService.deletePermission(root, USER_ID, Permission.ADMIN); + permissionsService.removePermission(root, USER_ID); } } -- GitLab