Skip to content

Commit

Permalink
Merge pull request #1879 from youennmerel/fli-iam#1859
Browse files Browse the repository at this point in the history
[#1859] Add an API to fetch subject names by ids
  • Loading branch information
jcomedouteau authored Oct 25, 2023
2 parents e19b640 + d65a60a commit d1c67e2
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 24 deletions.
6 changes: 5 additions & 1 deletion shanoir-ng-front/src/app/datasets/shared/dataset.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,12 @@ export class DatasetDTOService {
*/
public toEntityList(dtos: DatasetDTO[], result?: Dataset[], mode: 'eager' | 'lazy' = 'eager'): Promise<Dataset[]>{
if (!result) result = [];
let subjectIds = new Set<number>;
if (dtos) {
for (let dto of dtos ? dtos : []) {
if (dto.subjectId) {
subjectIds.add(dto.subjectId);
}
let entity = DatasetUtils.getDatasetInstance(dto.type);
DatasetDTOService.mapSyncFields(dto, entity);
result.push(entity);
Expand All @@ -94,7 +98,7 @@ export class DatasetDTOService {
entity.study.name = studies.find(study => study.id == entity.study.id)?.name;
}
}),
this.subjectService.getSubjectsNames().then(subjects => {
this.subjectService.getSubjectsNames(subjectIds).then(subjects => {
for (let entity of result) {
if (entity.subject)
entity.subject.name = subjects.find(subject => subject.id == entity.subject.id)?.name;
Expand Down
10 changes: 5 additions & 5 deletions shanoir-ng-front/src/app/studies/study/study.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export class StudyComponent extends EntityComponent<Study> {

return study;
});
this.getSubjects();
this.getAllSubjects();

this.protocolFiles = [];

Expand Down Expand Up @@ -211,7 +211,7 @@ export class StudyComponent extends EntityComponent<Study> {
this.selectedCenter = null;
this.protocolFiles = [];
this.dataUserAgreement = null;
this.getSubjects();
this.getAllSubjects();

this.fetchUsers().then(users => {
// Add the connected user by default
Expand Down Expand Up @@ -346,14 +346,14 @@ export class StudyComponent extends EntityComponent<Study> {
});
}

private getSubjects(): void {
private getAllSubjects(): void {
this.subjectService
.getSubjectsNames()
.getAllSubjectsNames()
.then(subjects => {
this.subjects = subjects?.sort(function(a:Subject, b:Subject){
return a.name.localeCompare(b.name);
});
});
});
}

/** Center section management **/
Expand Down
11 changes: 10 additions & 1 deletion shanoir-ng-front/src/app/subjects/shared/subject.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { SubjectDTO, SubjectDTOService } from './subject.dto';
import { SubjectStudyDTO } from './subject-study.dto';
import { Page, Pageable } from 'src/app/shared/components/table/pageable.model';
import {BACKEND_API_SUBJECT_URL} from "../../utils/app.utils";
import {Dataset} from "../../datasets/shared/dataset.model";
import {DatasetDTO} from "../../datasets/shared/dataset.dto";

@Injectable()
export class SubjectService extends EntityService<Subject> {
Expand All @@ -36,8 +38,15 @@ export class SubjectService extends EntityService<Subject> {

getEntityInstance() { return new Subject(); }

getSubjectsNames(): Promise<IdName[]> {
getAllSubjectsNames(): Promise<IdName[]> {
return this.http.get<IdName[]>(AppUtils.BACKEND_API_SUBJECT_NAMES_URL)
.toPromise();
}

getSubjectsNames(subjectIds: Set<number>): Promise<IdName[]> {
const formData: FormData = new FormData();
formData.set('subjectIds', Array.from(subjectIds).join(","));
return this.http.post<IdName[]>(AppUtils.BACKEND_API_SUBJECT_NAMES_URL, formData)
.toPromise();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,18 @@ ResponseEntity<List<SubjectDTO>> findSubjects(
@ApiResponse(responseCode = "500", description = "unexpected error") })
@GetMapping(value = "/names", produces = { "application/json" })
@PreAuthorize("hasAnyRole('ADMIN', 'EXPERT', 'USER')")
ResponseEntity<List<IdName>> findSubjectsNames();
ResponseEntity<List<IdName>> findAllSubjectsNames();

@Operation(summary = "", description = "Returns id and name for the given subject ids")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "found subjects"),
@ApiResponse(responseCode = "204", description = "no subject found"),
@ApiResponse(responseCode = "401", description = "unauthorized"),
@ApiResponse(responseCode = "403", description = "forbidden"),
@ApiResponse(responseCode = "500", description = "unexpected error") })
@PostMapping(value = "/names", produces = { "application/json" })
@PreAuthorize("hasAnyRole('ADMIN', 'EXPERT', 'USER')")
ResponseEntity<List<IdName>> findSubjectsNames(@RequestParam(value = "subjectIds", required = true) List<Long> subjectIds);

@Operation(summary = "", description = "If exists, returns the subject corresponding to the given id")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "found bubject"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,17 @@ public ResponseEntity<List<SubjectDTO>> findSubjects(boolean preclinical, boolea
}

@Override
public ResponseEntity<List<IdName>> findSubjectsNames() {
final List<IdName> subjectsNames = subjectService.findNames();
public ResponseEntity<List<IdName>> findAllSubjectsNames() {
final List<IdName> subjectsNames = subjectService.findAllNames();
if (subjectsNames.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(subjectsNames, HttpStatus.OK);
}

@Override
public ResponseEntity<List<IdName>> findSubjectsNames(List<Long> subjectIds) {
final List<IdName> subjectsNames = subjectService.findNames(subjectIds);
if (subjectsNames.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ public interface SubjectRepository extends CrudRepository<Subject, Long>, Subjec
*/
Iterable<Subject> findBySubjectStudyListStudyIdIn(Iterable<Long> studyIds);

Iterable<Subject> findBySubjectStudyListStudyIdInAndIdIn(Iterable<Long> studyIds, Iterable<Long> ids);

List<Subject> findByPreclinical(boolean preclinical);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ public interface SubjectService {
* @return a list of subjects.
*/
@PreAuthorize("hasAnyRole('ADMIN', 'EXPERT', 'USER')")
List<IdName> findNames();
List<IdName> findAllNames();

@PreAuthorize("hasAnyRole('ADMIN', 'EXPERT', 'USER')")
List<IdName> findNames(List<Long> subjectIds);

/**
* Get all the subjects of a study
Expand Down Expand Up @@ -199,4 +201,5 @@ public interface SubjectService {
List<Subject> findByPreclinical(boolean preclinical);

boolean existsSubjectWithName(String name);

}
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public List<Subject> findAll() {


@Override
public List<IdName> findNames() {
public List<IdName> findAllNames() {
Iterable<Subject> subjects;
if (KeycloakUtil.getTokenRoles().contains("ROLE_ADMIN")) {
subjects = subjectRepository.findAll();
Expand All @@ -138,17 +138,38 @@ public List<IdName> findNames() {
List<Long> studyIds = studyUserRepository.findDistinctStudyIdByUserId(userId, StudyUserRight.CAN_SEE_ALL.getId());
subjects = subjectRepository.findBySubjectStudyListStudyIdIn(studyIds);
}
List<IdName> names = new ArrayList<IdName>();
if (subjects != null) {
for (Subject subject : subjects) {
IdName name = new IdName(subject.getId(), subject.getName());
names.add(name);
}
return getIdNamesFromSubjects(subjects);
}

@Override
public List<IdName> findNames(List<Long> subjectIds) {
Iterable<Subject> subjects;
if (KeycloakUtil.getTokenRoles().contains("ROLE_ADMIN")) {
subjects = subjectRepository.findAllById(subjectIds);
} else {
Long userId = KeycloakUtil.getTokenUserId();
List<Long> studyIds = studyUserRepository.findDistinctStudyIdByUserId(userId, StudyUserRight.CAN_SEE_ALL.getId());
subjects = subjectRepository.findBySubjectStudyListStudyIdInAndIdIn(studyIds, subjectIds);
}
return getIdNamesFromSubjects(subjects);
}


private List<IdName> getIdNamesFromSubjects(Iterable<Subject> subjects) {

if (subjects == null) {
return new ArrayList<>();
}

List<IdName> names = new ArrayList<>();
for (Subject subject : subjects) {
IdName name = new IdName(subject.getId(), subject.getName());
names.add(name);
}
return names;
}

@Override
@Override
public Subject findByData(final String name) {
return subjectRepository.findByName(name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ public void setup() {
public void testAsAnonymous() throws ShanoirException, RestServiceException {
assertAccessDenied(api::deleteSubject, ENTITY_ID);
assertAccessDenied(api::findSubjects, true, true);
assertAccessDenied(api::findSubjectsNames);
assertAccessDenied(api::findAllSubjectsNames);
assertAccessDenied(api::findSubjectsNames, List.of(ENTITY_ID));
assertAccessDenied(api::findSubjectById, ENTITY_ID);
assertAccessDenied(api::saveNewSubject, mockNew, null, mockBindingResult);
assertAccessDenied(api::updateSubject, ENTITY_ID, mockExisting, mockBindingResult);
Expand Down Expand Up @@ -155,7 +156,8 @@ public void testAsExpert() throws ShanoirException, RestServiceException {
public void testAsAdmin() throws ShanoirException, RestServiceException {
assertAccessAuthorized(api::deleteSubject, ENTITY_ID);
assertAccessAuthorized(api::findSubjects, true, true);
assertAccessAuthorized(api::findSubjectsNames);
assertAccessAuthorized(api::findAllSubjectsNames);
assertAccessAuthorized(api::findSubjectsNames, List.of(ENTITY_ID));
assertAccessAuthorized(api::findSubjectById, ENTITY_ID);
assertAccessAuthorized(api::saveNewSubject, mockNew, null, mockBindingResult);
assertAccessAuthorized(api::updateSubject, ENTITY_ID, mockExisting, mockBindingResult);
Expand All @@ -179,7 +181,9 @@ private void testRead() throws ShanoirException {
given(repository.findAll()).willReturn(Arrays.asList(subjectMockNoRights));
assertAccessAuthorized(api::findSubjects,true, true);
assertEquals(null, api.findSubjects(true, true).getBody());
assertAccessAuthorized(api::findSubjectsNames);
assertAccessAuthorized(api::findAllSubjectsNames);
assertAccessAuthorized(api::findSubjectsNames, List.of(ENTITY_ID));

//assertNotNull(api.findSubjectsNames().getBody());
SubjectStudy subjectStudyMock = new SubjectStudy();
subjectStudyMock.setStudy(buildStudyMock(1L));
Expand All @@ -204,7 +208,8 @@ private void testRead() throws ShanoirException {
given(repository.findAll()).willReturn(Arrays.asList(subjectMockWrongRights));
assertAccessAuthorized(api::findSubjects, true, true);
assertEquals(null, api.findSubjects(true, true).getBody());
assertAccessAuthorized(api::findSubjectsNames);
assertAccessAuthorized(api::findAllSubjectsNames);
assertAccessAuthorized(api::findSubjectsNames, List.of(ENTITY_ID));
//assertEquals(null, api.findSubjectsNames().getBody());
subjectStudyMock = new SubjectStudy();
subjectStudyMock.setStudy(buildStudyMock(1L));
Expand All @@ -229,7 +234,8 @@ private void testRead() throws ShanoirException {
given(repository.findAllById(Arrays.asList(1L))).willReturn(Arrays.asList(subjectMockRightRights));
assertAccessAuthorized(api::findSubjects, true, true);
assertEquals(1, api.findSubjects(true, true).getBody().size());
assertAccessAuthorized(api::findSubjectsNames);
assertAccessAuthorized(api::findAllSubjectsNames);
assertAccessAuthorized(api::findSubjectsNames, List.of(ENTITY_ID));
//assertEquals(1, api.findSubjectsNames().getBody().size());
subjectStudyMock = new SubjectStudy();
subjectStudyMock.setStudy(buildStudyMock(1L));
Expand Down

0 comments on commit d1c67e2

Please sign in to comment.