Skip to content
This repository was archived by the owner on Oct 6, 2023. It is now read-only.

Commit 55222ba

Browse files
author
sowerstl
committed
Enhance Roles with granular Admin roles and multiple Sites; (DOECODE-798)
1 parent 4843cd1 commit 55222ba

File tree

7 files changed

+262
-79
lines changed

7 files changed

+262
-79
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
*/
3+
package gov.osti.entity;
4+
5+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
6+
import java.io.Serializable;
7+
import java.util.Objects;
8+
import java.util.List;
9+
import java.util.ArrayList;
10+
import javax.persistence.EntityManager;
11+
import gov.osti.listeners.DoeServletContextListener;
12+
import javax.persistence.TypedQuery;
13+
14+
/**
15+
* A Generic Identifier for role; includes Admin and Standard roles.
16+
*
17+
* @author sowerst
18+
*/
19+
@JsonIgnoreProperties ( ignoreUnknown = true )
20+
public class UserRole implements Serializable {
21+
private static final long serialVersionUID = 1L;
22+
23+
/**
24+
* Enumeration of valid Admin Roles for a Role.
25+
*/
26+
public static enum RoleType {
27+
ADMIN, STANDARD;
28+
}
29+
30+
private String value;
31+
private String label;
32+
private String description;
33+
34+
public UserRole() {
35+
36+
}
37+
38+
public UserRole(String value, String label, String description) {
39+
this.setValue(value);
40+
this.setLabel(label);
41+
this.setDescription(description);
42+
}
43+
44+
/**
45+
* @return the value
46+
*/
47+
public String getValue() {
48+
return value;
49+
}
50+
51+
/**
52+
* @param value the value to set
53+
*/
54+
public void setValue(String value) {
55+
this.value = value;
56+
}
57+
58+
/**
59+
* @return the value
60+
*/
61+
public String getLabel() {
62+
return label;
63+
}
64+
65+
/**
66+
* @param value the value to set
67+
*/
68+
public void setLabel(String value) {
69+
this.label = value;
70+
}
71+
72+
/**
73+
* @return the value
74+
*/
75+
public String getDescription() {
76+
return description;
77+
}
78+
79+
/**
80+
* @param value the value to set
81+
*/
82+
public void setDescription(String value) {
83+
this.description = value;
84+
}
85+
86+
public static List<UserRole> GetRoles(RoleType roleType) {
87+
List<UserRole> roles = new ArrayList<>();
88+
if (RoleType.ADMIN.equals(roleType)) {
89+
roles.add(new UserRole("RecordAdmin", "Record Admin", "Permission to edit any project, regardless of Site affiliation."));
90+
roles.add(new UserRole("SiteAdmin", "Site Admin", "Permission to edit any Site and POC notifications."));
91+
roles.add(new UserRole("UserAdmin", "User Admin", "Permission to edit any User information and Role associations."));
92+
roles.add(new UserRole("ApprovalAdmin", "Approval Admin", "Permission to approve any project for biblio indexing."));
93+
roles.add(new UserRole("ContentAdmin", "Content Admin", "Permission to access content controls, such as Refresh, Reindex, etc."));
94+
}
95+
else if (RoleType.STANDARD.equals(roleType)) {
96+
EntityManager em = DoeServletContextListener.createEntityManager();
97+
try {
98+
// get ALL SITES
99+
TypedQuery<Site> query = em.createNamedQuery("Site.findAll", Site.class);
100+
List<Site> siteList = query.getResultList();
101+
102+
for (Site site:siteList) {
103+
String code = site.getSiteCode();
104+
String lab = site.getLab();
105+
roles.add(new UserRole(code, code, lab));
106+
}
107+
} finally {
108+
em.close();
109+
}
110+
}
111+
112+
return roles;
113+
}
114+
115+
public static List<String> GetRoleList(RoleType roleType) {
116+
List<String> roles = new ArrayList<>();
117+
if (RoleType.ADMIN.equals(roleType)) {
118+
roles.add("RecordAdmin");
119+
roles.add("SiteAdmin");
120+
roles.add("UserAdmin");
121+
roles.add("ApprovalAdmin");
122+
roles.add("ContentAdmin");
123+
}
124+
else if (RoleType.STANDARD.equals(roleType)) {
125+
EntityManager em = DoeServletContextListener.createEntityManager();
126+
try {
127+
// get ALL SITES
128+
TypedQuery<Site> query = em.createNamedQuery("Site.findAll", Site.class);
129+
List<Site> siteList = query.getResultList();
130+
131+
for (Site site:siteList) {
132+
roles.add(site.getSiteCode());
133+
}
134+
} finally {
135+
em.close();
136+
}
137+
}
138+
139+
return roles;
140+
}
141+
142+
@Override
143+
public boolean equals(Object o) {
144+
if (o instanceof UserRole ) {
145+
return ((UserRole)o).getValue().equals(getValue());
146+
}
147+
148+
return false;
149+
}
150+
151+
@Override
152+
public int hashCode() {
153+
int hash = 7;
154+
hash = 83 * hash + Objects.hashCode(this.value);
155+
return hash;
156+
}
157+
158+
}

