mirror of
https://github.com/apache/nifi.git
synced 2025-03-03 07:59:15 +00:00
NIFI-4907:
- Minor adjustments following PR. - Avoiding additional find operation when authorizing components when populating component details. - Requiring access to provenance events when downloading content or submitting a replay as they may provide events details. - Updating the REST API docs detailing the required permissions. - Updating the wording in the documentation regarding the provenance and data policies. - Removed the event attributes from the authorization calls that were verifying access to provenance events. - Only checking content availability when the user is authorized for the components data. - Addressing typo in JavaDoc. This closes #2703
This commit is contained in:
parent
e27798797a
commit
fe31a06fdc
@ -1102,18 +1102,18 @@ Component level access policies govern the following component level authorizati
|
||||
|Allows users to modify component configuration details
|
||||
|`resource="/<component-type>/<component-UUID>" action="W"`
|
||||
|
||||
|view provenance
|
||||
|Allows users to view provenance events generated by this component
|
||||
|`resource="/provenance-data/<component-type>/<component-UUID>" action="R"`
|
||||
|
||||
|view the data
|
||||
|Allows users to view metadata and content for this component through provenance data and flowfile queues in outbound connections
|
||||
|Allows users to view metadata and content for this component in flowfile queues in outbound connections and through provenance events
|
||||
|`resource="/data/<component-type>/<component-UUID>" action="R"`
|
||||
|
||||
|modify the data
|
||||
|Allows users to empty flowfile queues in outbound connections and submit replays
|
||||
|Allows users to empty flowfile queues in outbound connections and submit replays through provenance events
|
||||
|`resource="/data/<component-type>/<component-UUID>" action="W"`
|
||||
|
||||
|view provenance
|
||||
|Allows users to view provenance data generated by this component
|
||||
|`resource="/provenance-data/<component-type>/<component-UUID>" action="R"`
|
||||
|
||||
|view the policies
|
||||
|Allows users to view the list of users who can view/modify a component
|
||||
|`resource="/policies/<component-type>/<component-UUID>" action="R"`
|
||||
|
@ -209,9 +209,9 @@ The available component-level access policies are:
|
||||
|Policy |Privilege
|
||||
|view the component |Allows users to view component configuration details
|
||||
|modify the component |Allows users to modify component configuration details
|
||||
|view the data |Allows users to view metadata and content for this component through provenance data and flowfile queues in outbound connection
|
||||
|modify the data |Allows users to empty flowfile queues in outbound connections and to submit replays
|
||||
|view provenance |Allows users to view provenance data generated by this component
|
||||
|view provenance |Allows users to view provenance events generated by this component
|
||||
|view the data |Allows users to view metadata and content for this component in flowfile queues in outbound connections and through provenance events
|
||||
|modify the data |Allows users to empty flowfile queues in outbound connections and submit replays through provenance events
|
||||
|view the policies |Allows users to view the list of users who can view and modify a component
|
||||
|modify the policies |Allows users to modify the list of users who can view and modify a component
|
||||
|retrieve data via site-to-site |Allows a port to receive data from NiFi instances
|
||||
|
@ -22,10 +22,11 @@ package org.apache.nifi.authorization.resource;
|
||||
*
|
||||
* if a user has permissions to /policies/input-ports/1234 then they have permissions to the following
|
||||
*
|
||||
* - the policy for /input-ports/1234 -> /policies/input-ports/1234
|
||||
* - the policy for /data/input-ports/1234 -> /policies/data/input-ports/1234
|
||||
* - the policy for /data-transfers/input-ports/1234 -> /policies/data-transfers/input-ports/1234
|
||||
* - the policy for /policies/input-ports/1234 -> /policies/policies/input-ports/1234
|
||||
* - the policy for /input-ports/1234 -> /policies/input-ports/1234
|
||||
* - the policy for /data/input-ports/1234 -> /policies/data/input-ports/1234
|
||||
* - the policy for /provenance-data/input-ports/1234 -> /policies/provenance-data/input-ports/1234
|
||||
* - the policy for /data-transfers/input-ports/1234 -> /policies/data-transfers/input-ports/1234
|
||||
* - the policy for /policies/input-ports/1234 -> /policies/policies/input-ports/1234
|
||||
*/
|
||||
public interface EnforcePolicyPermissionsThroughBaseResource {
|
||||
|
||||
|
@ -81,6 +81,7 @@ public class ProvenanceEventResource extends ApplicationResource {
|
||||
value = "Gets the input content for a provenance event",
|
||||
response = StreamingOutput.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Read Component Provenance Data - /provenance-data/{component-type}/{uuid}"),
|
||||
@Authorization(value = "Read Component Data - /data/{component-type}/{uuid}")
|
||||
}
|
||||
)
|
||||
@ -164,6 +165,7 @@ public class ProvenanceEventResource extends ApplicationResource {
|
||||
value = "Gets the output content for a provenance event",
|
||||
response = StreamingOutput.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Read Component Provenance Data - /provenance-data/{component-type}/{uuid}"),
|
||||
@Authorization(value = "Read Component Data - /data/{component-type}/{uuid}")
|
||||
}
|
||||
)
|
||||
@ -247,7 +249,7 @@ public class ProvenanceEventResource extends ApplicationResource {
|
||||
value = "Gets a provenance event",
|
||||
response = ProvenanceEventEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Read Component Data - /data/{component-type}/{uuid}")
|
||||
@Authorization(value = "Read Component Provenance Data - /provenance-data/{component-type}/{uuid}")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
@ -320,6 +322,7 @@ public class ProvenanceEventResource extends ApplicationResource {
|
||||
value = "Replays content from a provenance event",
|
||||
response = ProvenanceEventEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Read Component Provenance Data - /provenance-data/{component-type}/{uuid}"),
|
||||
@Authorization(value = "Read Component Data - /data/{component-type}/{uuid}"),
|
||||
@Authorization(value = "Write Component Data - /data/{component-type}/{uuid}")
|
||||
}
|
||||
|
@ -887,6 +887,7 @@ public class ControllerFacade implements Authorizable {
|
||||
final Resource inputPortResource = inputPort.getResource();
|
||||
resources.add(inputPortResource);
|
||||
resources.add(ResourceFactory.getDataResource(inputPortResource));
|
||||
resources.add(ResourceFactory.getProvenanceDataResource(inputPortResource));
|
||||
resources.add(ResourceFactory.getPolicyResource(inputPortResource));
|
||||
if (inputPort instanceof RootGroupPort) {
|
||||
resources.add(ResourceFactory.getDataTransferResource(inputPortResource));
|
||||
@ -898,6 +899,7 @@ public class ControllerFacade implements Authorizable {
|
||||
final Resource outputPortResource = outputPort.getResource();
|
||||
resources.add(outputPortResource);
|
||||
resources.add(ResourceFactory.getDataResource(outputPortResource));
|
||||
resources.add(ResourceFactory.getProvenanceDataResource(outputPortResource));
|
||||
resources.add(ResourceFactory.getPolicyResource(outputPortResource));
|
||||
if (outputPort instanceof RootGroupPort) {
|
||||
resources.add(ResourceFactory.getDataTransferResource(outputPortResource));
|
||||
@ -1081,10 +1083,7 @@ public class ControllerFacade implements Authorizable {
|
||||
if (includeResults || queryResult.isFinished()) {
|
||||
final List<ProvenanceEventDTO> events = new ArrayList<>();
|
||||
for (final ProvenanceEventRecord record : queryResult.getMatchingEvents()) {
|
||||
final ProvenanceEventDTO dto = createProvenanceEventDto(record, Boolean.TRUE.equals(summarize));
|
||||
if (dto != null) {
|
||||
events.add(dto);
|
||||
}
|
||||
events.add(createProvenanceEventDto(record, Boolean.TRUE.equals(summarize)));
|
||||
}
|
||||
resultsDto.setProvenanceEvents(events);
|
||||
}
|
||||
@ -1215,7 +1214,7 @@ public class ControllerFacade implements Authorizable {
|
||||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
|
||||
// get the event in order to get the filename
|
||||
final ProvenanceEventRecord event = flowController.getProvenanceRepository().getEvent(eventId);
|
||||
final ProvenanceEventRecord event = flowController.getProvenanceRepository().getEvent(eventId, user);
|
||||
if (event == null) {
|
||||
throw new ResourceNotFoundException("Unable to find the specified event.");
|
||||
}
|
||||
@ -1271,13 +1270,13 @@ public class ControllerFacade implements Authorizable {
|
||||
}
|
||||
|
||||
// lookup the original event
|
||||
final ProvenanceEventRecord originalEvent = flowController.getProvenanceRepository().getEvent(eventId);
|
||||
final ProvenanceEventRecord originalEvent = flowController.getProvenanceRepository().getEvent(eventId, user);
|
||||
if (originalEvent == null) {
|
||||
throw new ResourceNotFoundException("Unable to find the specified event.");
|
||||
}
|
||||
|
||||
// authorize the replay
|
||||
authorizeData(originalEvent);
|
||||
authorizeReplay(originalEvent);
|
||||
|
||||
// replay the flow file
|
||||
final ProvenanceEventRecord event = flowController.replayFlowFile(originalEvent, user);
|
||||
@ -1290,11 +1289,14 @@ public class ControllerFacade implements Authorizable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorizes access to replay a specified provenance event.
|
||||
* Authorizes access to replay a specified provenance event. Whether to check read data permission can be specified. The context this
|
||||
* method is invoked may have already verified these permissions. Using a flag here as it forces the caller to acknowledge this fact
|
||||
* limiting the possibility of overlooking it.
|
||||
*
|
||||
* @param event event
|
||||
* @param checkReadDataPermissions whether to verify read data permissions
|
||||
*/
|
||||
private AuthorizationResult checkAuthorizationForReplay(final ProvenanceEventRecord event) {
|
||||
private AuthorizationResult checkAuthorizationForReplay(final ProvenanceEventRecord event, final boolean checkReadDataPermissions) {
|
||||
// if the connection id isn't specified, then the replay wouldn't be available anyways and we have nothing to authorize against so deny it`
|
||||
if (event.getSourceQueueIdentifier() == null) {
|
||||
return AuthorizationResult.denied("The connection id in the provenance event is unknown.");
|
||||
@ -1310,16 +1312,24 @@ public class ControllerFacade implements Authorizable {
|
||||
|
||||
final Map<String, String> eventAttributes = event.getAttributes();
|
||||
|
||||
if (checkReadDataPermissions) {
|
||||
// ensure we can read the data
|
||||
final AuthorizationResult result = dataAuthorizable.checkAuthorization(authorizer, RequestAction.READ, user, eventAttributes);
|
||||
if (!Result.Approved.equals(result.getResult())) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure we can write the data; read the data should have been checked already
|
||||
return dataAuthorizable.checkAuthorization(authorizer, RequestAction.WRITE, user, eventAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorizes access to replay a specified provenance event.
|
||||
* Authorizes access to replay for a specified provenance event.
|
||||
*
|
||||
* @param event event
|
||||
*/
|
||||
private void authorizeData(final ProvenanceEventRecord event) {
|
||||
private void authorizeReplay(final ProvenanceEventRecord event) {
|
||||
// if the connection id isn't specified, then the replay wouldn't be available anyways and we have nothing to authorize against so deny it`
|
||||
if (event.getSourceQueueIdentifier() == null) {
|
||||
throw new AccessDeniedException("The connection id in the provenance event is unknown.");
|
||||
@ -1339,6 +1349,11 @@ public class ControllerFacade implements Authorizable {
|
||||
dataAuthorizable.authorize(authorizer, RequestAction.WRITE, user, eventAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorizes access to data for a specified provenance event.
|
||||
*
|
||||
* @param event event
|
||||
*/
|
||||
private AuthorizationResult checkAuthorizationForData(ProvenanceEventRecord event) {
|
||||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
final Authorizable dataAuthorizable;
|
||||
@ -1354,52 +1369,6 @@ public class ControllerFacade implements Authorizable {
|
||||
return dataAuthorizable.checkAuthorization(authorizer, RequestAction.READ, user, eventAttributes);
|
||||
}
|
||||
|
||||
private AuthorizationResult checkAuthorizationForProvenanceData(final ProvenanceEventRecord event) {
|
||||
final ProcessGroup rootGroup = flowController.getGroup(getRootGroupId());
|
||||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
final String componentId = event.getComponentId();
|
||||
Connectable connectable;
|
||||
String targetId = null;
|
||||
// check if the component is the rootGroup
|
||||
if (getRootGroupId().equals(componentId)) {
|
||||
targetId = componentId;
|
||||
}
|
||||
if (targetId == null) {
|
||||
// check if the component is a processor
|
||||
connectable = rootGroup.findProcessor(componentId);
|
||||
if (connectable == null) {
|
||||
// if the component id is not a processor then consider a connection
|
||||
connectable = rootGroup.findConnection(componentId).getSource();
|
||||
|
||||
if (connectable == null) {
|
||||
throw new ResourceNotFoundException("The component that generated this event is no longer part of the data flow");
|
||||
}
|
||||
}
|
||||
targetId = connectable.getIdentifier();
|
||||
}
|
||||
final Authorizable provenanceDataAuthorizable = flowController.createProvenanceDataAuthorizable(targetId);
|
||||
|
||||
return provenanceDataAuthorizable.checkAuthorization(authorizer, RequestAction.READ, user);
|
||||
}
|
||||
|
||||
private AuthorizationResult checkConnectableAuthorization(final String componentId) {
|
||||
final ProcessGroup rootGroup = flowController.getGroup(getRootGroupId());
|
||||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
if (rootGroup.getIdentifier().equals(componentId)) {
|
||||
return rootGroup.checkAuthorization(authorizer, RequestAction.READ, user);
|
||||
}
|
||||
Connectable connectable = rootGroup.findProcessor(componentId);
|
||||
if (connectable == null) {
|
||||
// if the component id is not a processor then consider a connection
|
||||
connectable = rootGroup.findConnection(componentId).getSource();
|
||||
|
||||
if (connectable == null) {
|
||||
throw new ResourceNotFoundException("The component that generated this event is no longer part of the data flow");
|
||||
}
|
||||
}
|
||||
return connectable.checkAuthorization(authorizer, RequestAction.READ, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the provenance event with the specified event id.
|
||||
*
|
||||
@ -1421,17 +1390,13 @@ public class ControllerFacade implements Authorizable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ProvenanceEventDTO for the specified ProvenanceEventRecord.
|
||||
* Creates a ProvenanceEventDTO for the specified ProvenanceEventRecord. This should only be invoked once the
|
||||
* current user has been authorized for access to this provenance event.
|
||||
*
|
||||
* @param event event
|
||||
* @return event
|
||||
*/
|
||||
private ProvenanceEventDTO createProvenanceEventDto(final ProvenanceEventRecord event, final boolean summarize) {
|
||||
// do not generate DTO if not authorized
|
||||
final AuthorizationResult provenanceResult = checkAuthorizationForProvenanceData(event);
|
||||
if (Result.Denied.equals(provenanceResult.getResult())) {
|
||||
return null;
|
||||
}
|
||||
final ProvenanceEventDTO dto = new ProvenanceEventDTO();
|
||||
dto.setId(String.valueOf(event.getEventId()));
|
||||
dto.setEventId(event.getEventId());
|
||||
@ -1443,9 +1408,6 @@ public class ControllerFacade implements Authorizable {
|
||||
dto.setComponentId(event.getComponentId());
|
||||
dto.setComponentType(event.getComponentType());
|
||||
|
||||
// sets the component details if it can find the component still in the flow
|
||||
setComponentDetails(dto);
|
||||
|
||||
// only include all details if not summarizing
|
||||
if (!summarize) {
|
||||
// convert the attributes
|
||||
@ -1491,11 +1453,11 @@ public class ControllerFacade implements Authorizable {
|
||||
dto.setRelationship(event.getRelationship());
|
||||
dto.setDetails(event.getDetails());
|
||||
|
||||
final ContentAvailability contentAvailability = flowController.getContentAvailability(event);
|
||||
|
||||
// set flowfile attributes and content only if approved for view the data
|
||||
final AuthorizationResult dataResult = checkAuthorizationForData(event);
|
||||
if (Result.Approved.equals(dataResult.getResult())) {
|
||||
final ContentAvailability contentAvailability = flowController.getContentAvailability(event);
|
||||
|
||||
// attributes
|
||||
dto.setAttributes(attributes);
|
||||
|
||||
@ -1520,15 +1482,17 @@ public class ControllerFacade implements Authorizable {
|
||||
dto.setInputContentClaimFileSize(FormatUtils.formatDataSize(event.getPreviousFileSize()));
|
||||
}
|
||||
|
||||
// determine if authorized for event replay
|
||||
// this authorization is for data write only; ensure data read was approved
|
||||
final AuthorizationResult replayAuthorized = checkAuthorizationForReplay(event);
|
||||
// determine if authorized for event replay - only need to check write as read was verified above
|
||||
final AuthorizationResult replayAuthorized = checkAuthorizationForReplay(event, false);
|
||||
|
||||
// replay
|
||||
dto.setReplayAvailable(contentAvailability.isReplayable() && Result.Approved.equals(replayAuthorized.getResult()));
|
||||
dto.setReplayExplanation(contentAvailability.isReplayable()
|
||||
&& !Result.Approved.equals(replayAuthorized.getResult()) ? replayAuthorized.getExplanation() : contentAvailability.getReasonNotReplayable());
|
||||
dto.setSourceConnectionIdentifier(event.getSourceQueueIdentifier());
|
||||
} else {
|
||||
dto.setReplayAvailable(false);
|
||||
dto.setReplayExplanation(dataResult.getExplanation());
|
||||
}
|
||||
|
||||
// event duration
|
||||
@ -1553,34 +1517,44 @@ public class ControllerFacade implements Authorizable {
|
||||
dto.setChildUuids(childUuids);
|
||||
}
|
||||
|
||||
// sets the component details if it can find the component still in the flow
|
||||
setComponentDetails(dto);
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
private void setComponentDetails(final ProvenanceEventDTO dto) {
|
||||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
final ProcessGroup root = flowController.getGroup(flowController.getRootGroupId());
|
||||
final AuthorizationResult componentResult = checkConnectableAuthorization(dto.getComponentId());
|
||||
|
||||
final Connectable connectable = root.findLocalConnectable(dto.getComponentId());
|
||||
if (connectable != null) {
|
||||
dto.setGroupId(connectable.getProcessGroup().getIdentifier());
|
||||
if (Result.Denied.equals(componentResult.getResult())) {
|
||||
dto.setComponentType("Processor");
|
||||
dto.setComponentName(dto.getComponentId());
|
||||
} else {
|
||||
|
||||
// if the user is approved for this component policy, provide additional details, otherwise override/redact as necessary
|
||||
if (Result.Approved.equals(connectable.checkAuthorization(authorizer, RequestAction.READ, user).getResult())) {
|
||||
dto.setComponentName(connectable.getName());
|
||||
} else {
|
||||
dto.setComponentType(connectable.getConnectableType().toString());
|
||||
dto.setComponentName(dto.getComponentId());
|
||||
dto.setRelationship(null);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
final RemoteGroupPort remoteGroupPort = root.findRemoteGroupPort(dto.getComponentId());
|
||||
if (remoteGroupPort != null) {
|
||||
dto.setGroupId(remoteGroupPort.getProcessGroupIdentifier());
|
||||
if (Result.Denied.equals(componentResult.getResult())) {
|
||||
dto.setComponentType("RemoteGroupPort");
|
||||
dto.setComponentName(dto.getComponentId());
|
||||
} else {
|
||||
|
||||
// if the user is approved for this component policy, provide additional details, otherwise override/redact as necessary
|
||||
if (Result.Approved.equals(remoteGroupPort.checkAuthorization(authorizer, RequestAction.READ, user).getResult())) {
|
||||
dto.setComponentName(remoteGroupPort.getName());
|
||||
} else {
|
||||
dto.setComponentName(dto.getComponentId());
|
||||
dto.setRelationship(null);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1588,16 +1562,17 @@ public class ControllerFacade implements Authorizable {
|
||||
if (connection != null) {
|
||||
dto.setGroupId(connection.getProcessGroup().getIdentifier());
|
||||
|
||||
if (Result.Denied.equals(componentResult.getResult())) {
|
||||
dto.setComponentType("Connection");
|
||||
dto.setComponentName(dto.getComponentId());
|
||||
} else {
|
||||
// if the user is approved for this component policy, provide additional details, otherwise override/redact as necessary
|
||||
if (Result.Approved.equals(connection.checkAuthorization(authorizer, RequestAction.READ, user).getResult())) {
|
||||
String name = connection.getName();
|
||||
final Collection<Relationship> relationships = connection.getRelationships();
|
||||
if (StringUtils.isBlank(name) && CollectionUtils.isNotEmpty(relationships)) {
|
||||
name = StringUtils.join(relationships.stream().map(relationship -> relationship.getName()).collect(Collectors.toSet()), ", ");
|
||||
}
|
||||
dto.setComponentName(name);
|
||||
} else {
|
||||
dto.setComponentName(dto.getComponentId());
|
||||
dto.setRelationship(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -529,18 +529,18 @@
|
||||
text: 'modify the component',
|
||||
value: 'write-component',
|
||||
description: 'Allows users to modify component configuration details'
|
||||
}, {
|
||||
text: 'view provenance',
|
||||
value: 'read-provenance',
|
||||
description: 'Allows users to view provenance events generated by this component'
|
||||
}, {
|
||||
text: 'view the data',
|
||||
value: 'read-data',
|
||||
description: 'Allows users to view metadata and content for this component through flowfile queues in outbound connections'
|
||||
description: 'Allows users to view metadata and content for this component in flowfile queues in outbound connections and through provenance events'
|
||||
}, {
|
||||
text: 'modify the data',
|
||||
value: 'write-data',
|
||||
description: 'Allows users to empty flowfile queues in outbound connections and submit replays'
|
||||
}, {
|
||||
text: 'view provenance',
|
||||
value: 'read-provenance',
|
||||
description: 'Allows users to view provenance data generated by this component'
|
||||
description: 'Allows users to empty flowfile queues in outbound connections and submit replays through provenance events'
|
||||
}, {
|
||||
text: 'receive data via site-to-site',
|
||||
value: 'write-receive-data',
|
||||
|
@ -1312,6 +1312,9 @@
|
||||
}
|
||||
});
|
||||
|
||||
// ensure the details are selected in case other tabs we're previously selected and have been hidden
|
||||
$(tabs).first().click();
|
||||
|
||||
// update the event details
|
||||
$('#provenance-event-id').text(event.eventId);
|
||||
$('#provenance-event-time').html(nfCommon.formatValue(event.eventTime)).ellipsis();
|
||||
|
@ -390,7 +390,7 @@ public class PersistentProvenanceRepository implements ProvenanceRepository {
|
||||
return false;
|
||||
}
|
||||
|
||||
final AuthorizationResult result = eventAuthorizable.checkAuthorization(authorizer, RequestAction.READ, user, event.getAttributes());
|
||||
final AuthorizationResult result = eventAuthorizable.checkAuthorization(authorizer, RequestAction.READ, user);
|
||||
return Result.Approved.equals(result.getResult());
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ public class VolatileProvenanceRepository implements ProvenanceRepository {
|
||||
return false;
|
||||
}
|
||||
|
||||
final AuthorizationResult result = eventAuthorizable.checkAuthorization(authorizer, RequestAction.READ, user, event.getAttributes());
|
||||
final AuthorizationResult result = eventAuthorizable.checkAuthorization(authorizer, RequestAction.READ, user);
|
||||
return Result.Approved.equals(result.getResult());
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user