From 86bf97bde3b6b0083bed3895e990e2a461ef4ea8 Mon Sep 17 00:00:00 2001 From: Thorben Betten <thorben.betten@open-xchange.com> Date: Wed, 4 Oct 2023 21:11:39 +0200 Subject: [PATCH] Fixed: MWB-2336: Aligned naming of settings to the ones used by UI --- .../WebhooksPushNotificationTransport.java | 4 +- .../doc/examples/webhooks-template.yml | 10 ++-- .../webhooks/DefaultWebhookInfo.java | 38 ++++++------- .../openexchange/webhooks/WebhookInfo.java | 2 +- .../internal/WebhookConfigParser.java | 20 +++---- documentation/detailed_software_changes.md | 8 +-- documentation/push_notifications/webhooks.md | 12 ++--- .../javax/mail/internet/MimeMultipart.java | 53 ++++++++++--------- 8 files changed, 74 insertions(+), 73 deletions(-) diff --git a/com.openexchange.pns.transport.webhooks/src/com/openexchange/pns/transport/webhooks/WebhooksPushNotificationTransport.java b/com.openexchange.pns.transport.webhooks/src/com/openexchange/pns/transport/webhooks/WebhooksPushNotificationTransport.java index 82279acbaa7b..fcc97c92bedf 100644 --- a/com.openexchange.pns.transport.webhooks/src/com/openexchange/pns/transport/webhooks/WebhooksPushNotificationTransport.java +++ b/com.openexchange.pns.transport.webhooks/src/com/openexchange/pns/transport/webhooks/WebhooksPushNotificationTransport.java @@ -342,10 +342,10 @@ public class WebhooksPushNotificationTransport implements PushNotificationTransp } // Signing... - if (Strings.isNotEmpty(webhookInfo.getSharedSecret()) && Strings.isNotEmpty(webhookInfo.getSignatureHeaderName())) { + if (Strings.isNotEmpty(webhookInfo.getSignatureSecret()) && Strings.isNotEmpty(webhookInfo.getSignatureHeaderName())) { // Generate signature through concatenating the version number, time stamp, and payload of the notification: v1:<time-stamp>:<request-payload> StringBuilder sb = new StringBuilder(128).append('v').append(webhookInfo.getVersion()).append(':').append(timestamp).append(':').append(textMessage); - HashFunction hmacSha256 = Hashing.hmacSha256(webhookInfo.getSharedSecret().getBytes(StandardCharsets.UTF_8)); + HashFunction hmacSha256 = Hashing.hmacSha256(webhookInfo.getSignatureSecret().getBytes(StandardCharsets.UTF_8)); String signature = hmacSha256.hashBytes(sb.toString().getBytes(StandardCharsets.UTF_8)).toString(); // Construct the final header value via: t=<time-stamp>,v1=<signature> diff --git a/com.openexchange.webhooks/doc/examples/webhooks-template.yml b/com.openexchange.webhooks/doc/examples/webhooks-template.yml index 999391aa0e76..9fb67decd471 100644 --- a/com.openexchange.webhooks/doc/examples/webhooks-template.yml +++ b/com.openexchange.webhooks/doc/examples/webhooks-template.yml @@ -22,7 +22,7 @@ # required to start with same prefix. For `exact` the client-specified and configured URI for a Webhook end-point are # required to be exactly the same. `prefix` is default. # -# authorization: <authorization> +# webhookSecret: <webhook-secret> # String. The value for the "Authorization" HTTP header to pass on calling Webhook's URI. May be overridden during subscribe. # # login: <login> @@ -33,7 +33,7 @@ # String. The password part for HTTP Basic Authentication if no value for the "Authorization" HTTP header is specified. May be # overridden during subscribe. # -# sharedSecret: <shared-secret> +# signatureSecret: <signature-secret> # String. Specifies shared secret known by caller and Webhook host. Used for signing. # # version: <version> @@ -55,8 +55,8 @@ # An example using "Authorization" HTTP header mywebhook: uri: https://my.endpoint.com:8080/webhook/event - authorization: supersecret - sharedSecret: da39a3ee5e6b4b + webhookSecret: supersecret + signatureSecret: da39a3ee5e6b4b version: 1 signatureHeaderName: X-OX-Signature maxTimeToLiveMillis: 2678400000 @@ -69,6 +69,6 @@ mywebhook2: uri: https://another.endpoint.com:8080/webhook/event login: admin password: topsecret - sharedSecret: fe39a3e12e6b8a + signatureSecret: fe39a3e12e6b8a version: 1 signatureHeaderName: X-Custom-Signature diff --git a/com.openexchange.webhooks/src/com/openexchange/webhooks/DefaultWebhookInfo.java b/com.openexchange.webhooks/src/com/openexchange/webhooks/DefaultWebhookInfo.java index c823b030049a..42c6fbd937b9 100644 --- a/com.openexchange.webhooks/src/com/openexchange/webhooks/DefaultWebhookInfo.java +++ b/com.openexchange.webhooks/src/com/openexchange/webhooks/DefaultWebhookInfo.java @@ -68,7 +68,7 @@ public class DefaultWebhookInfo implements WebhookInfo { private URI uri; private String authorization; private BasicAuthCredentials basicAuthCredentials; - private String sharedSecret; + private String signatureSecret; private int version; private String signatureHeaderName; private long maxTimeToLiveMillis; @@ -104,7 +104,7 @@ public class DefaultWebhookInfo implements WebhookInfo { uri = webhookInfo.getUri(); authorization = webhookInfo.getAuthorization(); basicAuthCredentials = webhookInfo.getBasicAuthCredentials(); - sharedSecret = webhookInfo.getSharedSecret(); + signatureSecret = webhookInfo.getSignatureSecret(); version = webhookInfo.getVersion(); signatureHeaderName = webhookInfo.getSignatureHeaderName(); maxTimeToLiveMillis = webhookInfo.getMaxTimeToLiveMillis(); @@ -169,13 +169,13 @@ public class DefaultWebhookInfo implements WebhookInfo { } /** - * Sets the shared secret. + * Sets the signature secret. * - * @param sharedSecret The shared secret + * @param signatureSecret The signature secret * @return This builder */ - public Builder withSharedSecret(String sharedSecret) { - this.sharedSecret = sharedSecret; + public Builder withSignatureSecret(String signatureSecret) { + this.signatureSecret = signatureSecret; return this; } @@ -225,9 +225,9 @@ public class DefaultWebhookInfo implements WebhookInfo { } /** - * Sets the authorization header value. + * Sets the <code>"Authorization"</code> header value. * - * @param authorization The authorization to set + * @param authorization The <code>"Authorization"</code> header value to set * @return This builder */ public Builder withAuthorization(String authorization) { @@ -258,10 +258,10 @@ public class DefaultWebhookInfo implements WebhookInfo { if (uri == null) { throw new IllegalArgumentException("Webhook URI must not be null"); } - if (Strings.isNotEmpty(sharedSecret) && Strings.isEmpty(signatureHeaderName)) { + if (Strings.isNotEmpty(signatureSecret) && Strings.isEmpty(signatureHeaderName)) { throw new IllegalArgumentException("The name of the signature header must not be null or empty if a shared secret is given"); } - return new DefaultWebhookInfo(webhookId, uri, authorization, basicAuthCredentials, sharedSecret, version, signatureHeaderName, maxTimeToLiveMillis, maxNumberOfSubscriptionsPerUser, allowSharedUri, uriValidationMode); + return new DefaultWebhookInfo(webhookId, uri, authorization, basicAuthCredentials, signatureSecret, version, signatureHeaderName, maxTimeToLiveMillis, maxNumberOfSubscriptionsPerUser, allowSharedUri, uriValidationMode); } } @@ -271,7 +271,7 @@ public class DefaultWebhookInfo implements WebhookInfo { private final URI uri; private final String authorization; private final BasicAuthCredentials basicAuthCredentials; - private final String sharedSecret; + private final String signatureSecret; private final int version; private final String signatureHeaderName; private final long maxTimeToLiveMillis; @@ -285,9 +285,9 @@ public class DefaultWebhookInfo implements WebhookInfo { * * @param webhookId The Webhook identifier * @param uri The Webhook's URI - * @param authorization The authorization or <code>null</code> + * @param authorization The <code>"Authorization"</code> header value or <code>null</code> * @param basicAuthCredentials The HTTP Basic Authentication credentials or <code>null</code> - * @param sharedSecret The shared secret between client and end-point host + * @param signatureSecret The signature secret shared between client and end-point host * @param version The version number * @param signatureHeaderName The name of the signature header * @param maxTimeToLiveMillis The max. time to live in milliseconds @@ -295,13 +295,13 @@ public class DefaultWebhookInfo implements WebhookInfo { * @param allowSharedUri <code>true</code> if shared URIs are allowed, <code>false</code> otherwise * @param uriValidationMode The URI validation mode */ - private DefaultWebhookInfo(String webhookId, URI uri, String authorization, BasicAuthCredentials basicAuthCredentials, String sharedSecret, int version, String signatureHeaderName, long maxTimeToLiveMillis, int maxNumberOfSubscriptionsPerUser, boolean allowSharedUri, WebhookUriValidationMode uriValidationMode) { + private DefaultWebhookInfo(String webhookId, URI uri, String authorization, BasicAuthCredentials basicAuthCredentials, String signatureSecret, int version, String signatureHeaderName, long maxTimeToLiveMillis, int maxNumberOfSubscriptionsPerUser, boolean allowSharedUri, WebhookUriValidationMode uriValidationMode) { super(); this.webhookId = webhookId; this.uri = uri; this.authorization = authorization; this.basicAuthCredentials = basicAuthCredentials; - this.sharedSecret = sharedSecret; + this.signatureSecret = signatureSecret; this.version = version; this.signatureHeaderName = signatureHeaderName; this.maxTimeToLiveMillis = maxTimeToLiveMillis; @@ -337,8 +337,8 @@ public class DefaultWebhookInfo implements WebhookInfo { } @Override - public String getSharedSecret() { - return sharedSecret; + public String getSignatureSecret() { + return signatureSecret; } @Override @@ -423,8 +423,8 @@ public class DefaultWebhookInfo implements WebhookInfo { if (basicAuthCredentials != null) { sb.append("basicAuthCredentials=").append(basicAuthCredentials).append(", "); } - if (sharedSecret != null) { - sb.append("sharedSecret=").append(sharedSecret).append(", "); + if (signatureSecret != null) { + sb.append("signatureSecret=").append(signatureSecret).append(", "); } sb.append("version=").append(version).append(", "); if (signatureHeaderName != null) { diff --git a/com.openexchange.webhooks/src/com/openexchange/webhooks/WebhookInfo.java b/com.openexchange.webhooks/src/com/openexchange/webhooks/WebhookInfo.java index e235dc2f1b4a..d1ddf196b537 100644 --- a/com.openexchange.webhooks/src/com/openexchange/webhooks/WebhookInfo.java +++ b/com.openexchange.webhooks/src/com/openexchange/webhooks/WebhookInfo.java @@ -68,7 +68,7 @@ public interface WebhookInfo { * * @return The shared secret */ - String getSharedSecret(); + String getSignatureSecret(); /** * Gets the name of the signature header. diff --git a/com.openexchange.webhooks/src/com/openexchange/webhooks/internal/WebhookConfigParser.java b/com.openexchange.webhooks/src/com/openexchange/webhooks/internal/WebhookConfigParser.java index 0a0925937097..d851b0bd95a7 100644 --- a/com.openexchange.webhooks/src/com/openexchange/webhooks/internal/WebhookConfigParser.java +++ b/com.openexchange.webhooks/src/com/openexchange/webhooks/internal/WebhookConfigParser.java @@ -43,10 +43,10 @@ import com.openexchange.webhooks.WebhookUriValidationMode; * webhook-test: * enabled: true * uri: http://localhost:8009/preliminary/webhook-test/event - * authorization: + * webhookSecret: * login: th0rb3n * password: secret - * sharedSecret: da39a3ee5e6b4b + * signatureSecret: da39a3ee5e6b4b * </pre> * * @author <a href="mailto:thorben.betten@open-xchange.com">Thorben Betten</a> @@ -82,10 +82,10 @@ public final class WebhookConfigParser { * webhook-test: * enabled: true * uri: http://localhost:8009/preliminary/webhook-test/event - * authorization: + * webhookSecret: * login: admin * password: secret - * sharedSecret: da39a3ee5e6b4b + * webhookSecret: da39a3ee5e6b4b * version: 1 * * webhook-anothertest: @@ -94,7 +94,7 @@ public final class WebhookConfigParser { * authorization: * login: anotheradmin * password: anothersecret - * sharedSecret: 1356a3ee5e6b4b + * webhookSecret: 1356a3ee5e6b4b * version: 1 * * ... @@ -164,10 +164,10 @@ public final class WebhookConfigParser { * webhook-test: * enabled: true * uri: http://localhost:8009/preliminary/webhook-test/event - * authorization: + * webhookSecret: * login: admin * password: secret - * sharedSecret: da39a3ee5e6b4b + * webhookSecret: da39a3ee5e6b4b * version: 1 * </pre> * @@ -187,10 +187,10 @@ public final class WebhookConfigParser { return Optional.empty(); } - String authorization = (String) values.get("authorization"); + String authorization = (String) values.get("webhookSecret"); String login = (String) values.get("login"); String password = (String) values.get("password"); - String sharedSecret = (String) values.get("sharedSecret"); + String signatureSecret = (String) values.get("signatureSecret"); Integer version = (Integer) values.get("version"); String signatureHeaderName = (String) values.get("signatureHeaderName"); Number maxTimeToLiveMillis = (Number) values.get("maxTimeToLiveMillis"); @@ -202,7 +202,7 @@ public final class WebhookConfigParser { .withUri(uri) .withAuthorization(authorization) .withBasicAuthCredentials(BasicAuthCredentials.getBasicAuthCredentialsFor(login, password)) - .withSharedSecret(Strings.isEmpty(sharedSecret) ? null : sharedSecret.trim()) + .withSignatureSecret(Strings.isEmpty(signatureSecret) ? null : signatureSecret.trim()) .withVersion(version == null ? WebhookInfo.DEFAULT_VERSION : version.intValue()) .withSignatureHeaderName(Strings.isEmpty(signatureHeaderName) ? WebhookInfo.DEFAULT_SIGNATURE_HEADER_NAME : signatureHeaderName.trim()) .withMaxTimeToLiveMillis(maxTimeToLiveMillis == null ? 0L : maxTimeToLiveMillis.longValue()) diff --git a/documentation/detailed_software_changes.md b/documentation/detailed_software_changes.md index 5f5ca7b8ca7e..f4c3bd483b68 100644 --- a/documentation/detailed_software_changes.md +++ b/documentation/detailed_software_changes.md @@ -151,7 +151,7 @@ Added new configuration file `webhooks.yml` containing the static configurations required to start with same prefix. For `exact` the client-specified and configured URI for a Webhook end-point are required to be exactly the same. `prefix` is default. - authorization: <authorization> + webhookSecret: <webhook-secret> String. The value for the "Authorization" HTTP header to pass on calling Webhook's URI. May be overridden during subscribe. login: <login> @@ -160,7 +160,7 @@ Added new configuration file `webhooks.yml` containing the static configurations password: <password> String. The password part for HTTP Basic Authentication if no value for the "Authorization" HTTP header is specified. May be overridden during subscribe. - sharedSecret: <shared-secret> + signatureSecret: <signature-secret> String. Specifies shared secret known by caller and Webhook host. Used for signing. version: <version> @@ -188,8 +188,8 @@ Added new configuration file `webhooks.yml` containing the static configurations ``` mywebhook: uri: https://my.endpoint.com:8080/webhook/event - authorization: supersecret - sharedSecret: da39a3ee5e6b4b + webhookSecret: supersecret + signatureSecret: da39a3ee5e6b4b version: 1 signatureHeaderName: X-OX-Signature maxTimeToLiveMillis: 2678400000 diff --git a/documentation/push_notifications/webhooks.md b/documentation/push_notifications/webhooks.md index c334020dbc90..f6cde178b280 100644 --- a/documentation/push_notifications/webhooks.md +++ b/documentation/push_notifications/webhooks.md @@ -17,13 +17,13 @@ Then under that identifier the Webhook properties are described: The URI end-point of the Webhook. May be overridden during subscribe depending on "uriValidationMode". * `uriValidationMode` Specifies how the possible client-specified URI for a Webhook end-point is supposed to be validated against the URIfrom configured Webhook end-point. Possible values: `none`, `prefix`, and `exact`. For `none` no requirements given. Any client-specified URI is accepted. For `prefix` he client-specified and configured URI for a Webhook end-point are required to start with same prefix. For `exact` the client-specified and configured URI for a Webhook end-point are required to be exactly the same. `prefix` is default. -* `authorization` +* `webhookSecret` The value for the "Authorization" HTTP header to pass on calling Webhook's URI. May be overridden during subscribe. * `login` The login part for HTTP Basic Authentication if no value for the "Authorization" HTTP header is specified. May be overridden during subscribe. * `password` The password part for HTTP Basic Authentication if no value for the "Authorization" HTTP header is specified. May be overridden during subscribe. -* `sharedSecret` +* `signatureSecret` Specifies shared secret known by caller and Webhook host. Used for signing. * `version` Specifies the version of the Webhook. Used for signing. @@ -42,8 +42,8 @@ Example: # An example using "Authorization" HTTP header mywebhook: uri: https://my.endpoint.com:8080/webhook/event - authorization: supersecret - sharedSecret: da39a3ee5e6b4b + webhookSecret: supersecret + signatureSecret: da39a3ee5e6b4b version: 1 signatureHeaderName: X-OX-Signature maxTimeToLiveMillis: 2678400000 @@ -56,7 +56,7 @@ mywebhook2: uri: https://my.another-endpoint.com:8080/webhook2/event login: admin password: topsecret - sharedSecret: fe39a3e12e6b8a + signatureSecret: fe39a3e12e6b8a version: 1 signatureHeaderName: X-Custom-Signature uriValidationMode: exact @@ -74,7 +74,7 @@ h3. Full example ``` webhook-test: uri: https://webhook-test.example.com/webhook2/event - sharedSecret: da39a3ee5e6b4b + signatureSecret: da39a3ee5e6b4b uriValidationMode: prefix ``` diff --git a/javax.mail/src/javax/mail/internet/MimeMultipart.java b/javax.mail/src/javax/mail/internet/MimeMultipart.java index 289a5e789943..ada506150b82 100644 --- a/javax.mail/src/javax/mail/internet/MimeMultipart.java +++ b/javax.mail/src/javax/mail/internet/MimeMultipart.java @@ -437,11 +437,11 @@ public class MimeMultipart extends Multipart { * Get the MimeBodyPart referred to by the given ContentID (CID). * Returns null if the part is not found. * - * @param CID the ContentID of the desired part + * @param contentId the <code>Content-ID</code> of the desired part * @return the Part * @exception MessagingException for failures */ - public synchronized BodyPart getBodyPart(String CID) + public synchronized BodyPart getBodyPart(String contentId) throws MessagingException { parse(); @@ -449,8 +449,8 @@ public class MimeMultipart extends Multipart { for (int i = 0; i < count; i++) { MimeBodyPart part = (MimeBodyPart)getBodyPart(i); String s = part.getContentID(); - if (s != null && s.equals(CID)) - return part; + if (s != null && s.equals(contentId)) + return part; } return null; } @@ -467,7 +467,7 @@ public class MimeMultipart extends Multipart { * of existing values */ @Override - public boolean removeBodyPart(BodyPart part) throws MessagingException { + public synchronized boolean removeBodyPart(BodyPart part) throws MessagingException { parse(); return super.removeBodyPart(part); } @@ -485,7 +485,7 @@ public class MimeMultipart extends Multipart { * @exception MessagingException for other failures */ @Override - public void removeBodyPart(int index) throws MessagingException { + public synchronized void removeBodyPart(int index) throws MessagingException { parse(); super.removeBodyPart(index); } @@ -677,14 +677,15 @@ public class MimeMultipart extends Multipart { InputStream in = null; SharedInputStream sin = null; - long start = 0, end = 0; + long start = 0; + long end = 0; try { in = ds.getInputStream(); if (!(in instanceof ByteArrayInputStream) && !(in instanceof BufferedInputStream) && !(in instanceof SharedInputStream)) - in = new BufferedInputStream(in); + in = new BufferedInputStream(in); } catch (Exception ex) { throw new MessagingException("No inputstream from datasource", ex); } @@ -696,7 +697,7 @@ public class MimeMultipart extends Multipart { if (!ignoreExistingBoundaryParameter) { String bp = cType.getParameter("boundary"); if (bp != null) - boundary = "--" + bp; + boundary = "--" + bp; } if (boundary == null && !ignoreMissingBoundaryParameter && !ignoreExistingBoundaryParameter) @@ -718,12 +719,12 @@ public class MimeMultipart extends Multipart { for (i = line.length() - 1; i >= 0; i--) { char c = line.charAt(i); if (!(c == ' ' || c == '\t')) - break; + break; } line = line.substring(0, i + 1); if (boundary != null) { if (line.equals(boundary)) - break; + break; if (line.length() == boundary.length() + 2 && line.startsWith(boundary) && line.endsWith("--")) { line = null; // signal end of multipart @@ -760,7 +761,7 @@ public class MimeMultipart extends Multipart { } if (preamblesb != null) - preamble = preamblesb.toString(); + preamble = preamblesb.toString(); if (line == null) { if (allowEmpty) @@ -780,7 +781,7 @@ public class MimeMultipart extends Multipart { // initialize Bad Character Shift table int[] bcs = new int[256]; for (int i = 0; i < bl; i++) - bcs[bndbytes[i] & 0xff] = i + 1; + bcs[bndbytes[i] & 0xff] = i + 1; // initialize Good Suffix Shift table int[] gss = new int[bl]; @@ -815,7 +816,7 @@ public class MimeMultipart extends Multipart { start = sin.getPosition(); // skip headers while ((line = lin.readLine()) != null && line.length() > 0) - ; + ; if (line == null) { if (!ignoreMissingEndBoundary) throw new ParseException( @@ -891,7 +892,7 @@ public class MimeMultipart extends Multipart { if (b == '\n' && prevSize >= 2) { b = previnbuf[prevSize - 2]; if (b == '\r') - eolLen = 2; + eolLen = 2; } } } @@ -904,18 +905,18 @@ public class MimeMultipart extends Multipart { // matched the boundary, check for last boundary int b2 = in.read(); if (b2 == '-') { - if (in.read() == '-') { - complete = true; - done = true; - break; // ignore trailing text - } + if (in.read() == '-') { // NOSONARLINT + complete = true; + done = true; + break; // ignore trailing text + } } // skip linear whitespace while (b2 == ' ' || b2 == '\t') - b2 = in.read(); + b2 = in.read(); // check for end of line if (b2 == '\n') - break; // got it! break out of the loop + break; // got it! break out of the loop if (b2 == '\r') { in.mark(1); if (in.read() != '\n') @@ -1007,7 +1008,7 @@ public class MimeMultipart extends Multipart { private static boolean allDashes(String s) { for (int i = 0; i < s.length(); i++) { if (s.charAt(i) != '-') - return false; + return false; } return true; } @@ -1034,7 +1035,7 @@ public class MimeMultipart extends Multipart { while (len > 0) { int bsize = in.read(buf, off, len); if (bsize <= 0) // should never be zero - break; + break; off += bsize; total += bsize; len -= bsize; @@ -1046,11 +1047,11 @@ public class MimeMultipart extends Multipart { * Skip the specified number of bytes, repeatedly calling * the skip method as necessary. */ - private void skipFully(InputStream in, long offset) throws IOException { + private static void skipFully(InputStream in, long offset) throws IOException { while (offset > 0) { long cur = in.skip(offset); if (cur <= 0) - throw new EOFException("can't skip"); + throw new EOFException("can't skip"); offset -= cur; } } -- GitLab