Add system and member privacy support
This commit is contained in:
13
PluralKit.Core/Migrations/2.sql
Normal file
13
PluralKit.Core/Migrations/2.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- We're doing a psuedo-enum here since Dapper is wonky with enums
|
||||
-- Still getting mapped to enums at the CLR level, though.
|
||||
-- https://github.com/StackExchange/Dapper/issues/332 (from 2015, still unsolved!)
|
||||
-- 1 = "public"
|
||||
-- 2 = "private"
|
||||
-- not doing a bool here since I want to open up for the possibliity of other privacy levels (eg. "mutuals only")
|
||||
alter table systems add column description_privacy integer check (description_privacy in (1, 2)) not null default 1;
|
||||
alter table systems add column member_list_privacy integer check (member_list_privacy in (1, 2)) not null default 1;
|
||||
alter table systems add column front_privacy integer check (front_privacy in (1, 2)) not null default 1;
|
||||
alter table systems add column front_history_privacy integer check (front_history_privacy in (1, 2)) not null default 1;
|
||||
alter table members add column member_privacy integer check (member_privacy in (1, 2)) not null default 1;
|
||||
|
||||
update info set schema_version = 2;
|
||||
@@ -17,6 +17,25 @@ namespace PluralKit
|
||||
{
|
||||
public PKParseError(string message): base(message) { }
|
||||
}
|
||||
|
||||
public enum PrivacyLevel
|
||||
{
|
||||
Public = 1,
|
||||
Private = 2
|
||||
}
|
||||
|
||||
public static class PrivacyExt
|
||||
{
|
||||
public static bool CanAccess(this PrivacyLevel level, LookupContext ctx) =>
|
||||
level == PrivacyLevel.Public || ctx == LookupContext.ByOwner;
|
||||
}
|
||||
|
||||
public enum LookupContext
|
||||
{
|
||||
ByOwner,
|
||||
ByNonOwner,
|
||||
API
|
||||
}
|
||||
|
||||
public struct ProxyTag
|
||||
{
|
||||
@@ -58,14 +77,19 @@ namespace PluralKit
|
||||
[JsonIgnore] public string Token { get; set; }
|
||||
[JsonProperty("created")] public Instant Created { get; set; }
|
||||
[JsonProperty("tz")] public string UiTz { get; set; }
|
||||
public PrivacyLevel DescriptionPrivacy { get; set; }
|
||||
public PrivacyLevel MemberListPrivacy { get; set; }
|
||||
public PrivacyLevel FrontPrivacy { get; set; }
|
||||
public PrivacyLevel FrontHistoryPrivacy { get; set; }
|
||||
|
||||
[JsonIgnore] public DateTimeZone Zone => DateTimeZoneProviders.Tzdb.GetZoneOrNull(UiTz);
|
||||
|
||||
public JObject ToJson()
|
||||
public JObject ToJson(LookupContext ctx)
|
||||
{
|
||||
var o = new JObject();
|
||||
o.Add("id", Hid);
|
||||
o.Add("name", Name);
|
||||
o.Add("description", Description);
|
||||
o.Add("description", DescriptionPrivacy.CanAccess(ctx) ? Description : null);
|
||||
o.Add("tag", Tag);
|
||||
o.Add("avatar_url", AvatarUrl);
|
||||
o.Add("created", Formats.TimestampExportFormat.Format(Created));
|
||||
@@ -100,6 +124,8 @@ namespace PluralKit
|
||||
[JsonProperty("keep_proxy")] public bool KeepProxy { get; set; }
|
||||
[JsonProperty("created")] public Instant Created { get; set; }
|
||||
|
||||
public PrivacyLevel MemberPrivacy { get; set; }
|
||||
|
||||
/// Returns a formatted string representing the member's birthday, taking into account that a year of "0001" is hidden
|
||||
[JsonIgnore] public string BirthdayString
|
||||
{
|
||||
@@ -120,17 +146,17 @@ namespace PluralKit
|
||||
return $"{guildDisplayName ?? DisplayName ?? Name} {systemTag}";
|
||||
}
|
||||
|
||||
public JObject ToJson()
|
||||
public JObject ToJson(LookupContext ctx)
|
||||
{
|
||||
var o = new JObject();
|
||||
o.Add("id", Hid);
|
||||
o.Add("name", Name);
|
||||
o.Add("color", Color);
|
||||
o.Add("color", MemberPrivacy.CanAccess(ctx) ? Color : null);
|
||||
o.Add("display_name", DisplayName);
|
||||
o.Add("birthday", Birthday.HasValue ? Formats.DateExportFormat.Format(Birthday.Value) : null);
|
||||
o.Add("pronouns", Pronouns);
|
||||
o.Add("birthday", MemberPrivacy.CanAccess(ctx) && Birthday.HasValue ? Formats.DateExportFormat.Format(Birthday.Value) : null);
|
||||
o.Add("pronouns", MemberPrivacy.CanAccess(ctx) ? Pronouns : null);
|
||||
o.Add("avatar_url", AvatarUrl);
|
||||
o.Add("description", Description);
|
||||
o.Add("description", MemberPrivacy.CanAccess(ctx) ? Description : null);
|
||||
|
||||
var tagArray = new JArray();
|
||||
foreach (var tag in ProxyTags)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
@@ -11,7 +10,7 @@ using Serilog;
|
||||
namespace PluralKit {
|
||||
public class SchemaService
|
||||
{
|
||||
private const int TargetSchemaVersion = 1;
|
||||
private const int TargetSchemaVersion = 2;
|
||||
|
||||
private DbConnectionFactory _conn;
|
||||
private ILogger _logger;
|
||||
@@ -22,6 +21,13 @@ namespace PluralKit {
|
||||
_logger = logger.ForContext<SchemaService>();
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
// Without these it'll still *work* but break at the first launch + probably cause other small issues
|
||||
NpgsqlConnection.GlobalTypeMapper.MapComposite<ProxyTag>("proxy_tag");
|
||||
NpgsqlConnection.GlobalTypeMapper.MapEnum<PrivacyLevel>("privacy_level");
|
||||
}
|
||||
|
||||
public async Task ApplyMigrations()
|
||||
{
|
||||
for (var version = 0; version <= TargetSchemaVersion; version++)
|
||||
|
||||
@@ -116,7 +116,8 @@ namespace PluralKit {
|
||||
/// <summary>
|
||||
/// Gets the member count of a system.
|
||||
/// </summary>
|
||||
Task<int> GetSystemMemberCount(PKSystem system);
|
||||
/// <param name="includePrivate">Whether the returned count should include private members.</param>
|
||||
Task<int> GetSystemMemberCount(PKSystem system, bool includePrivate);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of members with proxy tags that conflict with the given tags.
|
||||
@@ -488,7 +489,7 @@ namespace PluralKit {
|
||||
|
||||
public async Task SaveSystem(PKSystem system) {
|
||||
using (var conn = await _conn.Obtain())
|
||||
await conn.ExecuteAsync("update systems set name = @Name, description = @Description, tag = @Tag, avatar_url = @AvatarUrl, token = @Token, ui_tz = @UiTz where id = @Id", system);
|
||||
await conn.ExecuteAsync("update systems set name = @Name, description = @Description, tag = @Tag, avatar_url = @AvatarUrl, token = @Token, ui_tz = @UiTz, description_privacy = @DescriptionPrivacy, member_list_privacy = @MemberListPrivacy, front_privacy = @FrontPrivacy, front_history_privacy = @FrontHistoryPrivacy where id = @Id", system);
|
||||
|
||||
_logger.Information("Updated system {@System}", system);
|
||||
}
|
||||
@@ -590,7 +591,7 @@ namespace PluralKit {
|
||||
|
||||
public async Task SaveMember(PKMember member) {
|
||||
using (var conn = await _conn.Obtain())
|
||||
await conn.ExecuteAsync("update members set name = @Name, display_name = @DisplayName, description = @Description, color = @Color, avatar_url = @AvatarUrl, birthday = @Birthday, pronouns = @Pronouns, proxy_tags = @ProxyTags, keep_proxy = @KeepProxy where id = @Id", member);
|
||||
await conn.ExecuteAsync("update members set name = @Name, display_name = @DisplayName, description = @Description, color = @Color, avatar_url = @AvatarUrl, birthday = @Birthday, pronouns = @Pronouns, proxy_tags = @ProxyTags, keep_proxy = @KeepProxy, member_privacy = @MemberPrivacy where id = @Id", member);
|
||||
|
||||
_logger.Information("Updated member {@Member}", member);
|
||||
}
|
||||
@@ -637,10 +638,13 @@ namespace PluralKit {
|
||||
new { System = system.Id });
|
||||
}
|
||||
|
||||
public async Task<int> GetSystemMemberCount(PKSystem system)
|
||||
public async Task<int> GetSystemMemberCount(PKSystem system, bool includePrivate)
|
||||
{
|
||||
var query = "select count(*) from members where system = @Id";
|
||||
if (includePrivate) query += " and member_privacy = 1"; // 1 = public
|
||||
|
||||
using (var conn = await _conn.Obtain())
|
||||
return await conn.ExecuteScalarAsync<int>("select count(*) from members where system = @Id", system);
|
||||
return await conn.ExecuteScalarAsync<int>(query, system);
|
||||
}
|
||||
|
||||
public async Task<ulong> GetTotalMembers()
|
||||
|
||||
Reference in New Issue
Block a user