src/main/java/gov/osti/services/Authentication.java

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/main/java/gov/osti/services/CodeGov.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public Response listCodeGovData()
231231
@Path("/listrecords")
232232
@Produces(MediaType.APPLICATION_JSON)
233233
@RequiresAuthentication
234-
@RequiresRoles("OSTI")
234+
@RequiresRoles("ContentAdmin")
235235
public Response listApprovedSnapshots()
236236
throws JsonProcessingException {
237237
EntityManager em = DoeServletContextListener.createEntityManager();

src/main/java/gov/osti/services/Metadata.java

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import gov.osti.entity.Site;
3636
import gov.osti.entity.SponsoringOrganization;
3737
import gov.osti.entity.User;
38+
import gov.osti.entity.UserRole;
39+
import gov.osti.entity.UserRole.RoleType;
3840
import gov.osti.indexer.AgentSerializer;
3941
import gov.osti.listeners.DoeServletContextListener;
4042
import java.io.File;
@@ -304,7 +306,7 @@ public Response reserveDoi() throws IOException {
304306
* to succeeding.
305307
*
306308
* Ownership is defined as: owner and user email match, OR user's roles
307-
* include the SITE OWNERSHIP CODE of the record, OR user has the "OSTI"
309+
* include the SITE OWNERSHIP CODE of the record, OR user has the "RecordAdmin"
308310
* special administrative role.
309311
* Result Codes:
310312
* 200 - OK, with JSON containing the metadata information
@@ -343,7 +345,7 @@ public Response getSingleRecord(@PathParam("codeId") Long codeId, @QueryParam("f
343345

344346
// do you have permissions to get this?
345347
if ( !user.getEmail().equals(md.getOwner()) &&
346-
!user.hasRole("OSTI") &&
348+
!user.hasRole("RecordAdmin") &&
347349
!user.hasRole(md.getSiteOwnershipCode()))
348350
return ErrorResponse
349351
.forbidden("Permission denied.")
@@ -478,20 +480,22 @@ public Response listProjects(
478480

479481
try {
480482
Set<String> roles = user.getRoles();
481-
String rolecode = (null==roles) ? "" :
482-
(roles.isEmpty()) ? "" : roles.iterator().next();
483+
484+
List<String> allowedSites = UserRole.GetRoleList(RoleType.STANDARD);
485+
allowedSites.retainAll(roles);
483486

484487
TypedQuery<DOECodeMetadata> query;
485488
// admins see ALL PROJECTS
486-
if ("OSTI".equals(rolecode)) {
489+
if (roles.contains("RecordAdmin")) {
487490
query = em.createQuery("SELECT md FROM DOECodeMetadata md", DOECodeMetadata.class);
488-
} else if (StringUtils.isNotEmpty(rolecode)) {
489-
// if you have another ROLE, it is assumed to be a SITE ADMIN; see all those records
490-
query = em.createQuery("SELECT md FROM DOECodeMetadata md WHERE md.siteOwnershipCode = :site", DOECodeMetadata.class)
491-
.setParameter("site", rolecode);
491+
} else if (!allowedSites.isEmpty()) {
492+
// if you have any allowed site ROLE, it is assumed to be a SITE ADMIN; see all those records plus their own
493+
query = em.createQuery("SELECT md FROM DOECodeMetadata md WHERE md.owner = :owner OR md.siteOwnershipCode IN :site", DOECodeMetadata.class)
494+
.setParameter("owner", user.getEmail())
495+
.setParameter("site", allowedSites);
492496
} else {
493497
// no roles, you see only YOUR OWN projects
494-
query = em.createQuery("SELECT md FROM DOECodeMetadata md WHERE md.owner = lower(:owner)", DOECodeMetadata.class)
498+
query = em.createQuery("SELECT md FROM DOECodeMetadata md WHERE md.owner = :owner", DOECodeMetadata.class)
495499
.setParameter("owner", user.getEmail());
496500
}
497501

@@ -597,7 +601,7 @@ public Response listProjects(
597601
@Consumes (MediaType.APPLICATION_JSON)
598602
@Produces (MediaType.APPLICATION_JSON)
599603
@RequiresAuthentication
600-
@RequiresRoles("OSTI")
604+
@RequiresRoles("ApprovalAdmin")
601605
public Response listProjectsPending(@QueryParam("start") int start,
602606
@QueryParam("rows") int rows,
603607
@QueryParam("site") String siteCode,
@@ -765,7 +769,7 @@ private void store(EntityManager em, DOECodeMetadata md, User user) throws NotFo
765769

766770
// must be OSTI user in order to add/update PROJECT KEYWORDS
767771
List<String> projectKeywords = md.getProjectKeywords();
768-
if (projectKeywords != null && !projectKeywords.isEmpty() && !user.hasRole("OSTI"))
772+
if (projectKeywords != null && !projectKeywords.isEmpty() && !user.hasRole("RecordAdmin"))
769773
throw new ValidationException("Project Keywords can only be set by authorized users.");
770774

771775
// if there's a CODE ID, attempt to look up the record first and
@@ -789,7 +793,7 @@ private void store(EntityManager em, DOECodeMetadata md, User user) throws NotFo
789793
// must be the OWNER, SITE ADMIN, or OSTI in order to UPDATE
790794
if (!user.getEmail().equals(emd.getOwner()) &&
791795
!user.hasRole(emd.getSiteOwnershipCode()) &&
792-
!user.hasRole("OSTI"))
796+
!user.hasRole("RecordAdmin"))
793797
throw new IllegalAccessException("Invalid access attempt.");
794798

795799
// to Save, item must be non-existant, or already in Saved workflow status (if here, we know it exists)
@@ -1992,7 +1996,7 @@ public Response save(@FormDataParam("metadata") String metadata,
19921996
@Produces (MediaType.APPLICATION_JSON)
19931997
@Path ("/reindex")
19941998
@RequiresAuthentication
1995-
@RequiresRoles ("OSTI")
1999+
@RequiresRoles ("ContentAdmin")
19962000
public Response reindex() throws IOException {
19972001
EntityManager em = DoeServletContextListener.createEntityManager();
19982002

@@ -2022,7 +2026,7 @@ public Response reindex() throws IOException {
20222026
@Produces(MediaType.APPLICATION_JSON)
20232027
@Path("/refresh")
20242028
@RequiresAuthentication
2025-
@RequiresRoles("OSTI")
2029+
@RequiresRoles("ContentAdmin")
20262030
public Response refresh() throws Exception {
20272031
try {
20282032
DoeServletContextListener.refreshCaches();
@@ -2054,7 +2058,7 @@ public Response refresh() throws Exception {
20542058
@Path ("/approve/{codeId}")
20552059
@Produces (MediaType.APPLICATION_JSON)
20562060
@RequiresAuthentication
2057-
@RequiresRoles("OSTI")
2061+
@RequiresRoles("ApprovalAdmin")
20582062
public Response approve(@PathParam("codeId") Long codeId) {
20592063
EntityManager em = DoeServletContextListener.createEntityManager();
20602064
Subject subject = SecurityUtils.getSubject();

src/main/java/gov/osti/services/SiteServices.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public SiteServices() {
5858
*/
5959
@GET
6060
@RequiresAuthentication
61-
@RequiresRoles("OSTI")
61+
@RequiresRoles("SiteAdmin")
6262
@Consumes({MediaType.TEXT_HTML, MediaType.APPLICATION_JSON})
6363
@Produces(MediaType.APPLICATION_JSON)
6464
@Path("/info")
@@ -98,7 +98,7 @@ public Response getAllSiteInfo() {
9898
*/
9999
@GET
100100
@RequiresAuthentication
101-
@RequiresRoles("OSTI")
101+
@RequiresRoles("SiteAdmin")
102102
@Consumes({MediaType.TEXT_HTML, MediaType.APPLICATION_JSON})
103103
@Produces(MediaType.APPLICATION_JSON)
104104
@Path("/info/{site}")
@@ -149,7 +149,7 @@ public Response getSpecificSiteInfo(@PathParam("site") String siteCode) {
149149
*/
150150
@POST
151151
@RequiresAuthentication
152-
@RequiresRoles("OSTI")
152+
@RequiresRoles("SiteAdmin")
153153
@Produces(MediaType.APPLICATION_JSON)
154154
@Consumes(MediaType.APPLICATION_JSON)
155155
@Path("/update")

0 commit comments

Comments
 (0)