Skip to content

Commit 3ece01e

Browse files
authored
Merge pull request #651 from poppastring/support-webfinger
Support for webfinger close #650
2 parents 7c1435a + 19d36a1 commit 3ece01e

File tree

10 files changed

+163
-0
lines changed

10 files changed

+163
-0
lines changed

source/DasBlog.Services/ConfigFile/Interfaces/ISiteConfig.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,12 @@ public interface ISiteConfig
353353

354354
bool CookieConsentEnabled { get; set; }
355355

356+
string MastodonServerUrl { get; set; }
357+
358+
string MastodonAccount { get; set; }
359+
360+
string MastodonEmail { get; set; }
361+
356362
[XmlAnyElement]
357363
XmlElement[] anyElements { get; set; }
358364

source/DasBlog.Services/ConfigFile/SiteConfig.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,5 +219,11 @@ public SiteConfig() { }
219219
public string SecurityStyleSources { get; set; }
220220

221221
public string DefaultSources { get; set; }
222+
223+
public string MastodonServerUrl { get; set; }
224+
225+
public string MastodonAccount { get; set; }
226+
227+
public string MastodonEmail { get; set; }
222228
}
223229
}

source/DasBlog.Tests/UnitTests/SiteConfigTest.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,5 +168,8 @@ public class SiteConfigTest : ISiteConfig
168168

