public void Validate_IncorrectSecret_ReturnsInvalid() { // Arrange const string secret = "wrong-secret"; const string signature = "9wLF3xAfnzyB4ilHecbxOdbf9l+q+KL+NxRZhRxI/LWUFVWNcgV7gJV1lgjVpAaqqY/zBb+hhfpDeFY7aoE+Qg=="; // Act var(_, valid) = WebhookPayloadValidator.Validate(signature, secret, "{}"); // Assert Assert.False(valid); }
public void Validate_CorrectSecret_ReturnsValid() { // Arrange const string secret = "ded6ca53-64c1-4deb-b684-83eea6f8301d"; const string signature = "9wLF3xAfnzyB4ilHecbxOdbf9l+q+KL+NxRZhRxI/LWUFVWNcgV7gJV1lgjVpAaqqY/zBb+hhfpDeFY7aoE+Qg=="; // Act var(_, valid) = WebhookPayloadValidator.Validate(signature, secret, "{}"); // Assert Assert.True(valid); }
public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post")] string data, [Table("transactions", "AzureWebJobsStorage")] CloudTable table, HttpRequestMessage req, TraceWriter log) { if (string.IsNullOrWhiteSpace(data)) { log.Error("Webhook content empty."); return(req.CreateResponse(HttpStatusCode.OK)); } // #if !DEBUG req.Headers.TryGetValues("X-Hook-Signature", out var headers); var sign = headers?.FirstOrDefault(); var secret = EnvironmentExtensions.GetEnvString("STARLING_WEBHOOK_SECRET"); var(_, valid) = WebhookPayloadValidator.Validate(sign, secret, data); if (!valid) { log.Error("Webhook signature mismatch. Rejected."); return(req.CreateResponse(HttpStatusCode.OK)); } // #endif var payload = StarlingDeserialiser.WebhookPayload(data); var existing = await table.GetExistingTransaction(payload.AccountHolderUid, payload.Content.TransactionUid); if (existing != null) { log.Warning($"Transaction {existing.RowKey} already processed on {existing.Timestamp}."); return(req.CreateResponse(HttpStatusCode.OK)); } var goalId = EnvironmentExtensions.GetEnvString("STARLING_GOAL_ID"); var remainder = (long)(Math.Abs(payload.Content.Amount) * 100 % 100); var difference = 100 - remainder; var threshold = EnvironmentExtensions.GetEnvInt("ROUND_UP_THRESHOLD"); if (remainder >= threshold) { await _httpClient.SavingsGoalsAddMoney(goalId, difference); } await table.SaveTransaction(payload.AccountHolderUid, payload.Content.TransactionUid, difference); return(req.CreateResponse(HttpStatusCode.OK)); }
public void Validate_NullEmptyWhitespaceJson_ThrowsException(string val, Type exception) { Assert.Throws(exception, () => WebhookPayloadValidator.Validate("signature", "secret", val)); }
public void Validate_NullEmptyWhitespaceSecret_ThrowsException(string value, Type exception) { // Act/Assert Assert.Throws(exception, () => WebhookPayloadValidator.Validate("signature", value, "{}")); }