Skip to content

Commit e1c3f7f

Browse files
committed
#721 | impl_version 1 for GroupPrivilege
1 parent d998af1 commit e1c3f7f

File tree

7 files changed

+90
-18
lines changed

7 files changed

+90
-18
lines changed

avni-server-api/src/main/java/org/avni/server/dao/GroupPrivilegeRepository.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.avni.server.dao;
22

3-
import org.avni.server.domain.CHSEntity;
43
import org.avni.server.domain.accessControl.GroupPrivilege;
54
import org.joda.time.DateTime;
65
import org.springframework.data.domain.Page;
@@ -27,14 +26,15 @@ default GroupPrivilege findByNameIgnoreCase(String name) {
2726
throw new UnsupportedOperationException("No field 'name' in GroupPrivilege.");
2827
}
2928

30-
List<GroupPrivilege> findByGroup_Id(Long groupId);
29+
List<GroupPrivilege> findByGroup_IdAndImplVersion(Long groupId, int implVersion);
3130

3231
@Query(value = "select distinct gp.*\n" +
3332
"from group_privilege gp\n" +
3433
" join user_group ug on ug.group_id = gp.group_id\n" +
3534
" join privilege p on gp.privilege_id = p.id\n" +
3635
"where ug.user_id = :userId\n" +
3736
" and gp.is_voided = false\n" +
37+
" and gp.impl_version = 1\n" +
3838
" and ug.is_voided = false\n" +
3939
" and allow = true", nativeQuery = true)
4040
List<GroupPrivilege> getAllAllowedPrivilegesForUser(Long userId);
@@ -50,4 +50,14 @@ Page<GroupPrivilege> findBySubjectTypeIsNotNullAndLastModifiedDateTimeIsBetweenO
5050
default boolean existsByLastModifiedDateTimeGreaterThan(DateTime lastModifiedDateTime) {
5151
return existsByLastModifiedDateTimeGreaterThan(lastModifiedDateTime == null ? null : lastModifiedDateTime.toDate());
5252
}
53+
54+
default GroupPrivilege saveGroupPrivilege(GroupPrivilege groupPrivilege) {
55+
groupPrivilege.setImplVersion(GroupPrivilege.IMPL_VERSION);
56+
return this.save(groupPrivilege);
57+
}
58+
59+
default List<GroupPrivilege> saveAllGroupPrivileges(List<GroupPrivilege> groupPrivileges) {
60+
groupPrivileges.forEach(gp -> gp.setImplVersion(GroupPrivilege.IMPL_VERSION));
61+
return this.saveAll(groupPrivileges);
62+
}
5363
}

avni-server-api/src/main/java/org/avni/server/domain/accessControl/GroupPrivilege.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
44
import org.avni.server.domain.*;
5-
import org.avni.server.domain.accessControl.Privilege;
65
import org.hibernate.annotations.BatchSize;
76

