Skip to content

Commit 3114701

Browse files
alex-odysseusjcnamendiOdysseusoleg-odysseuschrisknoll
authored
Tools module functionality (#2389)
- adding permissions to sec_permission, sec_role_permission (migration script) - distinguishing the Tools listing logic for administrators and the other users - replacing PermissionManager usage with UserRepository when appropriate to avoid exceptions when there is no security enabled --------- Co-authored-by: Juan Carlos Namendi Pineda <[email protected]> Co-authored-by: oleg-odysseus <[email protected]> Co-authored-by: Chris Knoll <[email protected]>
1 parent 17cbf89 commit 3114701

File tree

13 files changed

+564
-8
lines changed

13 files changed

+564
-8
lines changed

src/main/java/org/ohdsi/webapi/security/model/EntityType.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.ohdsi.webapi.reusable.domain.Reusable;
1414
import org.ohdsi.webapi.source.Source;
1515
import org.ohdsi.webapi.tag.domain.Tag;
16+
import org.ohdsi.webapi.tool.Tool;
1617

1718
public enum EntityType {
1819
COHORT_DEFINITION(CohortDefinition.class),
@@ -26,6 +27,7 @@ public enum EntityType {
2627
PREDICTION(PredictionAnalysis.class),
2728
COHORT_SAMPLE(CohortSample.class),
2829
TAG(Tag.class),
30+
TOOL(Tool.class),
2931
REUSABLE(Reusable.class);
3032
private final Class<? extends CommonEntity> entityClass;
3133

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.ohdsi.webapi.security.model;
2+
3+
import org.springframework.stereotype.Component;
4+
5+
import java.util.HashMap;
6+
import java.util.Map;
7+
8+
@Component
9+
public class ToolPermissionSchema extends EntityPermissionSchema {
10+
private static Map<String, String> writePermissions = new HashMap<String, String>() {{
11+
put("tool:%s:delete", "Delete Tool with id = %s");
12+
}};
13+
private static Map<String, String> readPermissions = new HashMap<String, String>() {
14+
{
15+
put("tool:%s:get", "View Tool with id = %s");
16+
}
17+
};
18+
19+
public ToolPermissionSchema() {
20+
super(EntityType.TOOL, readPermissions, writePermissions);
21+
}
22+
23+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package org.ohdsi.webapi.tool;
2+
3+
import org.hibernate.annotations.GenericGenerator;
4+
import org.hibernate.annotations.Parameter;
5+
import org.ohdsi.webapi.model.CommonEntity;
6+
7+
import javax.persistence.Entity;
8+
import javax.persistence.Table;
9+
import javax.persistence.Id;
10+
import javax.persistence.GeneratedValue;
11+
import javax.persistence.Column;
12+
import java.util.Objects;
13+
14+
@Entity
15+
@Table(name = "tool")
16+
public class Tool extends CommonEntity<Integer> {
17+
@Id
18+
@GenericGenerator(
19+
name = "tool_generator",
20+
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
21+
parameters = {
22+
@Parameter(name = "sequence_name", value = "tool_seq"),
23+
@Parameter(name = "increment_size", value = "1")
24+
}
25+
)
26+
@GeneratedValue(generator = "tool_generator")
27+
private Integer id;
28+
29+
@Column(name = "name")
30+
private String name;
31+
32+
@Column(name = "url")
33+
private String url;
34+
35+
@Column(name = "description")
36+
private String description;
37+
@Column(name = "is_enabled")
38+
private Boolean enabled;
39+
40+
@Override
41+
public Integer getId() {
42+
return id;
43+
}
44+
45+
public void setId(Integer id) {
46+
this.id = id;
47+
}
48+
49+
public String getName() {
50+
return name;
51+
}
52+
53+
public void setName(String name) {
54+
this.name = name;
55+
}
56+
57+
public String getUrl() {
58+
return url;
59+
}
60+
61+
public void setUrl(String url) {
62+
this.url = url;
63+
}
64+
65+
public String getDescription() {
66+
return description;
67+
}
68+
69+
public void setDescription(String description) {
70+
this.description = description;
71+
}
72+
73+
public Boolean getEnabled() {
74+
return enabled;
75+
}
76+
77+
public void setEnabled(Boolean enabled) {
78+
this.enabled = enabled;
79+
}
80+
81+
@Override
82+
public boolean equals(Object o) {
83+
if (this == o) return true;
84+
if (o == null || getClass() != o.getClass()) return false;
85+
Tool tool = (Tool) o;
86+
return Objects.equals(name, tool.name);
87+
}
88+
89+
@Override
90+
public int hashCode() {
91+
return Objects.hash(name);
92+
}
93+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.ohdsi.webapi.tool;
2+
3+
import org.ohdsi.webapi.tool.dto.ToolDTO;
4+
import org.springframework.stereotype.Controller;
5+
6+
import javax.ws.rs.Consumes;
7+
import javax.ws.rs.DELETE;
8+
import javax.ws.rs.GET;
9+
import javax.ws.rs.POST;
10+
import javax.ws.rs.PUT;
11+
import javax.ws.rs.Path;
12+
import javax.ws.rs.PathParam;
13+
import javax.ws.rs.Produces;
14+
import javax.ws.rs.core.MediaType;
15+
import java.util.List;
16+
17+
@Controller
18+
@Path("/tool")
19+
public class ToolController {
20+
private final ToolServiceImpl service;
21+
22+
public ToolController(ToolServiceImpl service) {
23+
this.service = service;
24+
}
25+
26+
@GET
27+
@Path("")
28+
@Produces(MediaType.APPLICATION_JSON)
29+
public List<ToolDTO> getTools() {
30+
return service.getTools();
31+
}
32+
33+
@GET
34+
@Path("/{id}")
35+
@Produces(MediaType.APPLICATION_JSON)
36+
public ToolDTO getToolById(@PathParam("id") Integer id) {
37+
return service.getById(id);
38+
}
39+
40+
@POST
41+
@Path("")
42+
@Produces(MediaType.APPLICATION_JSON)
43+
@Consumes(MediaType.APPLICATION_JSON)
44+
public ToolDTO createTool(ToolDTO dto) {
45+
return service.saveTool(dto);
46+
}
47+
48+
@DELETE
49+
@Path("/{id}")
50+
@Produces(MediaType.APPLICATION_JSON)
51+
public void delete(@PathParam("id") Integer id) {
52+
service.delete(id);
53+
}
54+
55+
@PUT
56+
@Path("")
57+
@Produces(MediaType.APPLICATION_JSON)
58+
@Consumes(MediaType.APPLICATION_JSON)
59+
public ToolDTO updateTool(ToolDTO toolDTO) {
60+
return service.saveTool(toolDTO);
61+
}
62+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.ohdsi.webapi.tool;
2+
3+
import java.util.List;
4+
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.stereotype.Repository;
7+
8+
@Repository
9+
public interface ToolRepository extends JpaRepository<Tool, Integer> {
10+
List<Tool> findAllByEnabled(boolean enabled);
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.ohdsi.webapi.tool;
2+
3+
import org.ohdsi.webapi.tool.dto.ToolDTO;
4+
5+
import java.util.List;
6+
7+
public interface ToolService {
8+
List<ToolDTO> getTools();
9+
ToolDTO saveTool(ToolDTO toolDTO);
10+
ToolDTO getById(Integer id);
11+
12+
void delete(Integer id);
13+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package org.ohdsi.webapi.tool;
2+
3+
import java.text.SimpleDateFormat;
4+
import java.time.Instant;
5+
import java.util.Date;
6+
import java.util.List;
7+
import java.util.Optional;
8+
import java.util.stream.Collectors;
9+
import java.util.stream.Stream;
10+
11+
import org.apache.shiro.SecurityUtils;
12+
import org.ohdsi.webapi.service.AbstractDaoService;
13+
import org.ohdsi.webapi.shiro.Entities.UserEntity;
14+
import org.ohdsi.webapi.tool.dto.ToolDTO;
15+
import org.springframework.stereotype.Service;
16+
17+
@Service
18+
public class ToolServiceImpl extends AbstractDaoService implements ToolService {
19+
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
20+
21+
private final ToolRepository toolRepository;
22+
23+
public ToolServiceImpl(ToolRepository toolRepository) {
24+
this.toolRepository = toolRepository;
25+
}
26+
27+
@Override
28+
public List<ToolDTO> getTools() {
29+
List<Tool> tools = (isAdmin() || canManageTools()) ? toolRepository.findAll() : toolRepository.findAllByEnabled(true);
30+
return tools.stream()
31+
.map(this::toDTO).collect(Collectors.toList());
32+
}
33+
34+
@Override
35+
public ToolDTO saveTool(ToolDTO toolDTO) {
36+
Tool tool = saveToolFromDTO(toolDTO, getCurrentUser());
37+
return toDTO(toolRepository.saveAndFlush(tool));
38+
}
39+
40+
private Tool saveToolFromDTO(ToolDTO toolDTO, UserEntity currentUser) {
41+
Tool tool = toEntity(toolDTO);
42+
if (toolDTO.getId() == null) {
43+
tool.setCreatedBy(currentUser);
44+
}
45+
tool.setModifiedBy(currentUser);
46+
return tool;
47+
}
48+
49+
@Override
50+
public ToolDTO getById(Integer id) {
51+
return toDTO(toolRepository.findOne(id));
52+
}
53+
54+
@Override
55+
public void delete(Integer id) {
56+
toolRepository.delete(id);
57+
}
58+
59+
private boolean canManageTools() {
60+
return Stream.of("tool:put", "tool:post", "tool:*:delete")
61+
.allMatch(permission -> SecurityUtils.getSubject().isPermitted(permission));
62+
}
63+
64+
Tool toEntity(ToolDTO toolDTO) {
65+
boolean isNewTool = toolDTO.getId() == null;
66+
Tool tool = isNewTool ? new Tool() : toolRepository.findOne(toolDTO.getId());
67+
Instant currentInstant = Instant.now();
68+
if (isNewTool) {
69+
setCreationDetails(tool, currentInstant);
70+
} else {
71+
setModificationDetails(tool, currentInstant);
72+
}
73+
updateToolFromDTO(tool, toolDTO);
74+
return tool;
75+
}
76+
77+
private void setCreationDetails(Tool tool, Instant currentInstant) {
78+
tool.setCreatedDate(Date.from(currentInstant));
79+
tool.setCreatedBy(getCurrentUser());
80+
}
81+
82+
private void setModificationDetails(Tool tool, Instant currentInstant) {
83+
tool.setModifiedDate(Date.from(currentInstant));
84+
tool.setModifiedBy(getCurrentUser());
85+
}
86+
87+
private void updateToolFromDTO(Tool tool, ToolDTO toolDTO) {
88+
Optional.ofNullable(toolDTO.getName()).ifPresent(tool::setName);
89+
Optional.ofNullable(toolDTO.getUrl()).ifPresent(tool::setUrl);
90+
Optional.ofNullable(toolDTO.getDescription()).ifPresent(tool::setDescription);
91+
Optional.ofNullable(toolDTO.getEnabled()).ifPresent(tool::setEnabled);
92+
}
93+
94+
ToolDTO toDTO(Tool tool) {
95+
return Optional.ofNullable(tool)
96+
.map(t -> {
97+
ToolDTO toolDTO = new ToolDTO();
98+
toolDTO.setId(t.getId());
99+
toolDTO.setName(t.getName());
100+
toolDTO.setUrl(t.getUrl());
101+
toolDTO.setDescription(t.getDescription());
102+
Optional.ofNullable(tool.getCreatedBy())
103+
.map(UserEntity::getId)
104+
.map(userRepository::findOne)
105+
.map(UserEntity::getName)
106+
.ifPresent(toolDTO::setCreatedByName);
107+
Optional.ofNullable(tool.getModifiedBy())
108+
.map(UserEntity::getId)
109+
.map(userRepository::findOne)
110+
.map(UserEntity::getName)
111+
.ifPresent(toolDTO::setModifiedByName);
112+
toolDTO.setCreatedDate(t.getCreatedDate() != null ? new SimpleDateFormat(DATE_TIME_FORMAT).format(t.getCreatedDate()) : null);
113+
toolDTO.setModifiedDate(t.getModifiedDate() != null ? new SimpleDateFormat(DATE_TIME_FORMAT).format(t.getModifiedDate()) : null);
114+
toolDTO.setEnabled(t.getEnabled());
115+
return toolDTO;
116+
})
117+
.orElse(null);
118+
}
119+
120+
}

0 commit comments

Comments
 (0)