Skip to content

Commit

Permalink
1.8
Browse files Browse the repository at this point in the history
 - Improved docs
 - Renamed a method
  • Loading branch information
Osiris-Team committed Mar 31, 2021
1 parent 90c9baa commit b0fcb68
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 35 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.osiris.payhook</groupId>
<artifactId>PayHook</artifactId>
<version>1.7</version>
<version>1.8</version>
<packaging>jar</packaging>

<name>PayHook</name>
Expand Down
74 changes: 45 additions & 29 deletions src/main/java/com/osiris/payhook/PayHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,46 +21,48 @@
import java.util.Map;
import java.util.Objects;

/**
* Contains methods for validating
* WebHook events/notifications and some
* utility methods.
*/
public class PayHook {
private boolean isSandboxMode = false;

/**
* Parses the header, represented as {@link Map},
* Parses the provided header {@link Map}
* into a {@link WebhookEventHeader} object and returns it.
* @throws ParseHeaderException if this operation fails.
*/
public WebhookEventHeader parseAndGetHeader(Map<String, String> headerAsMap) throws ParseHeaderException {
// Check if all keys we need exist
String transmissionId = validateKeyAndGetValue(headerAsMap, Constants.PAYPAL_HEADER_TRANSMISSION_ID);
String timestamp = validateKeyAndGetValue(headerAsMap, Constants.PAYPAL_HEADER_TRANSMISSION_TIME);
String transmissionSignature = validateKeyAndGetValue(headerAsMap, Constants.PAYPAL_HEADER_TRANSMISSION_SIG);
String certUrl = validateKeyAndGetValue(headerAsMap, Constants.PAYPAL_HEADER_CERT_URL);
String authAlgorithm = validateKeyAndGetValue(headerAsMap, Constants.PAYPAL_HEADER_AUTH_ALGO);
String transmissionId = checkKeyAndGetValue(headerAsMap, Constants.PAYPAL_HEADER_TRANSMISSION_ID);
String timestamp = checkKeyAndGetValue(headerAsMap, Constants.PAYPAL_HEADER_TRANSMISSION_TIME);
String transmissionSignature = checkKeyAndGetValue(headerAsMap, Constants.PAYPAL_HEADER_TRANSMISSION_SIG);
String certUrl = checkKeyAndGetValue(headerAsMap, Constants.PAYPAL_HEADER_CERT_URL);
String authAlgorithm = checkKeyAndGetValue(headerAsMap, Constants.PAYPAL_HEADER_AUTH_ALGO);

// Note that the webhook id and crc32 get set after the validation was run
return new WebhookEventHeader(transmissionId, timestamp, transmissionSignature, authAlgorithm, certUrl);
}

/**
* Parses the body, represented as {@link String},
* Parses the provided body {@link String}
* into a {@link JsonObject} and returns it.
* @throws ParseBodyException if this operation fails.
*/
public JsonObject parseAndGetBody(String bodyString) throws ParseBodyException {
public JsonObject parseAndGetBody(String bodyAsString) throws ParseBodyException {
try{
return JsonParser.parseString(bodyString).getAsJsonObject();
return JsonParser.parseString(bodyAsString).getAsJsonObject();
} catch (Exception e) {
throw new ParseBodyException(e.getMessage());
}
}

/**
* Checks if the provided key exists in the map and returns its value.
* The keys existence is checked by {@link String#equalsIgnoreCase(String)}, so that its case is ignored.
* Checks if the provided key exists in the provided map and returns its value. <br>
* The keys existence is checked by {@link String#equalsIgnoreCase(String)}, so that its case is ignored. <br>
* @return the value mapped to the provided key.
* @throws WebHookValidationException
*/
public String validateKeyAndGetValue(Map<String, String> map, String key) throws ParseHeaderException {
public String checkKeyAndGetValue(Map<String, String> map, String key) throws ParseHeaderException {
Objects.requireNonNull(map);
Objects.requireNonNull(key);

Expand All @@ -81,7 +83,8 @@ public String validateKeyAndGetValue(Map<String, String> map, String key) throws
}

/**
* See {@link #validateWebhookEvent(WebhookEvent)} (WebHookEvent)} for details.
* Creates a new {@link WebhookEvent} and validates it. <br>
* See {@link #validateWebhookEvent(WebhookEvent)} for details. <br>
* @param validId your webhooks valid id. Get it from here: https://developer.paypal.com/developer/applications/
* @param validTypes your webhooks valid types/names. Here is a full list: https://developer.paypal.com/docs/api-basics/notifications/webhooks/event-names/
* @param header the http messages header as string.
Expand All @@ -92,16 +95,20 @@ public void validateWebhookEvent(String validId, List<String> validTypes, Webhoo
}

/**
* Performs various checks to see if the received {@link WebhookEvent} is valid or not.
* Performed checks:
* Is this events name/type in the valid events list?
* Are this events certificates valid?
* Is this events data/transmission-signature valid?
* Do the webhook ids match?
* @param event
* @return true if the webhook event is valid
* @throws WebHookValidationException if validation failed. IMPORTANT: MESSAGE MAY CONTAIN SENSITIVE INFORMATION!
* @throws ParseBodyException
* Validate the provided {@link WebhookEvent}.<br>
* Throws an {@link Exception} if the validation fails. <br>
* Performed checks: <br>
* <ul>
* <li>Is the name/type valid?</li>
* <li>Are the certificates valid?</li>
* <li>Is the data/transmission-signature valid? (not in sandbox-mode)</li>
* <li>Do the webhook ids match? (not in sandbox-mode)</li>
* </ul>
* Note: Since the transmission-signature is <u>not</u> decoded in sandbox-mode
* {@link WebhookEventHeader#getWebhookId()} and {@link WebhookEventHeader#getCrc32()}
* will return encoded values, that are <u>not</u> readable.
* @param event The {@link WebhookEvent} to validate.
* @throws WebHookValidationException <b style='color:red' >IMPORTANT: MESSAGE MAY CONTAIN SENSITIVE INFORMATION!</b>
*/
public void validateWebhookEvent(WebhookEvent event) throws WebHookValidationException, ParseBodyException, IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
WebhookEventHeader header = event.getHeader();
Expand Down Expand Up @@ -177,10 +184,9 @@ public void validateWebhookEvent(WebhookEvent event) throws WebHookValidationExc
}

/**
* Formats all of the WebHooks information to a String and returns it.
* @param webHookEvent
* Formats all of the {@link WebhookEvent} information to a {@link String} and returns it.
*/
public String getWebhookAsString(WebhookEvent webHookEvent) {
public String getWebhookEventAsString(WebhookEvent webHookEvent) {
Objects.requireNonNull(webHookEvent);

StringBuilder stringBuilder = new StringBuilder();
Expand Down Expand Up @@ -214,10 +220,20 @@ public String getWebhookAsString(WebhookEvent webHookEvent) {
return stringBuilder.toString();
}

/**
* See {@link PayHook#setSandboxMode(boolean)} for details.
*/
public boolean isSandboxMode() {
return isSandboxMode;
}

/**
* Enable/Disable the sandbox-mode. <br>
* Disabled by default. <br>
* If enabled some validation checks, which only succeed for
* live applications, wont be done. <br>
* See {@link PayHook#validateWebhookEvent(WebhookEvent)} for details.
*/
public void setSandboxMode(boolean sandboxMode) {
isSandboxMode = sandboxMode;
}
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/com/osiris/payhook/WebhookEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

import java.util.List;


/**
* The in-memory representation of a Webhook event/notification. <br>
* Can be validated through {@link PayHook#validateWebhookEvent(WebhookEvent)}.
*/
public class WebhookEvent {
private String validWebhookId;
private List<String> validTypesList;
Expand All @@ -15,7 +20,8 @@ public class WebhookEvent {
private boolean isValid = false;

/**
* The in-memory representation of a webhook event.
* The in-memory representation of a Webhook event/notification. <br>
* Can be validated through {@link PayHook#validateWebhookEvent(WebhookEvent)}.
* @param validWebhookId your webhooks valid id. Get it from here: https://developer.paypal.com/developer/applications/
* @param validTypesList your webhooks valid types/names. Here is a full list: https://developer.paypal.com/docs/api-basics/notifications/webhooks/event-names/
* @param header the http messages header as {@link WebhookEventHeader}.
Expand Down
26 changes: 22 additions & 4 deletions src/main/java/com/osiris/payhook/WebhookEventHeader.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package com.osiris.payhook;

import java.util.Map;

/**
* Contains the {@link WebhookEvent}s headers
* essential information for its validation. <br>
* Can be created thorough {@link PayHook#parseAndGetHeader(Map)}.
*/
public class WebhookEventHeader {
private String transmissionId;
private String timestamp;
Expand All @@ -9,6 +16,11 @@ public class WebhookEventHeader {
private String authAlgorithm;
private String certUrl;

/**
* Contains the {@link WebhookEvent}s headers
* essential information for its validation.
* Can be created thorough {@link PayHook#parseAndGetHeader(Map)}.
*/
public WebhookEventHeader(String transmissionId, String timestamp, String transmissionSignature, String authAlgorithm, String certUrl) {
this.transmissionId = transmissionId;
this.timestamp = timestamp;
Expand Down Expand Up @@ -36,27 +48,33 @@ public String getTimestamp() {
}

/**
* IMPORTANT: SINCE THE WEBHOOK ID IS INSIDE THE ENCRYPTED TRANSMISSION SIGNATURE, THIS RETURNS NULL
* The ID of the webhook resource for the destination URL to which PayPal delivers the event notification. <br>
* IMPORTANT: SINCE THE WEBHOOK-ID IS INSIDE THE ENCODED TRANSMISSION-SIGNATURE, THIS RETURNS NULL
* UNLESS YOU SUCCESSFULLY EXECUTED {@link PayHook#validateWebhookEvent(WebhookEvent)} ONCE BEFORE!
* The ID of the webhook resource for the destination URL to which PayPal delivers the event notification.
*/
public String getWebhookId() {
return webhookId;
}

/**
* See {@link WebhookEventHeader#getWebhookId()} for details.
*/
public void setWebhookId(String webhookId) {
this.webhookId = webhookId;
}

/**
* IMPORTANT: SINCE THE CRC32 IS INSIDE THE ENCRYPTED TRANSMISSION SIGNATURE, THIS RETURNS NULL
* The Cyclic Redundancy Check (CRC32) checksum for the body of the HTTP payload. <br>
* IMPORTANT: SINCE THE CRC32 IS INSIDE THE ENCODED TRANSMISSION-SIGNATURE, THIS RETURNS NULL
* UNLESS YOU SUCCESSFULLY EXECUTED {@link PayHook#validateWebhookEvent(WebhookEvent)} ONCE BEFORE!
* The Cyclic Redundancy Check (CRC32) checksum for the body of the HTTP payload.
*/
public String getCrc32() {
return crc32;
}

/**
* See {@link WebhookEventHeader#getCrc32()} for details.
*/
public void setCrc32(String crc32) {
this.crc32 = crc32;
}
Expand Down

0 comments on commit b0fcb68

Please sign in to comment.