Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

broken out NotificationParser to decouple from required use of HttpListenerRequest #65

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Riskified.SDK/Notifications/NotificationHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ public void ReceiveNotifications()
bool acionSucceeded = false;
try
{
var notificationData = HttpUtils.ParsePostRequestToObject<OrderWrapper<Notification>>(request,_authToken);
OrderNotification n = new OrderNotification(notificationData);
OrderNotification n = NotificationParser.ParseListenerRequest(request, _authToken);

responseString =
string.Format(
"<HTML><BODY>Merchant Received Notification For Order {0} with status {1} and description {2}</BODY></HTML>",
Expand Down
24 changes: 24 additions & 0 deletions Riskified.SDK/Notifications/NotificationParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Net;
using Riskified.SDK.Model;
using Riskified.SDK.Model.Internal;
using Riskified.SDK.Utils;

namespace Riskified.SDK.Notifications
{
public static class NotificationParser
{
public static string HmacHeaderName => HttpUtils.HmacHeaderName;

public static OrderNotification ParseListenerRequest(HttpListenerRequest request, string authToken)
{
var notificationData = HttpUtils.ParsePostRequestToObject<OrderWrapper<Notification>>(request, authToken);
return new OrderNotification(notificationData);
}

public static OrderNotification ParseRequestComponents(string hmacHeader, string requestBody, string authToken)
{
var notificationData = HttpUtils.ParsePostRequestComponentsToObject<OrderWrapper<Notification>>(hmacHeader, requestBody, authToken);
return new OrderNotification(notificationData);
}
}
}
1 change: 0 additions & 1 deletion Riskified.SDK/Orders/OrdersGateway.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Linq;
using Riskified.SDK.Exceptions;
using Riskified.SDK.Model;
using Riskified.SDK.Utils;
Expand Down
21 changes: 16 additions & 5 deletions Riskified.SDK/Utils/HttpUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ internal enum HttpBodyType
internal static class HttpUtils
{
private const string ShopDomainHeaderName = "X-RISKIFIED-SHOP-DOMAIN";
private const string HmacHeaderName = "X-RISKIFIED-HMAC-SHA256";
internal const string HmacHeaderName = "X-RISKIFIED-HMAC-SHA256";
private const int ServerApiVersion = 2;

private static readonly string AssemblyVersion;
Expand Down Expand Up @@ -233,7 +233,7 @@ internal class ErrorMessage
/// <returns>An object of type T containing data parsed from the request</returns>
/// <exception cref="RiskifiedAuthenticationException">On missing/bad HMAC signature that doesn't match the given auth token</exception>
/// <exception cref="RiskifiedTransactionException">On parsing error from string into the relevant object of type T</exception>
public static T ParsePostRequestToObject<T>(HttpListenerRequest request,string authToken) where T : class
internal static T ParsePostRequestToObject<T>(HttpListenerRequest request,string authToken) where T : class
{
if (!request.HasEntityBody)
{
Expand All @@ -243,21 +243,32 @@ public static T ParsePostRequestToObject<T>(HttpListenerRequest request,string a
T obj = JsonStringToObject<T>(postData);
return obj;
}

internal static T ParsePostRequestComponentsToObject<T>(string hmacHeader, string requestBody, string authToken) where T : class
{
if (!AuthorizeContent(hmacHeader, requestBody, authToken))
{
throw new RiskifiedAuthenticationException("Request HMAC signature was either missing or incorrect");
}
return JsonStringToObject<T>(requestBody);
}

private static string AuthorizeAndExtractContent(HttpListenerRequest request, string authToken)
{
if (!string.IsNullOrEmpty(request.Headers[HmacHeaderName]))
{
Stream s = request.InputStream;
string postData = ExtractStreamData(s);
if (string.Equals(request.Headers[HmacHeaderName], CalcHmac(postData, authToken), StringComparison.Ordinal))
var s = request.InputStream;
var postData = ExtractStreamData(s);
if (AuthorizeContent(request.Headers[HmacHeaderName], postData, authToken))
{
return postData;
}
}
throw new RiskifiedAuthenticationException("Request HMAC signature was either missing or incorrect");
}

private static bool AuthorizeContent(string expectedSignature, string postData, string authToken) => string.Equals(expectedSignature, CalcHmac(postData, authToken), StringComparison.Ordinal);

private static string ExtractStreamData(Stream stream)
{
if (stream != null)
Expand Down