Commit d49e9972 authored by Alexander Prendetskiy's avatar Alexander Prendetskiy Committed by Matija Obreza

Include inherited permissions in Permissions API

Signed-off-by: Matija Obreza's avatarMatija Obreza <matija.obreza@croptrust.org>
parent 1d4248fb
...@@ -15,17 +15,22 @@ ...@@ -15,17 +15,22 @@
*/ */
package org.genesys2.server.api.v1; package org.genesys2.server.api.v1;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.genesys.blocks.model.JsonViews; import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.oauth.model.OAuthClient; import org.genesys.blocks.oauth.model.OAuthClient;
import org.genesys.blocks.oauth.service.OAuthClientDetailsService; import org.genesys.blocks.oauth.service.OAuthClientDetailsService;
import org.genesys.blocks.security.model.AclEntry;
import org.genesys.blocks.security.model.AclObjectIdentity; import org.genesys.blocks.security.model.AclObjectIdentity;
import org.genesys.blocks.security.model.AclSid; import org.genesys.blocks.security.model.AclSid;
import org.genesys.blocks.security.serialization.AclEntriesToPermissions;
import org.genesys.blocks.security.serialization.SidPermissions; import org.genesys.blocks.security.serialization.SidPermissions;
import org.genesys.blocks.security.service.CustomAclService; import org.genesys.blocks.security.service.CustomAclService;
import org.genesys2.server.api.ApiBaseController; import org.genesys2.server.api.ApiBaseController;
...@@ -45,7 +50,9 @@ import org.springframework.web.bind.annotation.RequestMapping; ...@@ -45,7 +50,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.annotation.JsonView; import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
...@@ -85,7 +92,7 @@ public class PermissionController { ...@@ -85,7 +92,7 @@ public class PermissionController {
@Transactional @Transactional
@PostMapping(value = "/permissions/{clazz}/{id}", produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = "/permissions/{clazz}/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@JsonView(JsonViews.Minimal.class) @JsonView(JsonViews.Minimal.class)
public AclObjectIdentity addPermission(@PathVariable(value = "clazz") final String className, @PathVariable("id") final long id, public AclObjectIdentityExt addPermission(@PathVariable(value = "clazz") final String className, @PathVariable("id") final long id,
@RequestBody final SidPermissions sidPermissions) { @RequestBody final SidPermissions sidPermissions) {
final AclObjectIdentity objectIdentity = aclService.ensureObjectIdentity(id, className); final AclObjectIdentity objectIdentity = aclService.ensureObjectIdentity(id, className);
LOG.info("Setting permissions {}", sidPermissions); LOG.info("Setting permissions {}", sidPermissions);
...@@ -105,7 +112,7 @@ public class PermissionController { ...@@ -105,7 +112,7 @@ public class PermissionController {
@Transactional(readOnly = true) @Transactional(readOnly = true)
@GetMapping(value = "/permissions/{clazz}/{id}", produces = MediaType.APPLICATION_JSON_VALUE) @GetMapping(value = "/permissions/{clazz}/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@JsonView(JsonViews.Minimal.class) @JsonView(JsonViews.Minimal.class)
public AclObjectIdentity permissions(@PathVariable(value = "clazz") final String className, @PathVariable("id") final long id) { public AclObjectIdentityExt permissions(@PathVariable(value = "clazz") final String className, @PathVariable("id") final long id) {
final AclObjectIdentity objectIdentity = aclService.getObjectIdentity(id, className); final AclObjectIdentity objectIdentity = aclService.getObjectIdentity(id, className);
return lazyLoadForJson(objectIdentity); return lazyLoadForJson(objectIdentity);
} }
...@@ -116,13 +123,33 @@ public class PermissionController { ...@@ -116,13 +123,33 @@ public class PermissionController {
* @param objectIdentity the object identity * @param objectIdentity the object identity
* @return the acl object identity * @return the acl object identity
*/ */
protected AclObjectIdentity lazyLoadForJson(final AclObjectIdentity objectIdentity) { protected AclObjectIdentityExt lazyLoadForJson(final AclObjectIdentity objectIdentity) {
AclObjectIdentityExt _aclObjectIdentity = new AclObjectIdentityExt(objectIdentity);
if (objectIdentity != null && objectIdentity.getAclEntries() != null) { if (objectIdentity != null && objectIdentity.getAclEntries() != null) {
objectIdentity.getAclEntries().size(); objectIdentity.getAclEntries().size();
List<AclEntry> inheritedEntries = inherited(objectIdentity, new ArrayList<>(), new HashSet<>());
_aclObjectIdentity.inherited.addAll(inheritedEntries);
// lazy load for JSON // lazy load for JSON
objectIdentity.getAclEntries().forEach(entry -> entry.getAclSid().getId()); _aclObjectIdentity.inherited.forEach(entry -> entry.getAclSid().getId());
}
return _aclObjectIdentity;
}
private List<AclEntry> inherited(AclObjectIdentity objectIdentity, List<AclEntry> aclEntries, Set<AclObjectIdentity> handled) {
if (objectIdentity == null || handled.contains(objectIdentity)) {
return aclEntries;
}
aclEntries.addAll(objectIdentity.getAclEntries());
handled.add(objectIdentity);
if (objectIdentity.getParentObject() != null) {
inherited(objectIdentity.getParentObject(), aclEntries, handled);
} }
return objectIdentity;
return aclEntries;
} }
/** /**
...@@ -131,9 +158,10 @@ public class PermissionController { ...@@ -131,9 +158,10 @@ public class PermissionController {
* @param id the internal ID of aclObjectIdentity * @param id the internal ID of aclObjectIdentity
* @return the acl object identity * @return the acl object identity
*/ */
@Transactional(readOnly = true)
@GetMapping(value = "/permissions/{aclObjectIdentityId}", produces = MediaType.APPLICATION_JSON_VALUE) @GetMapping(value = "/permissions/{aclObjectIdentityId}", produces = MediaType.APPLICATION_JSON_VALUE)
@JsonView(JsonViews.Minimal.class) @JsonView(JsonViews.Minimal.class)
public AclObjectIdentity permissions(@PathVariable(value = "aclObjectIdentityId") final long id) { public AclObjectIdentityExt permissions(@PathVariable(value = "aclObjectIdentityId") final long id) {
final AclObjectIdentity objectIdentity = aclService.getObjectIdentity(id); final AclObjectIdentity objectIdentity = aclService.getObjectIdentity(id);
return lazyLoadForJson(objectIdentity); return lazyLoadForJson(objectIdentity);
} }
...@@ -211,4 +239,18 @@ public class PermissionController { ...@@ -211,4 +239,18 @@ public class PermissionController {
} }
return oauthMap; return oauthMap;
} }
/**
* Wraps {@link AclObjectIdentity} and adds list of inherited permissions.
*/
private static class AclObjectIdentityExt {
@JsonUnwrapped
public AclObjectIdentity original;
@JsonSerialize(converter = AclEntriesToPermissions.class)
public List<AclEntry> inherited = new ArrayList<>();
public AclObjectIdentityExt(AclObjectIdentity source) {
this.original = source;
}
}
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment