Disclose federation restrictions
This commit is contained in:
parent
8299249973
commit
1463a35c32
11 changed files with 197 additions and 161 deletions
|
@ -21,5 +21,7 @@
|
|||
|
||||
public int MaxFollowsPerUser { get; set; }
|
||||
|
||||
public bool DiscloseInstanceRestrictions { get; set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -11,6 +11,12 @@ namespace BirdsiteLive.Domain.Repository
|
|||
{
|
||||
ModerationTypeEnum GetModerationType(ModerationEntityTypeEnum type);
|
||||
ModeratedTypeEnum CheckStatus(ModerationEntityTypeEnum type, string entity);
|
||||
|
||||
IEnumerable<string> GetWhitelistedFollowers();
|
||||
IEnumerable<string> GetBlacklistedFollowers();
|
||||
IEnumerable<string> GetWhitelistedAccounts();
|
||||
|
||||
IEnumerable<string> GetBlacklistedAccounts();
|
||||
}
|
||||
|
||||
public class ModerationRepository : IModerationRepository
|
||||
|
@ -23,9 +29,13 @@ namespace BirdsiteLive.Domain.Repository
|
|||
private readonly Dictionary<ModerationEntityTypeEnum, ModerationTypeEnum> _modMode =
|
||||
new Dictionary<ModerationEntityTypeEnum, ModerationTypeEnum>();
|
||||
|
||||
private readonly ModerationSettings _settings;
|
||||
|
||||
#region Ctor
|
||||
public ModerationRepository(ModerationSettings settings)
|
||||
{
|
||||
_settings = settings;
|
||||
|
||||
var parsedFollowersWhiteListing = PatternsParser.Parse(settings.FollowersWhiteListing);
|
||||
var parsedFollowersBlackListing = PatternsParser.Parse(settings.FollowersBlackListing);
|
||||
var parsedTwitterAccountsWhiteListing = PatternsParser.Parse(settings.TwitterAccountsWhiteListing);
|
||||
|
@ -123,6 +133,35 @@ namespace BirdsiteLive.Domain.Repository
|
|||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
private char GetSplitChar(string entry)
|
||||
{
|
||||
var separationChar = '|';
|
||||
if (entry.Contains(";")) separationChar = ';';
|
||||
else if (entry.Contains(",")) separationChar = ',';
|
||||
|
||||
return separationChar;
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetWhitelistedFollowers()
|
||||
{
|
||||
return _settings.FollowersWhiteListing.Split(GetSplitChar(_settings.FollowersWhiteListing));
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetBlacklistedFollowers()
|
||||
{
|
||||
return _settings.FollowersBlackListing.Split(GetSplitChar(_settings.FollowersBlackListing));
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetWhitelistedAccounts()
|
||||
{
|
||||
return _settings.TwitterAccountsWhiteListing.Split(GetSplitChar(_settings.TwitterAccountsWhiteListing));
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetBlacklistedAccounts()
|
||||
{
|
||||
return _settings.TwitterAccountsBlackListing.Split(GetSplitChar(_settings.TwitterAccountsBlackListing));
|
||||
}
|
||||
}
|
||||
|
||||
public enum ModerationEntityTypeEnum
|
||||
|
|
|
@ -14,10 +14,10 @@ namespace BirdsiteLive.Component
|
|||
public class NodeInfoViewComponent : ViewComponent
|
||||
{
|
||||
private readonly IModerationRepository _moderationRepository;
|
||||
private readonly ICachedStatisticsService _cachedStatisticsService;
|
||||
private readonly IAboutPageService _cachedStatisticsService;
|
||||
|
||||
#region Ctor
|
||||
public NodeInfoViewComponent(IModerationRepository moderationRepository, ICachedStatisticsService cachedStatisticsService)
|
||||
public NodeInfoViewComponent(IModerationRepository moderationRepository, IAboutPageService cachedStatisticsService)
|
||||
{
|
||||
_moderationRepository = moderationRepository;
|
||||
_cachedStatisticsService = cachedStatisticsService;
|
||||
|
@ -29,7 +29,7 @@ namespace BirdsiteLive.Component
|
|||
var followerPolicy = _moderationRepository.GetModerationType(ModerationEntityTypeEnum.Follower);
|
||||
var twitterAccountPolicy = _moderationRepository.GetModerationType(ModerationEntityTypeEnum.TwitterAccount);
|
||||
|
||||
var statistics = await _cachedStatisticsService.GetStatisticsAsync();
|
||||
var statistics = await _cachedStatisticsService.GetAboutPageDataAsync();
|
||||
|
||||
var viewModel = new NodeInfoViewModel
|
||||
{
|
||||
|
@ -37,7 +37,8 @@ namespace BirdsiteLive.Component
|
|||
twitterAccountPolicy == ModerationTypeEnum.BlackListing,
|
||||
WhitelistingEnabled = followerPolicy == ModerationTypeEnum.WhiteListing ||
|
||||
twitterAccountPolicy == ModerationTypeEnum.WhiteListing,
|
||||
InstanceSaturation = statistics.Saturation
|
||||
InstanceSaturation = statistics.Saturation,
|
||||
DiscloseRestrictions = statistics.Settings.DiscloseInstanceRestrictions
|
||||
};
|
||||
|
||||
//viewModel = new NodeInfoViewModel
|
||||
|
@ -55,5 +56,6 @@ namespace BirdsiteLive.Component
|
|||
public bool BlacklistingEnabled { get; set; }
|
||||
public bool WhitelistingEnabled { get; set; }
|
||||
public int InstanceSaturation { get; set; }
|
||||
public bool DiscloseRestrictions { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,49 +10,21 @@ namespace BirdsiteLive.Controllers
|
|||
{
|
||||
public class AboutController : Controller
|
||||
{
|
||||
private readonly IModerationRepository _moderationRepository;
|
||||
private readonly ICachedStatisticsService _cachedStatisticsService;
|
||||
private readonly IAboutPageService _aboutPageService;
|
||||
|
||||
#region Ctor
|
||||
public AboutController(IModerationRepository moderationRepository, ICachedStatisticsService cachedStatisticsService)
|
||||
public AboutController(IAboutPageService cachedStatisticsService)
|
||||
{
|
||||
_moderationRepository = moderationRepository;
|
||||
_cachedStatisticsService = cachedStatisticsService;
|
||||
_aboutPageService = cachedStatisticsService;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
var stats = await _cachedStatisticsService.GetStatisticsAsync();
|
||||
var stats = await _aboutPageService.GetAboutPageDataAsync();
|
||||
return View(stats);
|
||||
}
|
||||
|
||||
public IActionResult Blacklisting()
|
||||
{
|
||||
var status = GetModerationStatus();
|
||||
return View("Blacklisting", status);
|
||||
}
|
||||
|
||||
public IActionResult Whitelisting()
|
||||
{
|
||||
var status = GetModerationStatus();
|
||||
return View("Whitelisting", status);
|
||||
}
|
||||
|
||||
private ModerationStatus GetModerationStatus()
|
||||
{
|
||||
var status = new ModerationStatus
|
||||
{
|
||||
Followers = _moderationRepository.GetModerationType(ModerationEntityTypeEnum.Follower),
|
||||
TwitterAccounts = _moderationRepository.GetModerationType(ModerationEntityTypeEnum.TwitterAccount)
|
||||
};
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
public class ModerationStatus
|
||||
{
|
||||
public ModerationTypeEnum Followers { get; set; }
|
||||
public ModerationTypeEnum TwitterAccounts { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
75
src/BirdsiteLive/Services/AboutPageService.cs
Normal file
75
src/BirdsiteLive/Services/AboutPageService.cs
Normal file
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BirdsiteLive.Common.Settings;
|
||||
using BirdsiteLive.DAL.Contracts;
|
||||
using BirdsiteLive.Domain.Repository;
|
||||
|
||||
namespace BirdsiteLive.Services
|
||||
{
|
||||
public interface IAboutPageService
|
||||
{
|
||||
Task<AboutPageData> GetAboutPageDataAsync();
|
||||
}
|
||||
|
||||
public class AboutPageService : IAboutPageService
|
||||
{
|
||||
private readonly ITwitterUserDal _twitterUserDal;
|
||||
|
||||
private static AboutPageData _aboutPageData;
|
||||
private readonly InstanceSettings _instanceSettings;
|
||||
private readonly IModerationRepository _moderationRepository;
|
||||
|
||||
#region Ctor
|
||||
public AboutPageService(ITwitterUserDal twitterUserDal, InstanceSettings instanceSettings, IModerationRepository moderationRepository)
|
||||
{
|
||||
_twitterUserDal = twitterUserDal;
|
||||
_instanceSettings = instanceSettings;
|
||||
_moderationRepository = moderationRepository;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public async Task<AboutPageData> GetAboutPageDataAsync()
|
||||
{
|
||||
if (_aboutPageData == null ||
|
||||
(DateTime.UtcNow - _aboutPageData.RefreshedTime).TotalMinutes > 15)
|
||||
{
|
||||
var twitterUserMax = _instanceSettings.MaxUsersCapacity;
|
||||
var twitterUserCount = await _twitterUserDal.GetTwitterUsersCountAsync();
|
||||
var saturation = (int)((double)twitterUserCount / twitterUserMax * 100);
|
||||
|
||||
_aboutPageData = new AboutPageData
|
||||
{
|
||||
RefreshedTime = DateTime.UtcNow,
|
||||
Saturation = saturation,
|
||||
UnlistedUsers = _instanceSettings.UnlistedTwitterAccounts.Length > 0 ? string.Join("\n", _instanceSettings.UnlistedTwitterAccounts.Split(";").Select(i => "<li>" + i + "</li>")) : "(none)",
|
||||
Settings = _instanceSettings,
|
||||
ModerationStatus = new ModerationStatus
|
||||
{
|
||||
Followers = _moderationRepository.GetModerationType(ModerationEntityTypeEnum.Follower),
|
||||
TwitterAccounts = _moderationRepository.GetModerationType(ModerationEntityTypeEnum.TwitterAccount),
|
||||
Repository = _moderationRepository
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return _aboutPageData;
|
||||
}
|
||||
}
|
||||
|
||||
public class AboutPageData
|
||||
{
|
||||
public DateTime RefreshedTime { get; set; }
|
||||
public int Saturation { get; set; }
|
||||
public string UnlistedUsers { get; set; }
|
||||
public InstanceSettings Settings { get; set; }
|
||||
public ModerationStatus ModerationStatus { get; set; }
|
||||
}
|
||||
|
||||
public class ModerationStatus
|
||||
{
|
||||
public ModerationTypeEnum Followers { get; set; }
|
||||
public ModerationTypeEnum TwitterAccounts { get; set; }
|
||||
public IModerationRepository Repository { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BirdsiteLive.Common.Settings;
|
||||
using BirdsiteLive.DAL.Contracts;
|
||||
|
||||
namespace BirdsiteLive.Services
|
||||
{
|
||||
public interface ICachedStatisticsService
|
||||
{
|
||||
Task<CachedStatistics> GetStatisticsAsync();
|
||||
}
|
||||
|
||||
public class CachedStatisticsService : ICachedStatisticsService
|
||||
{
|
||||
private readonly ITwitterUserDal _twitterUserDal;
|
||||
|
||||
private static CachedStatistics _cachedStatistics;
|
||||
private readonly InstanceSettings _instanceSettings;
|
||||
|
||||
#region Ctor
|
||||
public CachedStatisticsService(ITwitterUserDal twitterUserDal, InstanceSettings instanceSettings)
|
||||
{
|
||||
_twitterUserDal = twitterUserDal;
|
||||
_instanceSettings = instanceSettings;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public async Task<CachedStatistics> GetStatisticsAsync()
|
||||
{
|
||||
if (_cachedStatistics == null ||
|
||||
(DateTime.UtcNow - _cachedStatistics.RefreshedTime).TotalMinutes > 15)
|
||||
{
|
||||
var twitterUserMax = _instanceSettings.MaxUsersCapacity;
|
||||
var twitterUserCount = await _twitterUserDal.GetTwitterUsersCountAsync();
|
||||
var saturation = (int)((double)twitterUserCount / twitterUserMax * 100);
|
||||
|
||||
_cachedStatistics = new CachedStatistics
|
||||
{
|
||||
RefreshedTime = DateTime.UtcNow,
|
||||
Saturation = saturation,
|
||||
UnlistedUsers = _instanceSettings.UnlistedTwitterAccounts.Length > 0 ? string.Join("\n", _instanceSettings.UnlistedTwitterAccounts.Split(";").Select(i => "<li>" + i + "</li>")) : "(none)",
|
||||
Settings = _instanceSettings
|
||||
};
|
||||
}
|
||||
|
||||
return _cachedStatistics;
|
||||
}
|
||||
}
|
||||
|
||||
public class CachedStatistics
|
||||
{
|
||||
public DateTime RefreshedTime { get; set; }
|
||||
public int Saturation { get; set; }
|
||||
public string UnlistedUsers { get; set; }
|
||||
public InstanceSettings Settings { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
@using BirdsiteLive.Domain.Repository
|
||||
@model BirdsiteLive.Controllers.ModerationStatus
|
||||
@{
|
||||
ViewData["Title"] = "Blacklisting";
|
||||
}
|
||||
|
||||
<div class="col-12 col-sm-12 col-md-10 col-lg-8 mx-auto">
|
||||
<h2>Blacklisting</h2>
|
||||
|
||||
@if (Model.Followers == ModerationTypeEnum.BlackListing)
|
||||
{
|
||||
<p><br />This node is blacklisting some instances and/or Fediverse users.<br /><br /></p>
|
||||
}
|
||||
|
||||
@if (Model.TwitterAccounts == ModerationTypeEnum.BlackListing)
|
||||
{
|
||||
<p><br />This node is blacklisting some twitter users.<br /><br /></p>
|
||||
}
|
||||
|
||||
@if (Model.Followers != ModerationTypeEnum.BlackListing && Model.TwitterAccounts != ModerationTypeEnum.BlackListing)
|
||||
{
|
||||
<p><br />This node is not using blacklisting.<br /><br /></p>
|
||||
}
|
||||
|
||||
@*<h2>FAQ</h2>
|
||||
<p>TODO</p>*@
|
||||
</div>
|
|
@ -1,4 +1,4 @@
|
|||
@model BirdsiteLive.Services.CachedStatistics
|
||||
@model BirdsiteLive.Services.AboutPageData
|
||||
@{
|
||||
ViewData["Title"] = "About";
|
||||
}
|
||||
|
@ -20,17 +20,17 @@
|
|||
</div>
|
||||
}
|
||||
|
||||
<h4>What is this site?</h4>
|
||||
<h4>About @Model.Settings.Name</h4>
|
||||
|
||||
<p>
|
||||
This site runs an instance of BirdsiteLIVE, an <a href="https://activitypub.rocks" target="_blank">ActivityPub</a>-compatible <a href="https://en.wikipedia.org/wiki/Fediverse" target="_blank">Fediverse</a> server that delivers Tweets from Twitter to users on the Fediverse.
|
||||
@Model.Settings.Name runs an instance of BirdsiteLIVE, an <a href="https://activitypub.rocks" target="_blank">ActivityPub</a>-compatible <a href="https://en.wikipedia.org/wiki/Fediverse" target="_blank">Fediverse</a> server that delivers Tweets from Twitter to users on the Fediverse.
|
||||
|
||||
<br /><br />
|
||||
|
||||
BirdsiteLIVE does not make any public posts; every post is scoped appropriately using the "followers-only" or "unlisted" ActivityPub audiences.
|
||||
</p>
|
||||
|
||||
<h4 id="followers-only">Why do accounts I follow on this node post followers-only?</h4>
|
||||
<h4 id="followers-only">Unlisted accounts</h4>
|
||||
|
||||
<p>
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
|||
</ul>
|
||||
</p>
|
||||
|
||||
<h4 id="saturation">What does "instance saturation" mean?</h4>
|
||||
<h4 id="saturation">Instance saturation</h4>
|
||||
|
||||
<p>
|
||||
This instance's saturation level is currently at @Model.Saturation%.
|
||||
|
@ -58,4 +58,65 @@
|
|||
|
||||
When possible, you should <a href="https://git.gamers.exposed/pasture/BirdsiteLIVE/src/branch/master/INSTALLATION.md" target="_blank">start your own BirdsiteLIVE instance</a>. If you cannot, please be courteous and follow a limited number of accounts to keep the service available for everyone.
|
||||
</p>
|
||||
|
||||
@if (Model.Settings.DiscloseInstanceRestrictions && (Model.ModerationStatus.Followers != BirdsiteLive.Domain.Repository.ModerationTypeEnum.None || Model.ModerationStatus.TwitterAccounts != BirdsiteLive.Domain.Repository.ModerationTypeEnum.None))
|
||||
{
|
||||
<h4 id="restrictions">
|
||||
Federation restrictions
|
||||
</h4>
|
||||
|
||||
<p>This instance can generally communicate with any other server following the ActivityPub protocol, with some exceptions, as listed below and configured by this server's administrators.</p>
|
||||
|
||||
if (Model.ModerationStatus.Followers == BirdsiteLive.Domain.Repository.ModerationTypeEnum.BlackListing)
|
||||
{
|
||||
<h5 id="instance-blacklist">Instance blacklist</h5>
|
||||
<p>No data for instances on this list will be processed. Users from instances on this list are not able to follow or directly receive Tweets from accounts on this instance.</p>
|
||||
|
||||
<ul>
|
||||
@foreach (var i in Model.ModerationStatus.Repository.GetBlacklistedFollowers())
|
||||
{
|
||||
<li>@i</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
|
||||
if (Model.ModerationStatus.Followers == BirdsiteLive.Domain.Repository.ModerationTypeEnum.WhiteListing)
|
||||
{
|
||||
<h5 id="instance-whitelist">Instance whitelist</h5>
|
||||
<p>Only users from instances on this list will be able to follow or directly receive Tweets from accounts on this instance.</p>
|
||||
|
||||
<ul>
|
||||
@foreach (var i in Model.ModerationStatus.Repository.GetWhitelistedFollowers())
|
||||
{
|
||||
<li>@i</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
|
||||
if (Model.ModerationStatus.TwitterAccounts == BirdsiteLive.Domain.Repository.ModerationTypeEnum.BlackListing)
|
||||
{
|
||||
<h5 id="account-blacklist">Account blacklist</h5>
|
||||
<p>Users will not be able to follow the following Twitter accounts on this instance, and Tweets from these accounts will not be relayed.</p>
|
||||
|
||||
<ul>
|
||||
@foreach (var i in Model.ModerationStatus.Repository.GetBlacklistedAccounts())
|
||||
{
|
||||
<li>@i</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
|
||||
if (Model.ModerationStatus.TwitterAccounts == BirdsiteLive.Domain.Repository.ModerationTypeEnum.WhiteListing)
|
||||
{
|
||||
<h5 id="account-whitelist">Account whitelist</h5>
|
||||
<p>Only Twitter accounts on this list are able to be followed from this instance.</p>
|
||||
|
||||
<ul>
|
||||
@foreach (var i in Model.ModerationStatus.Repository.GetWhitelistedAccounts())
|
||||
{
|
||||
<li>@i</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
}
|
||||
</div>
|
|
@ -1,27 +0,0 @@
|
|||
@using BirdsiteLive.Domain.Repository
|
||||
@model BirdsiteLive.Controllers.ModerationStatus
|
||||
@{
|
||||
ViewData["Title"] = "Whitelisting";
|
||||
}
|
||||
|
||||
<div class="col-12 col-sm-12 col-md-10 col-lg-8 mx-auto">
|
||||
<h2>Whitelisting</h2>
|
||||
|
||||
@if (Model.Followers == ModerationTypeEnum.WhiteListing)
|
||||
{
|
||||
<p><br />This node is whitelisting some instances and/or Fediverse users.<br /><br /></p>
|
||||
}
|
||||
|
||||
@if (Model.TwitterAccounts == ModerationTypeEnum.WhiteListing)
|
||||
{
|
||||
<p><br />This node is whitelisting some twitter users.<br /><br /></p>
|
||||
}
|
||||
|
||||
@if (Model.Followers != ModerationTypeEnum.WhiteListing && Model.TwitterAccounts != ModerationTypeEnum.WhiteListing)
|
||||
{
|
||||
<p><br />This node is not using whitelisting.<br /><br /></p>
|
||||
}
|
||||
|
||||
@*<h2>FAQ</h2>
|
||||
<p>TODO</p>*@
|
||||
</div>
|
|
@ -1,13 +1,9 @@
|
|||
@model BirdsiteLive.Component.NodeInfoViewModel
|
||||
|
||||
<div>
|
||||
@if (ViewData.Model.WhitelistingEnabled)
|
||||
@if (ViewData.Model.DiscloseRestrictions && (ViewData.Model.WhitelistingEnabled || ViewData.Model.BlacklistingEnabled))
|
||||
{
|
||||
<a asp-controller="About" asp-action="Whitelisting" class="badge badge-light" title="What does this mean?">Whitelisting Enabled</a>
|
||||
}
|
||||
@if (ViewData.Model.BlacklistingEnabled)
|
||||
{
|
||||
<a asp-controller="About" asp-action="Blacklisting" class="badge badge-light" title="What does this mean?">Blacklisting Enabled</a>
|
||||
<a asp-controller="About" asp-action="Index" class="badge badge-light" title="What does this mean?" asp-fragment="restrictions">View restrictions</a>
|
||||
}
|
||||
|
||||
<div class="node-progress-bar">
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
"TwitterDomainLabel": "",
|
||||
"InfoBanner": "",
|
||||
"ShowAboutInstanceOnProfiles": true,
|
||||
"MaxFollowsPerUser": 0
|
||||
"MaxFollowsPerUser": 0,
|
||||
"DiscloseInstanceRestrictions": false
|
||||
},
|
||||
"Db": {
|
||||
"Type": "postgres",
|
||||
|
|
Reference in a new issue