Skip to content
Snippets Groups Projects
Commit 86e28790 authored by Klaus Fischer's avatar Klaus Fischer
Browse files

Callback verification done

parent 09b0be66
No related branches found
No related tags found
1 merge request!6Routing Api
......@@ -202,27 +202,34 @@ public class Subscriber : FitConnectClient,
Logger?.LogInformation("Submission completed {status}", result);
}
public static string VerifyCallback(string callbackSecret,
long timestamp, string body) {
if (timestamp < DateTime.Now.AddMinutes(-5).ToEpochTime())
throw new ArgumentException("Request is too old");
var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(callbackSecret))
.ComputeHash(Encoding.UTF8.GetBytes($"{timestamp}.{body}"));
return Convert.ToHexString(hmac).ToLower();
}
public static bool VerifyCallback(string callbackSecret, HttpRequest request) {
if (!request.Headers.ContainsKey("callback-timestamp"))
throw new ArgumentException("Missing callback-timestamp header");
var timeStampString = request.Headers["callback-timestamp"].ToString();
var timestamp = long.Parse(timeStampString);
if (!long.TryParse(timeStampString, out var timestamp)) {
throw new ArgumentException("Invalid callback-timestamp header");
}
if (timestamp < DateTime.Now.AddMinutes(-5).ToEpochTime())
throw new ArgumentException("Request is too old");
var authentication = request.Headers["callback-authentication"];
using var requestStream = request.Body;
var content = new StreamReader(requestStream).ReadToEnd().Trim();
var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(callbackSecret))
.ComputeHash(Encoding.UTF8.GetBytes($"{timeStampString}.{content}"));
var hmacString = Convert.ToHexString(hmac);
if (hmacString != authentication)
var result = VerifyCallback(callbackSecret, timestamp, content);
if (result != authentication)
throw new ArgumentException("Request is not authentic");
return true;
}
......
......@@ -49,7 +49,7 @@ public class CallbackTest {
// };
var headers = new HeaderDictionary(new Dictionary<string, StringValues>() {
{ "callback-timestamp", DateTime.Now.ToEpochTime().ToString() }, {
{ "callback-timestamp", "1672527599" }, {
"callback-authentication",
"798cd0edb70c08e5b32aa8a18cbbc8ff6b3078c51af6d011ff4e32e470c746234fc4314821fe5185264b029e962bd37de33f3b9fc5f1a93c40ce6672845e90df"
}
......@@ -68,10 +68,25 @@ public class CallbackTest {
_callbackSecret = MockContainer.Container.Create().Resolve<MockSettings>().CallbackSecret;
}
[Test]
public void ValidRequest_WithSingeValues() {
// Arrange
//Act
var authentication = FitConnect.Subscriber.VerifyCallback(_callbackSecret, 1672527599,
"{\"type\":\"https://schema.fitko.de/fit-connect/submission-api/callbacks/new-submissions\",\"submissionIds\":[\"f39ab143-d91a-474a-b69f-b00f1a1873c2\"]}"
);
// Assert
authentication.Should()
.Be(
"798cd0edb70c08e5b32aa8a18cbbc8ff6b3078c51af6d011ff4e32e470c746234fc4314821fe5185264b029e962bd37de33f3b9fc5f1a93c40ce6672845e90df");
}
[Test]
public void ValidRequest() {
// Assert
FitConnect.Subscriber.VerifyCallback(_callbackSecret,Request).Should().Be(true);
FitConnect.Subscriber.VerifyCallback(_callbackSecret, Request).Should().Be(true);
}
[Test]
......@@ -81,7 +96,9 @@ public class CallbackTest {
// Atc
// Assert
Assert.Throws<ArgumentException>(() => { FitConnect.Subscriber.VerifyCallback(_callbackSecret,Request); })
Assert.Throws<ArgumentException>(() => {
FitConnect.Subscriber.VerifyCallback(_callbackSecret, Request);
})
.Message.Should().Be("Request is too old");
}
......@@ -93,7 +110,9 @@ public class CallbackTest {
// Atc
// Assert
Assert.Throws<ArgumentException>(() => { FitConnect.Subscriber.VerifyCallback(_callbackSecret,Request); })
Assert.Throws<ArgumentException>(() => {
FitConnect.Subscriber.VerifyCallback(_callbackSecret, Request);
})
.Message.Should().Be("Request is not authentic");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment