protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SlackSignedSecretRequirement requirement) { string configuredSecret = GetConfiguredSecret(); if (string.IsNullOrWhiteSpace(configuredSecret)) { throw new ArgumentException("The configured secret could not be retrieved. Authorization cannot occur."); } var request = ContextAccessor.HttpContext.Request; string requestSignature = request.Headers["X-Slack-Signature"]; string requestTimestamp = request.Headers["X-Slack-Request-Timestamp"]; /* * 🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥 * ⚙️ ⚙️ * 🌻 ☞ B A S I C V A L I D A T I O N ☜ 🌻 * ⚙️ ⚙️ * ✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️ */ { var theTwoThingsWeNeed = new[] { requestSignature, requestTimestamp }; if (theTwoThingsWeNeed.Any(thing => string.IsNullOrWhiteSpace(thing))) { return(Task.CompletedTask); } if (!long.TryParse(requestTimestamp, out long ticks)) { return(Task.CompletedTask); } if (!SlackSignatureUtilities.IsTimestampAboutNow(ticks, GetUtcNow())) { return(Task.CompletedTask); } } /* * 🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥🚦🚥 * ⚙️ ⚙️ * 🌻 ☞ S I G V E R I F I C A T I O N ☜ 🌻 * ⚙️ ⚙️ * ✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️❌✔️ */ { string requestBody = null; using (var reader = new BeKindPleaseRewindStreamReader(request.Body)) { requestBody = reader.ReadToEnd(); } string computedSignature = SlackSignatureUtilities.ComputeSignature( timestamp: requestTimestamp, body: requestBody, secret: configuredSecret); if (string.Compare(computedSignature, requestSignature, ignoreCase: true) != 0) { return(Task.CompletedTask); } } context.Succeed(requirement); return(Task.CompletedTask); }
public void RewindsOnDispose() { long streamPos = -1; using (var stream = new MemoryStream(Encoding.UTF8.GetBytes("Lipbalm Oram"))) using (var streamReader = new BeKindPleaseRewindStreamReader( stream: stream, onDispose: s => streamPos = s.Position)) { streamReader.ReadToEnd(); } Assert.Equal(0, streamPos); }