Skip to content

Commit

Permalink
Make hmacSha256SigningSecret optional and settable by users (DEV-2470…
Browse files Browse the repository at this point in the history
…2) (#73)
  • Loading branch information
johnlcox authored Apr 3, 2024
1 parent a95fce0 commit 19f97f4
Show file tree
Hide file tree
Showing 25 changed files with 310 additions and 923 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import com.backblaze.b2.client.structures.B2DownloadAuthorization;
import com.backblaze.b2.client.structures.B2DownloadByIdRequest;
import com.backblaze.b2.client.structures.B2DownloadByNameRequest;
import com.backblaze.b2.client.structures.B2EventNotificationRuleForRequest;
import com.backblaze.b2.client.structures.B2EventNotificationRule;
import com.backblaze.b2.client.structures.B2FileVersion;
import com.backblaze.b2.client.structures.B2FinishLargeFileRequest;
import com.backblaze.b2.client.structures.B2GetBucketNotificationRulesRequest;
Expand Down Expand Up @@ -1119,7 +1119,7 @@ default String getDownloadByNameUrl(String bucketName,
* @throws B2Exception if there's any trouble.
*/
default B2SetBucketNotificationRulesResponse setBucketNotificationRules(String bucketId,
List<B2EventNotificationRuleForRequest> eventNotificationRules) throws B2Exception {
List<B2EventNotificationRule> eventNotificationRules) throws B2Exception {
return setBucketNotificationRules(B2SetBucketNotificationRulesRequest.builder(bucketId, eventNotificationRules).build());
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,34 @@ public String toString() {

/**
* Create a new EventNotification from JSON content with signature check.
*
* @param json - The JSON content to create an B2EventNotification object from. The byte array should be UTF-8 encoded
* @return The B2EventNotification object
* @throws B2JsonException - If the content is not valid JSON
*/
public static B2EventNotification parse(byte[] json) throws IOException, B2JsonException {
B2Preconditions.checkArgumentIsNotNull(json, "json");
B2Preconditions.checkArgument(json.length > 0);

return B2Json.get().fromJson(json , B2EventNotification.class);
}

/**
* Create a new EventNotification from JSON content with signature check.
*
* @param json - The JSON content to create an B2EventNotification object from.
* @return The B2EventNotification object
* @throws B2JsonException - If the content is not valid JSON
*/
public static B2EventNotification parse(String json) throws B2JsonException {
B2Preconditions.checkArgument(!B2StringUtil.isEmpty(json), "json is required");

return B2Json.get().fromJson(json, B2EventNotification.class);
}

/**
* Create a new EventNotification from JSON content with signature check.
*
* @param json - The JSON content to create an B2EventNotification object from. The byte array should be UTF-8 encoded
* @param signatureFromHeader - The value of the X-Bz-Event-Notification-Signature header
* @param signingSecret - The secret for computing the signature.
Expand All @@ -75,14 +103,17 @@ public static B2EventNotification parse(byte[] json,
throws B2JsonException, IOException, B2SignatureVerificationException {
B2Preconditions.checkArgumentIsNotNull(json, "json");
B2Preconditions.checkArgument(json.length > 0);
B2Preconditions.checkArgumentIsNotNull(signatureFromHeader, "signatureFromHeader");
B2Preconditions.checkArgumentIsNotNull(signingSecret, "signingSecret");
SignatureUtils.verifySignature(json, signatureFromHeader, signingSecret);

// Only validate the signature if signature and secret are both provided
if (signatureFromHeader != null && signingSecret != null) {
SignatureUtils.verifySignature(json, signatureFromHeader, signingSecret);
}
return B2Json.get().fromJson(json , B2EventNotification.class);
}

/**
* Create a new EventNotification from JSON content with signature check.
*
* @param json - The JSON content to create an B2EventNotification object from.
* @param signatureFromHeader - The value of the X-Bz-Event-Notification-Signature header
* @param signingSecret - The secret for computing the signature.
Expand All @@ -94,12 +125,14 @@ public static B2EventNotification parse(String json,
String signatureFromHeader,
String signingSecret)
throws B2JsonException, B2SignatureVerificationException {
B2Preconditions.checkArgumentIsNotNull(json, "json");
B2Preconditions.checkArgument(json.length() > 0);
B2Preconditions.checkArgumentIsNotNull(signatureFromHeader, "signatureFromHeader");
B2Preconditions.checkArgumentIsNotNull(signingSecret, "signingSecret");
SignatureUtils.verifySignature(json.getBytes(StandardCharsets.UTF_8), signatureFromHeader, signingSecret);
return B2Json.get().fromJson(json, B2EventNotification.class);
B2Preconditions.checkArgument(!B2StringUtil.isEmpty(json), "json is required");

// Only validate the signature if signature and secret are both provided
if (signatureFromHeader != null && signingSecret != null) {
SignatureUtils.verifySignature(
json.getBytes(StandardCharsets.UTF_8), signatureFromHeader, signingSecret);
}
return B2Json.get().fromJson(json , B2EventNotification.class);
}

/*testing*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
package com.backblaze.b2.client.structures;

import com.backblaze.b2.json.B2Json;
import com.backblaze.b2.util.B2Preconditions;
import com.backblaze.b2.util.B2StringUtil;

import java.util.Comparator;
import java.util.Objects;
Expand All @@ -15,14 +13,14 @@
/**
* One rule about under what condition(s) to send notifications for events in a bucket.
*/
public class B2EventNotificationRuleForResponse implements Comparable<B2EventNotificationRuleForResponse> {
private static final Comparator<B2EventNotificationRuleForResponse> COMPARATOR = Comparator.comparing(B2EventNotificationRuleForResponse::getName)
public class B2EventNotificationRule implements Comparable<B2EventNotificationRule> {
private static final Comparator<B2EventNotificationRule> COMPARATOR = Comparator.comparing(B2EventNotificationRule::getName)
.thenComparing(rule -> String.join(",", rule.getEventTypes()))
.thenComparing(B2EventNotificationRuleForResponse::getObjectNamePrefix)
.thenComparing(B2EventNotificationRule::getObjectNamePrefix)
.thenComparing(rule -> rule.getTargetConfiguration().toString())
.thenComparing(B2EventNotificationRuleForResponse::isEnabled)
.thenComparing(B2EventNotificationRuleForResponse::isSuspended)
.thenComparing(B2EventNotificationRuleForResponse::getSuspensionReason);
.thenComparing(B2EventNotificationRule::isEnabled)
.thenComparing(B2EventNotificationRule::isSuspended)
.thenComparing(B2EventNotificationRule::getSuspensionReason);

/**
* A name for identifying the rule. Names must be unique within a bucket.
Expand Down Expand Up @@ -52,7 +50,7 @@ public class B2EventNotificationRuleForResponse implements Comparable<B2EventNot
* The target configuration for the event notification.
*/
@B2Json.required
private final B2EventNotificationTargetConfigurationForResponse targetConfiguration;
private final B2EventNotificationTargetConfiguration targetConfiguration;

/**
* Indicates if the rule is enabled.
Expand All @@ -63,8 +61,8 @@ public class B2EventNotificationRuleForResponse implements Comparable<B2EventNot
/**
* Indicates if the rule is suspended.
*/
@B2Json.required
private final boolean isSuspended;
@B2Json.optional
private final Boolean isSuspended;

/**
* If isSuspended is true, specifies the reason the rule was
Expand All @@ -74,18 +72,13 @@ public class B2EventNotificationRuleForResponse implements Comparable<B2EventNot
private final String suspensionReason;

@B2Json.constructor
public B2EventNotificationRuleForResponse(String name,
TreeSet<String> eventTypes,
String objectNamePrefix,
B2EventNotificationTargetConfigurationForResponse targetConfiguration,
boolean isEnabled,
boolean isSuspended,
String suspensionReason) {

B2Preconditions.checkArgument(
!isSuspended || !B2StringUtil.isEmpty(suspensionReason),
"A suspension reason is required if isSuspended is true"
);
public B2EventNotificationRule(String name,
TreeSet<String> eventTypes,
String objectNamePrefix,
B2EventNotificationTargetConfiguration targetConfiguration,
boolean isEnabled,
Boolean isSuspended,
String suspensionReason) {

this.name = name;
this.eventTypes = new TreeSet<>(eventTypes);
Expand All @@ -96,12 +89,12 @@ public B2EventNotificationRuleForResponse(String name,
this.suspensionReason = suspensionReason;
}

public B2EventNotificationRuleForResponse(String name,
TreeSet<String> eventTypes,
String objectNamePrefix,
B2EventNotificationTargetConfigurationForResponse targetConfiguration,
boolean isEnabled) {
this(name, eventTypes, objectNamePrefix, targetConfiguration, isEnabled, false, null);
public B2EventNotificationRule(String name,
TreeSet<String> eventTypes,
String objectNamePrefix,
B2EventNotificationTargetConfiguration targetConfiguration,
boolean isEnabled) {
this(name, eventTypes, objectNamePrefix, targetConfiguration, isEnabled, null, null);
}

public String getName() {
Expand All @@ -116,7 +109,7 @@ public String getObjectNamePrefix() {
return objectNamePrefix;
}

public B2EventNotificationTargetConfigurationForResponse getTargetConfiguration() {
public B2EventNotificationTargetConfiguration getTargetConfiguration() {
return targetConfiguration;
}

Expand All @@ -136,13 +129,13 @@ public String getSuspensionReason() {
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final B2EventNotificationRuleForResponse that = (B2EventNotificationRuleForResponse) o;
final B2EventNotificationRule that = (B2EventNotificationRule) o;
return isEnabled == that.isEnabled &&
isSuspended == that.isSuspended &&
name.equals(that.name) &&
eventTypes.equals(that.eventTypes) &&
objectNamePrefix.equals(that.objectNamePrefix) &&
targetConfiguration.equals(that.targetConfiguration) &&
Objects.equals(isSuspended, that.isSuspended) &&
Objects.equals(suspensionReason, that.suspensionReason);
}

Expand All @@ -161,7 +154,7 @@ public int hashCode() {

@Override
public String toString() {
return "B2EventNotificationRuleForResponse{" +
return "B2EventNotificationRule{" +
"name='" + name + '\'' +
", eventTypes=" + eventTypes +
", objectNamePrefix='" + objectNamePrefix + '\'' +
Expand All @@ -176,7 +169,7 @@ public String toString() {
* Rules are sorted by name first, and then additional attributes if necessary.
*/
@Override
public int compareTo(B2EventNotificationRuleForResponse r) {
public int compareTo(B2EventNotificationRule r) {
return COMPARATOR.compare(this, r);
}
}
Loading

0 comments on commit 19f97f4

Please sign in to comment.