Skip to content

Commit

Permalink
[#1228] Smart-channel-selection: Fix timeout exception headers; add m…
Browse files Browse the repository at this point in the history
…essage for live channel precondition failed exception

Signed-off-by: Yufei Cai <yufei.cai@bosch.io>
  • Loading branch information
yufei-cai committed Dec 9, 2021
1 parent df8f6cd commit 4bbcf3c
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -458,8 +458,7 @@ private Contextual<WithDittoHeaders> askAndBuildJsonViewWithAckForwarding(
final DistributedPub<ThingCommand<?>> pub,
final Enforcer enforcer) {

final var props = LiveResponseAndAcknowledgementForwarder.props(signal, pub.getPublisher(), sender()
);
final var props = LiveResponseAndAcknowledgementForwarder.props(signal, pub.getPublisher(), sender());
final var liveResponseForwarder = actorRefFactory.actorOf(props);
final var startTime = Instant.now();
final var responseCaster = getResponseCaster(signal, "before building JsonView")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ private static CompletionStage<ThingQueryCommandResponse<?>> applyTimeoutStrateg
final var timeoutException = GatewayCommandTimeoutException.newBuilder(timeout)
.dittoHeaders(twinResponse.getDittoHeaders()
.toBuilder()
.channel(TopicPath.Channel.LIVE.getName())
.putHeaders(getAdditionalLiveResponseHeaders(twinResponse.getDittoHeaders()))
.build())
.build();
Expand Down Expand Up @@ -919,11 +920,13 @@ static <T extends ThingCommand<T>> T authorizeByPolicyOrThrow(final Enforcer pol

final var condition = dittoHeaders.getCondition();
if (!(command instanceof CreateThing) && condition.isPresent()) {
enforceReadPermissionOnCondition(condition.get(), policyEnforcer, dittoHeaders);
enforceReadPermissionOnCondition(condition.get(), policyEnforcer, dittoHeaders,
ThingConditionFailedException.newBuilderForInsufficientPermission(dittoHeaders).build());
}
final var liveChannelCondition = dittoHeaders.getLiveChannelCondition();
if ((command instanceof ThingQueryCommand) && liveChannelCondition.isPresent()) {
enforceReadPermissionOnCondition(liveChannelCondition.get(), policyEnforcer, dittoHeaders);
enforceReadPermissionOnCondition(liveChannelCondition.get(), policyEnforcer, dittoHeaders,
ThingConditionFailedException.newBuilderForInsufficientLiveChannelPermission(dittoHeaders).build());
}

if (commandAuthorized) {
Expand All @@ -935,14 +938,15 @@ static <T extends ThingCommand<T>> T authorizeByPolicyOrThrow(final Enforcer pol

private static void enforceReadPermissionOnCondition(final String condition,
final Enforcer policyEnforcer,
final DittoHeaders dittoHeaders) {
final DittoHeaders dittoHeaders,
final DittoRuntimeException exception) {

final var authorizationContext = dittoHeaders.getAuthorizationContext();
final var rootNode = tryParseRqlCondition(condition, dittoHeaders);
final var resourceKeys = determineResourceKeys(rootNode, dittoHeaders);

if (!policyEnforcer.hasUnrestrictedPermissions(resourceKeys, authorizationContext, Permission.READ)) {
throw ThingConditionFailedException.newBuilderForInsufficientPermission(dittoHeaders).build();
throw exception;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ public final class ThingConditionFailedException extends DittoRuntimeException i
"The specified resource in the condition could not be found " +
"or the requester had insufficient permissions to access it.";

private static final String MESSAGE_FOR_INSUFFICIENT_LIVE_CHANNEL_PERMISSION =
"The specified resource in the live channel condition could not be found " +
"or the requester had insufficient permissions to access it.";

private static final String DEFAULT_DESCRIPTION = "The provided condition did not match the actual Thing state. " +
"Please check your provided condition.";

Expand Down Expand Up @@ -87,6 +91,20 @@ public static DittoRuntimeExceptionBuilder<ThingConditionFailedException> newBui
.description(DESCRIPTION_FOR_INSUFFICIENT_PERMISSION);
}

/**
* A mutable builder for when the live channel condition cannot be evaluated due to a lack of permission.
*
* @param dittoHeaders the headers to apply for the exception.
* @return the builder.
* @since 2.3.0
*/
public static DittoRuntimeExceptionBuilder<ThingConditionFailedException>
newBuilderForInsufficientLiveChannelPermission(final DittoHeaders dittoHeaders) {
return newBuilder(dittoHeaders)
.message(MESSAGE_FOR_INSUFFICIENT_LIVE_CHANNEL_PERMISSION)
.description(DESCRIPTION_FOR_INSUFFICIENT_PERMISSION);
}

/**
* Constructs a new {@code ThingConditionFailedException}
* object with the exception message extracted from the given JSON object.
Expand Down

0 comments on commit 4bbcf3c

Please sign in to comment.