Skip to content
This repository has been archived by the owner on Dec 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #8 from PromoFaux/development
Browse files Browse the repository at this point in the history
v1.2
  • Loading branch information
PromoFaux authored Sep 19, 2017
2 parents f420258 + e2886cf commit 9222f21
Show file tree
Hide file tree
Showing 12 changed files with 390 additions and 1,060 deletions.
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Stage 1
FROM microsoft/aspnetcore-build:1.0-2.0 AS builder
FROM microsoft/aspnetcore-build:2.0 AS builder
WORKDIR /source

COPY . .
RUN dotnet restore Matterhook.NET.sln
RUN dotnet publish Matterhook.NET.sln -c Release -o /publish
RUN dotnet restore Matterhook.NET/Matterhook.NET.csproj
RUN dotnet publish Matterhook.NET/Matterhook.NET.csproj -c Release -o /publish

# Stage 2
FROM microsoft/aspnetcore:2.0
Expand Down
53 changes: 49 additions & 4 deletions Matterhook.NET/Code/Util.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Matterhook.NET.Code
{
public class Util
public static class Util
{
public static string CalculateSignature(string payload, string signatureWithPrefix, string secret,
string shaPrefix)
{
if (!signatureWithPrefix.StartsWith(shaPrefix, StringComparison.OrdinalIgnoreCase))
{
return "Invalid shaPrefix";
}

var secretBytes = Encoding.UTF8.GetBytes(secret);
var payloadBytes = Encoding.UTF8.GetBytes(payload);
Expand Down Expand Up @@ -50,6 +54,50 @@ private static string ToHexString(byte[] bytes)
return builder.ToString();
}

public static void LogList(List<string> listToLog)
{
foreach (var s in listToLog)
{
Console.WriteLine(s);
}
Console.WriteLine("");
}


/// <summary>
/// Verifies mattermost config on a per-repo basis. If it's not found, then it's posted to the default settings.
/// </summary>
/// <param name="repoList"></param>
/// <param name="fullName"></param>
/// <param name="defaultMattermostConfig"></param>
/// <returns></returns>
public static MattermostConfig GetMattermostDetails(MattermostConfig defaultMattermostConfig, List<RepoConfig> repoList, string fullName)
{
var repo = repoList.FirstOrDefault(
x => string.Equals(x.RepoName, fullName, StringComparison.CurrentCultureIgnoreCase));

if (repo != null)
{
return new MattermostConfig
{
Channel = string.IsNullOrWhiteSpace(repo.MattermostConfig.Channel)
? defaultMattermostConfig.Channel
: repo.MattermostConfig.Channel,
IconUrl = string.IsNullOrWhiteSpace(repo.MattermostConfig.IconUrl)
? defaultMattermostConfig.IconUrl
: repo.MattermostConfig.IconUrl,
Username = string.IsNullOrWhiteSpace(repo.MattermostConfig.Username)
? defaultMattermostConfig.Username
: repo.MattermostConfig.Username,
WebhookUrl = string.IsNullOrWhiteSpace(repo.MattermostConfig.WebhookUrl)
? defaultMattermostConfig.WebhookUrl
: repo.MattermostConfig.WebhookUrl
};
}

return defaultMattermostConfig;
}

}

public class UnixDateTimeConverter : DateTimeConverterBase
Expand All @@ -60,9 +108,6 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
if (reader.TokenType != JsonToken.Integer)
{
return reader.Value;
throw new Exception(
String.Format("Unexpected token parsing date. Expected Integer, got {0}.",
reader.TokenType));
}

var ticks = (long)reader.Value;
Expand Down
7 changes: 1 addition & 6 deletions Matterhook.NET/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,18 @@ public class MattermostConfig
public string IconUrl { get; set; }
}

//TODO: Look at configuring subscribed events
public class GithubConfig
{
public string Secret { get; set; }
public MattermostConfig DefaultMattermostConfig { get; set; }
public bool VerboseCommitMessages { get; set; }

//TODO Look at this
//public string DefaultSubscribedEvents { get; set; }

public List<RepoConfig> RepoList { get; set; }
}