87
import javax.persistence.*;
@@ -13,6 +12,7 @@
1312
@JsonIgnoreProperties({"group", "privilege", "subjectType", "program", "programEncounterType", "encounterType", "checklistDetail"})
1413
@BatchSize(size = 100)
1514
public class GroupPrivilege extends OrganisationAwareEntity {
15+
public static final int IMPL_VERSION = 1;
1616

1717
@NotNull
1818
@ManyToOne(fetch = FetchType.LAZY)
@@ -46,6 +46,9 @@ public class GroupPrivilege extends OrganisationAwareEntity {
4646

4747
private boolean allow;
4848

49+
@Column
50+
private int implVersion;
51+
4952
public Group getGroup() {
5053
return group;
5154
}
@@ -207,4 +210,12 @@ public String toString() {
207210
", allow=" + allow +
208211
'}';
209212
}
213+
214+
public int getImplVersion() {
215+
return implVersion;
216+
}
217+
218+
public void setImplVersion(int implVersion) {
219+
this.implVersion = implVersion;
220+
}
210221
}

avni-server-api/src/main/java/org/avni/server/service/OrganisationService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.avni.server.dao.program.SubjectProgramEligibilityRepository;
2222
import org.avni.server.dao.task.TaskRepository;
2323
import org.avni.server.domain.*;
24+
import org.avni.server.domain.accessControl.GroupPrivilege;
2425
import org.avni.server.framework.security.UserContextHolder;
2526
import org.avni.server.importer.batch.model.BundleFolder;
2627
import org.avni.server.service.application.MenuItemService;
@@ -366,6 +367,7 @@ public void addGroupsJson(ZipOutputStream zos) throws IOException {
366367
public void addGroupPrivilegeJson(ZipOutputStream zos) throws IOException {
367368
List<GroupPrivilegeContractWeb> groupPrivileges = groupPrivilegeRepository.findAll().stream()
368369
.filter(groupPrivilege -> !groupPrivilege.getGroup().isAdministrator())
370+
.filter(groupPrivilege -> groupPrivilege.getImplVersion() == GroupPrivilege.IMPL_VERSION)
369371
.map(GroupPrivilegeContractWeb::fromEntity).collect(Collectors.toList());
370372
if (!groupPrivileges.isEmpty()) {
371373
addFileToZip(zos, "groupPrivilege.json", groupPrivileges);

avni-server-api/src/main/java/org/avni/server/service/accessControl/GroupPrivilegeService.java

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.util.ArrayList;
2222
import java.util.Arrays;
2323
import java.util.List;
24+
import java.util.Objects;
25+
import java.util.stream.Collectors;
2426

2527
@Service
2628
public class GroupPrivilegeService implements NonScopeAwareService {
@@ -174,7 +176,9 @@ public List<GroupPrivilege> getAllGroupPrivileges(long groupId) {
174176
}
175177

176178
public void savePrivileges(GroupPrivilegeContractWeb[] requests, Organisation organisation) {
177-
List<GroupPrivilege> groupPrivileges = groupPrivilegeRepository.findAll();
179+
List<GroupPrivilege> groupPrivileges = groupPrivilegeRepository.findAll()
180+
.stream().filter(groupPrivilege -> groupPrivilege.getImplVersion() == GroupPrivilege.IMPL_VERSION)
181+
.collect(Collectors.toList());
178182
List<Privilege> privileges = privilegeRepository.findAll();
179183
List<SubjectType> subjectTypes = subjectTypeRepository.findAll();
180184
List<Program> programs = programRepository.findAll();
@@ -183,21 +187,30 @@ public void savePrivileges(GroupPrivilegeContractWeb[] requests, Organisation or
183187
List<Group> groups = groupRepository.findAll();
184188

185189
Arrays.stream(requests).forEach(request -> {
186-
GroupPrivilege groupPrivilege = CollectionUtil.findByUuid(groupPrivileges, request.getUuid());
190+
GroupPrivilege groupPrivilege = groupPrivileges.stream().filter(gp ->
191+
Objects.equals(request.getGroupUUID(), gp.getGroupUuid())
192+
&& Objects.equals(request.getPrivilegeUUID(), gp.getPrivilegeUuid())
193+
&& Objects.equals(request.getSubjectTypeUUID(), gp.getSubjectTypeUuid())
194+
&& Objects.equals(request.getProgramUUID(), gp.getProgramUuid())
195+
&& Objects.equals(request.getProgramEncounterTypeUUID(), gp.getProgramEncounterTypeUuid())
196+
&& Objects.equals(request.getEncounterTypeUUID(), gp.getEncounterTypeUuid())
197+
&& Objects.equals(request.getChecklistDetailUUID(), gp.getChecklistDetailUuid()))
198+
.findAny().orElse(null);
187199
if (groupPrivilege == null) {
188200
groupPrivilege = new GroupPrivilege();
189-
groupPrivilege.setUuid(request.getUuid());
201+
//don't use uuid from request for bundle uploads since there could be records with matching uuid with older impl_version in db and unique org_uuid constraint is violated
202+
groupPrivilege.assignUUID();
203+
groupPrivilege.setPrivilege(CollectionUtil.findByUuid(privileges, request.getPrivilegeUUID()));
204+
groupPrivilege.setSubjectType(CollectionUtil.findByUuid(subjectTypes, request.getSubjectTypeUUID()));
205+
groupPrivilege.setProgram(CollectionUtil.findByUuid(programs, request.getProgramUUID()));
206+
groupPrivilege.setEncounterType(CollectionUtil.findByUuid(encounterTypes, request.getEncounterTypeUUID()));
207+
groupPrivilege.setProgramEncounterType(CollectionUtil.findByUuid(encounterTypes, request.getProgramEncounterTypeUUID()));
208+
groupPrivilege.setChecklistDetail(CollectionUtil.findByUuid(checklistDetails, request.getChecklistDetailUUID()));
209+
groupPrivilege.setGroup(getGroup(request, organisation, groups));
190210
}
191-
groupPrivilege.setPrivilege(CollectionUtil.findByUuid(privileges, request.getPrivilegeUUID()));
192-
groupPrivilege.setSubjectType(CollectionUtil.findByUuid(subjectTypes, request.getSubjectTypeUUID()));
193-
groupPrivilege.setProgram(CollectionUtil.findByUuid(programs, request.getProgramUUID()));
194-
groupPrivilege.setEncounterType(CollectionUtil.findByUuid(encounterTypes, request.getEncounterTypeUUID()));
195-
groupPrivilege.setProgramEncounterType(CollectionUtil.findByUuid(encounterTypes, request.getProgramEncounterTypeUUID()));
196-
groupPrivilege.setChecklistDetail(CollectionUtil.findByUuid(checklistDetails, request.getChecklistDetailUUID()));
197-
198-
groupPrivilege.setGroup(getGroup(request, organisation, groups));
211+
199212
groupPrivilege.setAllow(request.isAllow());
200-
groupPrivilegeRepository.save(groupPrivilege);
213+
groupPrivilegeRepository.saveGroupPrivilege(groupPrivilege);
201214
});
202215
}
203216

avni-server-api/src/main/java/org/avni/server/web/GroupPrivilegeController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public GroupPrivilegeController(GroupPrivilegeRepository groupPrivilegeRepositor
4646
@RequestMapping(value = "/groups/{id}/privileges", method = RequestMethod.GET)
4747
public List<GroupPrivilegeContract> getById(@PathVariable("id") Long id) {
4848
List<GroupPrivilege> allPossibleGroupPrivileges = groupPrivilegeService.getAllGroupPrivileges(id);
49-
List<GroupPrivilege> groupPrivileges = groupPrivilegeRepository.findByGroup_Id(id);
49+
List<GroupPrivilege> groupPrivileges = groupPrivilegeRepository.findByGroup_IdAndImplVersion(id, GroupPrivilege.IMPL_VERSION);
5050
groupPrivileges.addAll(allPossibleGroupPrivileges);
5151
return groupPrivileges.stream()
5252
.map(GroupPrivilegeContract::fromEntity)
@@ -61,6 +61,7 @@ public ResponseEntity addOrUpdateGroupPrivileges(@RequestBody List<GroupPrivileg
6161
List<GroupPrivilege> privilegesToBeAddedOrUpdated = new ArrayList<>();
6262

6363
for (GroupPrivilegeWebRequest groupPrivilegeRequest : request) {
64+
//continue to rely on uuid here since privilege list on webapp will either be new records or valid impl_version existing record for the same org
6465
GroupPrivilege groupPrivilege = groupPrivilegeRepository.findByUuid(groupPrivilegeRequest.getUuid());
6566
if (groupPrivilege != null) {
6667
groupPrivilege.setAllow(groupPrivilegeRequest.isAllow());
@@ -91,6 +92,6 @@ public ResponseEntity addOrUpdateGroupPrivileges(@RequestBody List<GroupPrivileg
9192
}
9293
}
9394

94-
return ResponseEntity.ok(groupPrivilegeRepository.saveAll(privilegesToBeAddedOrUpdated));
95+
return ResponseEntity.ok(groupPrivilegeRepository.saveAllGroupPrivileges(privilegesToBeAddedOrUpdated));
9596
}
9697
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
alter table group_privilege add column if not exists impl_version int not null default 1;
2+
3+
update group_privilege
4+
set impl_version = 0
5+
where is_voided = true;
6+
7+
create or replace function check_group_privilege_uniqueness(groupPrivilegeId int, groupId int, privilegeId int, subjectTypeId int, programId int, programEncounterTypeId int, encounterTypeId int, checklistDetailId int, implVersion int) returns boolean
8+
language plpgsql
9+
as
10+
$$
11+
declare
12+
begin
13+
if exists (select gp.*
14+
from public.group_privilege gp
15+
where gp.group_id = groupId
16+
and gp.privilege_id = privilegeId
17+
and (gp.subject_type_id = subjectTypeId or (gp.subject_type_id is null and subjectTypeId is null))
18+
and (gp.program_id = programId or (gp.program_id is null and programId is null))
19+
and (gp.program_encounter_type_id = programEncounterTypeId or (gp.program_encounter_type_id is null and programEncounterTypeId is null))
20+
and (gp.encounter_type_id = encounterTypeId or (gp.encounter_type_id is null and encounterTypeId is null))
21+
and (gp.checklist_detail_id = checklistDetailId or (gp.checklist_detail_id is null and checklistDetailId is null))
22+
and gp.id <> groupPrivilegeId
23+
and gp.impl_version = 1
24+
and implVersion = 1
25+
) then
26+
raise 'Duplicate group privilege exists for: id: %, group_id: %, privilege_id: % subject_type_id: %, program_id: %, program_encounter_type_id: %, encounter_type_id: %, checklist_detail_id: %', groupPrivilegeId, groupId, privilegeId, subjectTypeId, programId, programEncounterTypeId, encounterTypeId, checklistDetailId;
27+
end if;
28+
29+
return true;
30+
end
31+
$$;
32+
33+
alter table group_privilege
34+
add constraint check_group_privilege_unique
35+
check (check_group_privilege_uniqueness(id, group_id, privilege_id, subject_type_id, program_id, program_encounter_type_id, encounter_type_id, checklist_detail_id, impl_version));

avni-server-api/src/test/java/org/avni/server/service/builder/TestGroupService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ private void givePrivilege(Group group, GroupPrivilege groupPrivilege, Privilege
3939
Privilege p = privilegeRepository.findByType(privilegeType);
4040
groupPrivilege.setPrivilege(p);
4141
groupPrivilege.setGroup(group);
42-
groupPrivilegeRepository.save(groupPrivilege);
42+
groupPrivilegeRepository.saveGroupPrivilege(groupPrivilege);
4343
}
4444

4545
public void giveViewSubjectPrivilegeTo(Group group, SubjectType ... subjectTypes) {

0 commit comments

Comments
 (0)