169169
public string SecurityStyleSources { get; set; }
170170
public string DefaultSources { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
171+
public string MastodonServerUrl { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
172+
public string MastodonAccount { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
173+
public string MastodonEmail { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
171174
}
172175
}

source/DasBlog.Web.UI/Config/site.Development.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929

3030
<!-- END OF SUGGESTED SETTINGS -->
3131

32+
<MastodonServerUrl />
33+
<MastodonAccount />
34+
<MastodonEmail />
35+
3236
<RssDayCount>10</RssDayCount>
3337
<RssMainEntryCount>50</RssMainEntryCount>
3438
<RssEntryCount>50</RssEntryCount>

source/DasBlog.Web.UI/Config/site.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929

3030
<!-- END OF SUGGESTED SETTINGS -->
3131

32+
<MastodonServerUrl />
33+
<MastodonAccount />
34+
<MastodonEmail />
35+
3236
<RssDayCount>10</RssDayCount>
3337
<RssMainEntryCount>50</RssMainEntryCount>
3438
<RssEntryCount>50</RssEntryCount>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text.Encodings.Web;
4+
using System.Text.Json;
5+
using DasBlog.Services;
6+
using DasBlog.Web.Models.ActivityPubModels;
7+
using DasBlog.Web.Settings;
8+
using Microsoft.AspNetCore.Mvc;
9+
using Microsoft.Extensions.Logging;
10+
using Quartz.Util;
11+
12+
namespace DasBlog.Web.Controllers
13+
{
14+
[Route(".wellknown")]
15+
public class ActivityPubController : DasBlogBaseController
16+
{
17+
private readonly IDasBlogSettings dasBlogSettings;
18+
19+
public ActivityPubController(IDasBlogSettings settings) : base(settings)
20+
{
21+
dasBlogSettings = settings;
22+
}
23+
24+
[Produces("text/json")]
25+
[HttpGet("webfinger")]
26+
public ActionResult WebFinger(string resource)
27+
{
28+
string usersurl = new Uri(new Uri(dasBlogSettings.SiteConfiguration.MastodonServerUrl),
29+
string.Format("users/{0}", dasBlogSettings.SiteConfiguration.MastodonAccount)).AbsoluteUri;
30+
31+
string accturl = new Uri(new Uri(dasBlogSettings.SiteConfiguration.MastodonServerUrl),
32+
string.Format("@{0}", dasBlogSettings.SiteConfiguration.MastodonAccount)).AbsoluteUri;
33+
34+
string authurl = new Uri(new Uri(dasBlogSettings.SiteConfiguration.MastodonServerUrl),
35+
"authorize_interaction").AbsoluteUri + "?uri={uri}";
36+
37+
string email = string.Format("acct:{0}", dasBlogSettings.SiteConfiguration.MastodonEmail);
38+
39+
if (dasBlogSettings.SiteConfiguration.MastodonServerUrl.IsNullOrWhiteSpace() ||
40+
dasBlogSettings.SiteConfiguration.MastodonAccount.IsNullOrWhiteSpace())
41+
{
42+
return NoContent();
43+
}
44+
45+
if(string.Compare(email, resource, StringComparison.InvariantCultureIgnoreCase) != 0)
46+
{
47+
return NotFound();
48+
}
49+
50+
var results = new Root
51+
{
52+
subject = email,
53+
aliases = new List<string> { accturl, usersurl },
54+
55+
links = new List<Link>
56+
{
57+
new Link() { rel="http://webfinger.net/rel/profile-page", type="text/html", href=accturl },
58+
new Link() { rel="self", type=@"application/activity+json", href=usersurl},
59+
new Link() { rel="http://ostatus.org/schema/1.0/subscribe", template=authurl }
60+
}
61+
};
62+
63+
var options = new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping };
64+
65+
return Json(results, options);
66+
}
67+
}
68+
}

source/DasBlog.Web.UI/DasBlog.Web.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
</None>
5858
</ItemGroup>
5959
<ItemGroup>
60+
<Folder Include="Models\ActivityPubModels\" />
6061
<Folder Include="Properties" />
6162
<Folder Include="wwwroot\lib\font-awesome\" />
6263
</ItemGroup>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System.Collections.Generic;
2+
using System.Text.Json.Serialization;
3+
4+
namespace DasBlog.Web.Models.ActivityPubModels
5+
{
6+
public class Link
7+
{
8+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
9+
public string rel { get; set; }
10+
11+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
12+
public string type { get; set; }
13+
14+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
15+
public string href { get; set; }
16+
17+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
18+
public string template { get; set; }
19+
}
20+
21+
public class Root
22+
{
23+
public string subject { get; set; }
24+
public List<string> aliases { get; set; }
25+
public List<Link> links { get; set; }
26+
}
27+
}
28+

source/DasBlog.Web.UI/Models/AdminViewModels/SiteViewModel.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,23 @@ public class SiteViewModel
296296
[StringLength(50, MinimumLength = 1, ErrorMessage = "{0} should be between 1 to 50 characters")]
297297
public string DefaultSources { get; set; }
298298

299+
[DisplayName("Mastadon Server")]
300+
[Description("")]
301+
[DataType(DataType.Url, ErrorMessage = "Invalid URL format")]
302+
public string MastodonServerUrl { get; set; }
303+
304+
[DisplayName("Mastadon Account (@username)")]
305+
[Description("")]
306+
[RegularExpression("(@)((?:[A-Za-z0-9-_]*))")]
307+
public string MastodonAccount { get; set; }
308+
309+
[DisplayName("Mastadon Email")]
310+
[Description("")]
311+
[DataType(DataType.EmailAddress, ErrorMessage = "Invalid email format")]
312+
public string MastodonEmail { get; set; }
313+
314+
315+
299316
public bool EntryTitleAsLink { get; set; }
300317
public bool ObfuscateEmail { get; set; }
301318
public bool SendReferralsByEmail { get; set; }

source/DasBlog.Web.UI/Views/Admin/Settings.cshtml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,30 @@
386386

387387
<h3>Social</h3>
388388

389+
<div class="form-group row mb-3">
390+
@Html.LabelFor(m => @Model.SiteConfig.MastodonServerUrl, null, new { @class = "col-form-label col-sm-2" })
391+
<div class="col-sm-5">
392+
@Html.TextBoxFor(m => @Model.SiteConfig.MastodonServerUrl, null, new { @class = "form-control sm-10" })
393+
</div>
394+
@Html.ValidationMessageFor(m => m.SiteConfig.MastodonServerUrl, null, new { @class = "text-danger" })
395+
</div>
396+
397+
<div class="form-group row mb-3">
398+
@Html.LabelFor(m => @Model.SiteConfig.MastodonAccount, null, new { @class = "col-form-label col-sm-2" })
399+
<div class="col-sm-5">
400+
@Html.TextBoxFor(m => @Model.SiteConfig.MastodonAccount, null, new { @class = "form-control sm-10" })
401+
</div>
402+
@Html.ValidationMessageFor(m => m.SiteConfig.MastodonAccount, null, new { @class = "text-danger" })
403+
</div>
404+
405+
<div class="form-group row mb-3">
406+
@Html.LabelFor(m => @Model.SiteConfig.MastodonEmail, null, new { @class = "col-form-label col-sm-2" })
407+
<div class="col-sm-5">
408+
@Html.TextBoxFor(m => @Model.SiteConfig.MastodonEmail, null, new { @class = "form-control sm-10" })
409+
</div>
410+
@Html.ValidationMessageFor(m => m.SiteConfig.MastodonEmail, null, new { @class = "text-danger" })
411+
</div>
412+
389413
<div class="form-group row mb-3">
390414

391415
@Html.LabelFor(m => @Model.MetaConfig.TwitterSite, null, new { @class = "col-form-label col-sm-2" })
@@ -435,6 +459,8 @@
435459
@Html.ValidationMessageFor(m => m.MetaConfig.GoogleAnalyticsID, null, new { @class = "text-danger" })
436460
</div>
437461

462+
463+
438464
<h3>Blogging & Editing</h3>
439465

440466
<div class="form-check row mb-3">

0 commit comments

Comments
 (0)