-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature complete for mvp version 1 (#1)
- Loading branch information
Showing
28 changed files
with
958 additions
and
231 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
src/AuthenticationPipelineStep/AuthenticationPipelineStep.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>netcoreapp2.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="NATS.Client" Version="0.8.0" /> | ||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using NATS.Client; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Serialization; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
|
||
namespace AuthenticationPipelineStep | ||
{ | ||
public class MessageHelper | ||
{ | ||
private static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings | ||
{ | ||
ContractResolver = new CamelCasePropertyNamesContractResolver() | ||
}; | ||
|
||
public static T Deserialize<T>(string data) | ||
{ | ||
return JsonConvert.DeserializeObject<T>(data); | ||
} | ||
|
||
public static NatsMessage GetNatsMessage(Msg msg) | ||
{ | ||
return JsonConvert.DeserializeObject<NatsMessage>(Encoding.UTF8.GetString(msg.Data)); | ||
} | ||
|
||
public static string GetValue(string key, IEnumerable<KeyValuePair<string, string>> parameters) | ||
{ | ||
// force the enumeration of queryParms | ||
var parameterList = parameters.ToList(); | ||
|
||
// try to find the matching key | ||
var match = parameterList.FirstOrDefault(kv => kv.Key.Equals(key, StringComparison.OrdinalIgnoreCase)); | ||
|
||
// if we didn't find a match then just return an empty string | ||
return string.IsNullOrWhiteSpace(match.Key) ? string.Empty : match.Value; | ||
} | ||
|
||
public static byte[] PackageResponse(object data) | ||
{ | ||
return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data, SerializerSettings)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using Newtonsoft.Json; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace AuthenticationPipelineStep | ||
{ | ||
public sealed class NatsMessage | ||
{ | ||
public string Body { get; set; } | ||
public long CompletedOnUtc { get; set; } | ||
public List<KeyValuePair<string, string>> Cookies { get; set; } | ||
public string ErrorMessage { get; set; } | ||
public long ExecutionTimeMs => CompletedOnUtc - StartedOnUtc; | ||
public Dictionary<string, string> ExtendedProperties { get; set; } | ||
public string Host { get; set; } | ||
public List<KeyValuePair<string, string>> QueryParams { get; set; } | ||
public List<KeyValuePair<string, string>> RequestHeaders { get; set; } | ||
public string Response { get; set; } | ||
public string ResponseContentType { get; set; } | ||
public List<KeyValuePair<string, string>> ResponseHeaders { get; set; } | ||
public int ResponseStatusCode { get; set; } | ||
public bool ShouldTerminateRequest { get; set; } | ||
public long StartedOnUtc { get; set; } | ||
public string Subject { get; set; } | ||
|
||
public NatsMessage(string host, string contentType) | ||
{ | ||
// capture the time in epoch utc that this message was started | ||
StartedOnUtc = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); | ||
|
||
// default the response status code to an invalid value for comparison later on when the response is being processed by the RequestHandler | ||
ResponseStatusCode = -1; | ||
|
||
// capture the host machine that we're executing on | ||
Host = host; | ||
|
||
// capture the content type for the http response that we're configured for | ||
ResponseContentType = contentType; | ||
|
||
// initialize the default properties | ||
Cookies = new List<KeyValuePair<string, string>>(); | ||
ExtendedProperties = new Dictionary<string, string>(); | ||
QueryParams = new List<KeyValuePair<string, string>>(); | ||
RequestHeaders = new List<KeyValuePair<string, string>>(); | ||
ResponseHeaders = new List<KeyValuePair<string, string>>(); | ||
} | ||
|
||
public void MarkComplete() | ||
{ | ||
CompletedOnUtc = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); | ||
} | ||
} | ||
|
||
internal static class NatsMessageExtensions | ||
{ | ||
internal static byte[] ToBytes(this NatsMessage msg, JsonSerializerSettings serializerSettings) | ||
{ | ||
var serializedMessage = JsonConvert.SerializeObject(msg, serializerSettings); | ||
return Encoding.UTF8.GetBytes(serializedMessage); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using NATS.Client; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading; | ||
|
||
namespace AuthenticationPipelineStep | ||
{ | ||
internal class Program | ||
{ | ||
// we use a mre to keep the console application running while it's waiting on messages from NATS in the background | ||
private static readonly ManualResetEvent ManualResetEvent = new ManualResetEvent(false); | ||
|
||
private static IConnection _connection; | ||
|
||
private static void EnsureAuthHeaderPresent(object sender, MsgHandlerEventArgs e) | ||
{ | ||
// deserialize the NATS message | ||
var msg = MessageHelper.GetNatsMessage(e.Message); | ||
|
||
// if the msg doesn't include an authentication header we need to return a redirect to the auth url | ||
var authHeader = msg.RequestHeaders.FirstOrDefault(h => h.Key.Equals("Authorization")); | ||
|
||
if (null == authHeader.Value) | ||
{ | ||
Console.WriteLine($"No Authorization header found. Returning a 301 redirect to http://google.com"); | ||
msg.ResponseStatusCode = 301; | ||
msg.ResponseHeaders.Add(new KeyValuePair<string, string>("Location", "https://google.com")); | ||
msg.ShouldTerminateRequest = true; | ||
} | ||
else | ||
{ | ||
Console.WriteLine($"Authorization header was already on the message so nothing to do."); | ||
} | ||
|
||
// send the NATS message back to the caller | ||
_connection.Publish(e.Message.Reply, MessageHelper.PackageResponse(msg)); | ||
} | ||
|
||
private static void Main(string[] args) | ||
{ | ||
// configure the url to the NATS server | ||
var natsUrl = Environment.GetEnvironmentVariable("HTTP_NATS_PROXY_NAT_URL") ?? "nats://localhost:4222"; | ||
|
||
// create a connection to the NATS server | ||
var connectionFactory = new ConnectionFactory(); | ||
_connection = connectionFactory.CreateConnection(natsUrl); | ||
|
||
// setup a subscription to the "authentication" queue using a queue group for this microservice | ||
var subscriptions = new List<IAsyncSubscription> | ||
{ | ||
_connection.SubscribeAsync("authentication", "authentication-microservice-group", EnsureAuthHeaderPresent), | ||
}; | ||
|
||
// start the subscriptions | ||
subscriptions.ForEach(s => s.Start()); | ||
|
||
// keep this console app running | ||
Console.WriteLine($"Authentication Pipeline Step Connected to NATS at: {natsUrl}\r\nWaiting for messages..."); | ||
ManualResetEvent.WaitOne(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.