Details
-
Task
-
Resolution: Obsolete
-
Major
-
None
-
None
Description
Research a way to make the permission checking "transparent" by applying annotations to REST methods.
Thoughts:
@CheckPermission
annotation that could be applied to a package, type or method and will tell a Filter that permission checking should be done for this JAX-RS resource.
@ResourceId
annotation that could be applied to a parameter, to tell the permission checker the parameter to get the resource id from.
@SkipPermissionCheck
annotation, to black-list methods where the permission checking should not be done automatically.
@Path("/samples") @PermitAll @Stateless @CheckPermission public class SampleService { @Inject @HawkularAccountsSample EntityManager em; @Inject HawkularUser currentUser; @Inject PermissionChecker permissionChecker; @Inject ResourceService resourceService; @GET public Response getAllSamples() { // CheckPermission will not act on methods without @ResourceId, as the method should take care of // retrieving all the data related to this user/org by itself CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<Sample> query = builder.createQuery(Sample.class); Root<Sample> root = query.from(Sample.class); query.select(root); query.where(builder.equal(root.get(Sample_.ownerId), currentUser.getId())); return Response.ok().entity(em.createQuery(query).getResultList()).build(); } @GET @Path("{sampleId}") @SkipPermissionCheck public Response getSample(@PathParam("sampleId") String sampleId) { // on this case, we would want to do it by ourselves, for some reason Sample sample = em.find(Sample.class, sampleId); Resource resource = resourceService.get(sampleId); if (permissionChecker.hasAccessTo(currentUser, resource)) { return Response.ok().entity(sample).build(); } return Response.status(Response.Status.NOT_FOUND).build(); } @POST public Response createSample(SampleRequest request) { // no permission checking? Sample sample = new Sample(UUID.randomUUID().toString(), currentUser.getId()); resourceService.create(sample.getId()); sample.setName(request.getName()); em.persist(sample); return Response.ok().entity(sample).build(); } @DELETE @Path("{sampleId}") public Response removeSample(@ResourceId @PathParam("sampleId") String sampleId) { // permission checking will happen for this one, so, once this method is called, the permission has been // checked already em.remove(em.find(Sample.class, sampleId)); return Response.noContent().build(); } }