-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
163 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
...th-services/src/main/java/edu/harvard/hms/dbmi/avillach/auth/rest/StudyAccessService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package edu.harvard.hms.dbmi.avillach.auth.rest; | ||
|
||
import edu.harvard.hms.dbmi.avillach.auth.data.entity.Role; | ||
import edu.harvard.hms.dbmi.avillach.auth.data.repository.RoleRepository; | ||
import edu.harvard.hms.dbmi.avillach.auth.service.auth.FENCEAuthenticationService; | ||
import io.swagger.annotations.Api; | ||
import io.swagger.annotations.ApiOperation; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import javax.annotation.security.RolesAllowed; | ||
import javax.inject.Inject; | ||
import javax.transaction.Transactional; | ||
import javax.ws.rs.Consumes; | ||
import javax.ws.rs.POST; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.core.MediaType; | ||
import javax.ws.rs.core.Response; | ||
|
||
import java.util.Map; | ||
|
||
import static edu.harvard.hms.dbmi.avillach.auth.utils.AuthNaming.AuthRoleNaming.SUPER_ADMIN; | ||
|
||
/** | ||
* <p>Endpoint for service handling business logic for adding all the auth | ||
* rules for a given study</p> | ||
* <p>Note: Only users with the super admin role can access this endpoint.</p> | ||
*/ | ||
@Api | ||
@Path("/studyAccess") | ||
public class StudyAccessService { | ||
Logger logger = LoggerFactory.getLogger(StudyAccessService.class); | ||
|
||
public static final String MANUAL = "MANUAL_"; | ||
public static final String STUDY_IDENTIFIER = "study_identifier"; | ||
public static final String CONSENT_GROUP_CODE = "consent_group_code"; | ||
|
||
@Inject | ||
FENCEAuthenticationService fenceAuthenticationService; | ||
|
||
@ApiOperation(value = "POST a single study and it creates the role, privs, and rules for it, requires SUPER_ADMIN role") | ||
@Transactional | ||
@POST | ||
@RolesAllowed(SUPER_ADMIN) | ||
@Consumes(MediaType.APPLICATION_JSON) | ||
@Path("/") | ||
public Response addStudyAccess(String studyIdentifier) { | ||
if (StringUtils.isBlank(studyIdentifier)) { | ||
return Response.status(Response.Status.BAD_REQUEST) | ||
.entity("Study identifier cannot be blank") | ||
.build(); | ||
} | ||
Map fenceMappingForStudy = null; | ||
try { | ||
Map<String, Map> fenceMapping = fenceAuthenticationService.getFENCEMapping(); | ||
if (fenceMapping == null) { | ||
throw new Exception("Fence mapping is null"); | ||
} | ||
fenceMappingForStudy = fenceMapping.get(studyIdentifier); | ||
} catch(Exception ex) { | ||
logger.error(ex.toString()); | ||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR) | ||
.entity("Error occurred while fetching FENCE mapping") | ||
.build(); | ||
} | ||
if (fenceMappingForStudy == null || fenceMappingForStudy.isEmpty()) { | ||
logger.error("addStudyAccess - Could not find study: " + studyIdentifier + " in FENCE mapping"); | ||
return Response.status(Response.Status.NOT_FOUND) | ||
.entity("Could not find study with the provided identifier") | ||
.build(); | ||
} | ||
String projectId = (String) fenceMappingForStudy.get(STUDY_IDENTIFIER); | ||
String consentCode = (String) fenceMappingForStudy.get(CONSENT_GROUP_CODE); | ||
String newRoleName = StringUtils.isNotBlank(consentCode) ? MANUAL+projectId+"_"+consentCode : MANUAL+projectId; | ||
|
||
logger.debug("addStudyAccess - New manual PSAMA role name: "+newRoleName); | ||
|
||
if (fenceAuthenticationService.upsertRole(null, newRoleName, MANUAL + " role "+newRoleName)) { | ||
logger.info("addStudyAccess - Updated user role. Now it includes `"+newRoleName+"`"); | ||
return Response.ok("Role '" + newRoleName + "' successfully created").build(); | ||
} else { | ||
logger.error("addStudyAccess - could not add " + newRoleName + " role to to database"); | ||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR) | ||
.entity("Could not add role '" + newRoleName + "' to database") | ||
.build(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
...ure-auth-services/src/test/java/edu/harvard/hms/dbmi/avillach/StudyAccessServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package edu.harvard.hms.dbmi.avillach; | ||
|
||
import edu.harvard.hms.dbmi.avillach.auth.data.repository.RoleRepository; | ||
import edu.harvard.hms.dbmi.avillach.auth.rest.StudyAccessService; | ||
import edu.harvard.hms.dbmi.avillach.auth.service.auth.FENCEAuthenticationService; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.mockito.Mockito; | ||
import org.mockito.MockitoAnnotations; | ||
|
||
import javax.ws.rs.core.Response; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.mockito.Mockito.*; | ||
|
||
public class StudyAccessServiceTest { | ||
|
||
@InjectMocks | ||
private StudyAccessService studyAccessService; | ||
|
||
@Mock | ||
private FENCEAuthenticationService fenceAuthenticationService; | ||
|
||
@Before | ||
public void init() { | ||
MockitoAnnotations.initMocks(this); | ||
} | ||
|
||
|
||
@Test | ||
public void testAddStudyAccessWithBlankIdentifier() { | ||
String studyIdentifier = ""; | ||
Response response = studyAccessService.addStudyAccess(studyIdentifier); | ||
assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); | ||
assertEquals("Study identifier cannot be blank", response.getEntity()); | ||
} | ||
|
||
@Test | ||
public void testAddStudyAccess() { | ||
String studyIdentifier = "testStudy"; | ||
when(fenceAuthenticationService.getFENCEMapping()).thenReturn(Map.of(studyIdentifier, Map.of(StudyAccessService.STUDY_IDENTIFIER, studyIdentifier,StudyAccessService.CONSENT_GROUP_CODE, ""))); | ||
when(fenceAuthenticationService.upsertRole(null, "MANUAL_testStudy", "MANUAL_ role MANUAL_testStudy")).thenReturn(true); | ||
|
||
Response response = studyAccessService.addStudyAccess(studyIdentifier); | ||
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); | ||
assertEquals("Role 'MANUAL_testStudy' successfully created", response.getEntity()); | ||
} | ||
|
||
@Test | ||
public void testAddStudyAccessWithConsent() { | ||
String studyIdentifier = "testStudy2.c2"; | ||
when(fenceAuthenticationService.getFENCEMapping()).thenReturn(Map.of(studyIdentifier, Map.of(StudyAccessService.STUDY_IDENTIFIER, "testStudy2", StudyAccessService.CONSENT_GROUP_CODE, "c2"))); | ||
when(fenceAuthenticationService.upsertRole(null, "MANUAL_testStudy2_c2", "MANUAL_ role MANUAL_testStudy2_c2")).thenReturn(true); | ||
Response response = studyAccessService.addStudyAccess(studyIdentifier); | ||
|
||
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); | ||
assertEquals("Role 'MANUAL_testStudy2_c2' successfully created", response.getEntity()); | ||
} | ||
} |