public class RepoConfig
{
public string RepoName { get; set; }
//Todo: Look at this
//public string SubscribedEvents { get; set; }
public MattermostConfig MattermostConfig { get; set; }

}
Expand Down
66 changes: 38 additions & 28 deletions Matterhook.NET/Controllers/DiscourseHookController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,39 +23,44 @@ namespace Matterhook.NET.Controllers
[Route("[Controller]")]
public class DiscourseHookController : Controller
{
private const string Sha256Prefix = "sha256=";
private readonly DiscourseConfig _config;
private string DiscourseURL;
private string _discourseUrl;


public DiscourseHookController(IOptions<Config> config)
{
var c = config ?? throw new ArgumentNullException(nameof(config));
_config = c.Value.DiscourseConfig;

try
{
_config = config.Value.DiscourseConfig;
}
catch (ArgumentException e)
{
Console.WriteLine(e.Message);
}
}

[HttpPost("")]
public async Task<IActionResult> Receive()
{
var stuffToLog = new List<string>();
try
{
string payloadText;
//Generate DiscourseHook object for easier reading
Console.WriteLine($"Discourse Hook received: {DateTime.Now}");
stuffToLog.Add($"Discourse Hook received: {DateTime.Now}");

Request.Headers.TryGetValue("X-Discourse-Event-Id", out StringValues eventId);
Request.Headers.TryGetValue("X-Discourse-Event-Type", out StringValues eventType);
Request.Headers.TryGetValue("X-Discourse-Event", out StringValues eventName);
Request.Headers.TryGetValue("X-Discourse-Event-Signature", out StringValues signature);
Request.Headers.TryGetValue("X-Discourse-Instance", out StringValues discourseUrl);
DiscourseURL = discourseUrl;
_discourseUrl = discourseUrl;

Console.WriteLine($"Hook Id: {eventId}");
stuffToLog.Add($"Hook Id: {eventId}");

using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
{
payloadText = await reader.ReadToEndAsync();
payloadText = await reader.ReadToEndAsync().ConfigureAwait(false);
}

var calcSig = Util.CalculateSignature(payloadText, signature, _config.Secret, "sha256=");
Expand All @@ -66,39 +71,40 @@ public async Task<IActionResult> Receive()
var discourseHook = new DiscourseHook(eventId,eventType,eventName,signature,payloadText);
var matterHook = new MatterhookClient.MatterhookClient(_config.MattermostConfig.WebhookUrl);
HttpResponseMessage response = null;
switch (discourseHook.EventName)
MattermostMessage message = null;
if (discourseHook.EventName == "post_created")
{
case "post_created":
response = await matterHook.PostAsync(PostCreated((PostPayload)discourseHook.Payload));
break;
default:
break;
message = PostCreated((PostPayload) discourseHook.Payload);
response = await matterHook.PostAsync(message);
}

if (response == null || response.StatusCode != HttpStatusCode.OK)
{
Console.WriteLine(response != null
stuffToLog.Add(response != null
? $"Unable to post to Mattermost {response.StatusCode}"
: "Unable to post to Mattermost");

return Content(response != null ? $"Problem posting to Mattermost: {response.StatusCode}" : "Problem Posting to Mattermost");
}

Console.WriteLine("Succesfully posted to Mattermost");
if (message != null) stuffToLog.Add(message.Text);
stuffToLog.Add("Succesfully posted to Mattermost");
Util.LogList(stuffToLog);
return Ok();
}
else
{
Console.WriteLine("Invalid Signature!");
Console.WriteLine($"Expected: {signature}");
Console.WriteLine($"Calculated: {calcSig}");
stuffToLog.Add("Invalid Signature!");
stuffToLog.Add($"Expected: {signature}");
stuffToLog.Add($"Calculated: {calcSig}");
Util.LogList(stuffToLog);
return Unauthorized();
}

}
catch (Exception e)
{
Console.WriteLine(e.Message);
stuffToLog.Add(e.Message);
Util.LogList(stuffToLog);
return Content(e.Message);
}

Expand All @@ -116,7 +122,9 @@ private MattermostMessage PostCreated(PostPayload payload)
var p = payload.post;

if (_config.IgnoredTopicTitles.Contains(p.topic_title))
{
throw new Exception("Post title matches ignored titles");
}

if (_config.IgnorePrivateMessages)
{
Expand All @@ -125,7 +133,7 @@ private MattermostMessage PostCreated(PostPayload payload)
try
{
JObject.Parse(
new WebClient().DownloadString($"{DiscourseURL}/t/{p.topic_id}.json"));
new WebClient().DownloadString($"{_discourseUrl}/t/{p.topic_id}.json"));
}
catch
{
Expand All @@ -148,18 +156,20 @@ private MattermostMessage PostCreated(PostPayload payload)
{
Fallback = "New Post in Discourse Topic",
Title = p.topic_title,
TitleLink = new Uri($"{DiscourseURL}/t/{p.topic_id}/{p.post_number}"),
Text = new Converter().Convert(ExpandDiscourseUrls(p.cooked,DiscourseURL)),
TitleLink = new Uri($"{_discourseUrl}/t/{p.topic_id}/{p.post_number}"),
Text = new Converter().Convert(ExpandDiscourseUrls(p.cooked,_discourseUrl)),
AuthorName = p.username,
AuthorLink = new Uri($"{DiscourseURL}/u/{p.username}"),
AuthorIcon = new Uri($"{DiscourseURL}{p.avatar_template.Replace("{size}","16")}")
AuthorLink = new Uri($"{_discourseUrl}/u/{p.username}"),
AuthorIcon = new Uri($"{_discourseUrl}{p.avatar_template.Replace("{size}","16")}")
}
}

};

if (p.post_number.ToString() == "1")
retVal.Text = "#NewTopic\n";
{
retVal.Text = "#NewTopic\n";
}

retVal.Text += $"#{p.topic_slug}";

Expand Down
Loading

0 comments on commit 9222f21

Please sign in to comment.