[Fix] Added proper privilege validation for StrolchJob

This commit is contained in:
Robert von Burg 2019-01-17 13:57:26 +01:00
parent 434dd5a2dc
commit 81de2b94e4
2 changed files with 41 additions and 7 deletions

View File

@ -28,6 +28,7 @@ import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.base.PrivilegeException; import li.strolch.privilege.base.PrivilegeException;
import li.strolch.privilege.model.Certificate; import li.strolch.privilege.model.Certificate;
import li.strolch.privilege.model.PrivilegeContext; import li.strolch.privilege.model.PrivilegeContext;
import li.strolch.privilege.model.Restrictable;
import li.strolch.runtime.StrolchConstants; import li.strolch.runtime.StrolchConstants;
import li.strolch.runtime.privilege.PrivilegedRunnable; import li.strolch.runtime.privilege.PrivilegedRunnable;
import li.strolch.utils.helper.ExceptionHelper; import li.strolch.utils.helper.ExceptionHelper;
@ -38,7 +39,7 @@ import org.slf4j.LoggerFactory;
* A StrolchJob is a simple job which performs an action. A StrolchJob can be scheduled so that it executes * A StrolchJob is a simple job which performs an action. A StrolchJob can be scheduled so that it executes
* periodically, or trigger externally e.g. from a UI. Sub classes must implement the * periodically, or trigger externally e.g. from a UI. Sub classes must implement the
*/ */
public abstract class StrolchJob implements Runnable { public abstract class StrolchJob implements Runnable, Restrictable {
protected static final Logger logger = LoggerFactory.getLogger(StrolchJob.class); protected static final Logger logger = LoggerFactory.getLogger(StrolchJob.class);
@ -295,6 +296,16 @@ public abstract class StrolchJob implements Runnable {
protected abstract void execute(PrivilegeContext ctx) throws Exception; protected abstract void execute(PrivilegeContext ctx) throws Exception;
@Override
public String getPrivilegeName() {
return StrolchJob.class.getName();
}
@Override
public Object getPrivilegeValue() {
return this.getClass().getName();
}
public JsonObject toJson() { public JsonObject toJson() {
JsonObject jsonObject = new JsonObject(); JsonObject jsonObject = new JsonObject();

View File

@ -16,7 +16,9 @@
package li.strolch.rest.endpoint; package li.strolch.rest.endpoint;
import static java.util.Comparator.comparing; import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
import static li.strolch.rest.StrolchRestfulConstants.DATA; import static li.strolch.rest.StrolchRestfulConstants.DATA;
import static li.strolch.runtime.StrolchConstants.ROLE_STROLCH_ADMIN;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*; import javax.ws.rs.*;
@ -26,9 +28,12 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.List; import java.util.List;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.job.StrolchJob; import li.strolch.job.StrolchJob;
import li.strolch.job.StrolchJobsHandler; import li.strolch.job.StrolchJobsHandler;
import li.strolch.privilege.model.Certificate; import li.strolch.privilege.model.Certificate;
import li.strolch.privilege.model.IPrivilege;
import li.strolch.privilege.model.PrivilegeContext;
import li.strolch.rest.RestfulStrolchComponent; import li.strolch.rest.RestfulStrolchComponent;
import li.strolch.rest.StrolchRestfulConstants; import li.strolch.rest.StrolchRestfulConstants;
import li.strolch.rest.helper.ResponseUtil; import li.strolch.rest.helper.ResponseUtil;
@ -48,12 +53,25 @@ public class StrolchJobsResource {
public Response getAll(@Context HttpServletRequest request, @Context HttpHeaders headers) { public Response getAll(@Context HttpServletRequest request, @Context HttpHeaders headers) {
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
ComponentContainer container = RestfulStrolchComponent.getInstance().getContainer();
PrivilegeContext ctx = container.getPrivilegeHandler().validate(cert);
StrolchJobsHandler strolchJobsHandler = RestfulStrolchComponent.getInstance().getContainer() // assert user can access StrolchJobs
.getComponent(StrolchJobsHandler.class); if (!ctx.hasRole(ROLE_STROLCH_ADMIN))
ctx.assertHasPrivilege(StrolchJob.class.getName());
List<StrolchJob> jobs = strolchJobsHandler.getJobs(cert); StrolchJobsHandler strolchJobsHandler = container.getComponent(StrolchJobsHandler.class);
jobs.sort(comparing(StrolchJob::getName));
List<StrolchJob> jobs = strolchJobsHandler.getJobs(cert).stream() //
.filter(job -> {
if (ctx.hasRole(ROLE_STROLCH_ADMIN))
return true;
IPrivilege privilege = ctx.getPrivilege(StrolchJob.class.getName());
return privilege.isAllAllowed() || privilege.getAllowList().contains(job.getClass().getName());
}) //
.sorted(comparing(StrolchJob::getName)) //
.collect(toList());
return ResponseUtil.listToResponse(DATA, jobs, StrolchJob::toJson); return ResponseUtil.listToResponse(DATA, jobs, StrolchJob::toJson);
} }
@ -67,11 +85,16 @@ public class StrolchJobsResource {
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
StrolchJobsHandler strolchJobsHandler = RestfulStrolchComponent.getInstance().getContainer() ComponentContainer container = RestfulStrolchComponent.getInstance().getContainer();
.getComponent(StrolchJobsHandler.class); StrolchJobsHandler strolchJobsHandler = container.getComponent(StrolchJobsHandler.class);
StrolchJob job = strolchJobsHandler.getJob(cert, name); StrolchJob job = strolchJobsHandler.getJob(cert, name);
// assert user can access StrolchJobs
PrivilegeContext ctx = container.getPrivilegeHandler().validate(cert);
if (!ctx.hasRole(ROLE_STROLCH_ADMIN))
ctx.validateAction(job);
switch (action) { switch (action) {
case "runNow": case "runNow":