Add per-system member/group limit override

This commit is contained in:
Ske 2020-10-09 12:18:29 +02:00
parent 1e8470e77f
commit 1fda6ec919
8 changed files with 30 additions and 12 deletions

View File

@ -40,18 +40,21 @@ namespace PluralKit.API
[Authorize] [Authorize]
public async Task<ActionResult<JObject>> PostMember([FromBody] JObject properties) public async Task<ActionResult<JObject>> PostMember([FromBody] JObject properties)
{ {
var system = User.CurrentSystem();
if (!properties.ContainsKey("name")) if (!properties.ContainsKey("name"))
return BadRequest("Member name must be specified."); return BadRequest("Member name must be specified.");
var systemId = User.CurrentSystem();
await using var conn = await _db.Obtain(); await using var conn = await _db.Obtain();
var systemData = await _repo.GetSystem(conn, systemId);
// Enforce per-system member limit // Enforce per-system member limit
var memberCount = await conn.QuerySingleAsync<int>("select count(*) from members where system = @System", new {System = system}); var memberCount = await conn.QuerySingleAsync<int>("select count(*) from members where system = @System", new {System = systemId});
if (memberCount >= Limits.MaxMemberCount) var memberLimit = systemData?.MemberLimitOverride ?? Limits.MaxMemberCount;
return BadRequest($"Member limit reached ({memberCount} / {Limits.MaxMemberCount})."); if (memberCount >= memberLimit)
return BadRequest($"Member limit reached ({memberCount} / {memberLimit}).");
var member = await _repo.CreateMember(conn, system, properties.Value<string>("name")); var member = await _repo.CreateMember(conn, systemId, properties.Value<string>("name"));
MemberPatch patch; MemberPatch patch;
try try
{ {

View File

@ -38,8 +38,9 @@ namespace PluralKit.Bot
// Check group cap // Check group cap
var existingGroupCount = await conn.QuerySingleAsync<int>("select count(*) from groups where system = @System", new { System = ctx.System.Id }); var existingGroupCount = await conn.QuerySingleAsync<int>("select count(*) from groups where system = @System", new { System = ctx.System.Id });
if (existingGroupCount >= Limits.MaxGroupCount) var groupLimit = ctx.System.GroupLimitOverride ?? Limits.MaxGroupCount;
throw new PKError($"System has reached the maximum number of groups ({Limits.MaxGroupCount}). Please delete unused groups first in order to create new ones."); if (existingGroupCount >= groupLimit)
throw new PKError($"System has reached the maximum number of groups ({groupLimit}). Please delete unused groups first in order to create new ones.");
// Warn if there's already a group by this name // Warn if there's already a group by this name
var existingGroup = await _repo.GetGroupByName(conn, ctx.System.Id, groupName); var existingGroup = await _repo.GetGroupByName(conn, ctx.System.Id, groupName);

View File

@ -37,8 +37,9 @@ namespace PluralKit.Bot
// Enforce per-system member limit // Enforce per-system member limit
var memberCount = await _repo.GetSystemMemberCount(conn, ctx.System.Id); var memberCount = await _repo.GetSystemMemberCount(conn, ctx.System.Id);
if (memberCount >= Limits.MaxMemberCount) var memberLimit = ctx.System.MemberLimitOverride ?? Limits.MaxMemberCount;
throw Errors.MemberLimitReachedError; if (memberCount >= memberLimit)
throw Errors.MemberLimitReachedError(memberLimit);
// Create the member // Create the member
var member = await _repo.CreateMember(conn, ctx.System.Id, memberName); var member = await _repo.CreateMember(conn, ctx.System.Id, memberName);

View File

@ -44,7 +44,7 @@ namespace PluralKit.Bot {
public static PKError DescriptionTooLongError(int length) => new PKError($"Description too long ({length}/{Limits.MaxDescriptionLength} characters)."); public static PKError DescriptionTooLongError(int length) => new PKError($"Description too long ({length}/{Limits.MaxDescriptionLength} characters).");
public static PKError MemberNameTooLongError(int length) => new PKError($"Member name too long ({length}/{Limits.MaxMemberNameLength} characters)."); public static PKError MemberNameTooLongError(int length) => new PKError($"Member name too long ({length}/{Limits.MaxMemberNameLength} characters).");
public static PKError MemberPronounsTooLongError(int length) => new PKError($"Member pronouns too long ({length}/{Limits.MaxMemberNameLength} characters)."); public static PKError MemberPronounsTooLongError(int length) => new PKError($"Member pronouns too long ({length}/{Limits.MaxMemberNameLength} characters).");
public static PKError MemberLimitReachedError => new PKError($"System has reached the maximum number of members ({Limits.MaxMemberCount}). Please delete unused members first in order to create new ones."); public static PKError MemberLimitReachedError(int limit) => new PKError($"System has reached the maximum number of members ({limit}). Please delete unused members first in order to create new ones.");
public static PKError NoMembersError => new PKError("Your system has no members! Please create at least one member before using this command."); public static PKError NoMembersError => new PKError("Your system has no members! Please create at least one member before using this command.");
public static PKError InvalidColorError(string color) => new PKError($"\"{color}\" is not a valid color. Color must be in 6-digit RGB hex format (eg. #ff0000)."); public static PKError InvalidColorError(string color) => new PKError($"\"{color}\" is not a valid color. Color must be in 6-digit RGB hex format (eg. #ff0000).");

View File

@ -19,7 +19,7 @@ namespace PluralKit.Core
internal class Database: IDatabase internal class Database: IDatabase
{ {
private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files
private const int TargetSchemaVersion = 9; private const int TargetSchemaVersion = 10;
private readonly CoreConfig _config; private readonly CoreConfig _config;
private readonly ILogger _logger; private readonly ILogger _logger;

View File

@ -0,0 +1,11 @@
-- SCHEMA VERSION 10: 2020-10-09 --
-- Member/group limit override per-system
alter table systems add column member_limit_override smallint default null;
alter table systems add column group_limit_override smallint default null;
-- Lowering global limit to 1000 in this commit, so increase it for systems already above that
update systems s set member_count_override = 1500
where (select count(*) from members m where m.system = s.id) > 1000;
update info set schema_version = 10;

View File

@ -23,6 +23,8 @@ namespace PluralKit.Core {
public PrivacyLevel FrontPrivacy { get; } public PrivacyLevel FrontPrivacy { get; }
public PrivacyLevel FrontHistoryPrivacy { get; } public PrivacyLevel FrontHistoryPrivacy { get; }
public PrivacyLevel GroupListPrivacy { get; } public PrivacyLevel GroupListPrivacy { get; }
public int? MemberLimitOverride { get; }
public int? GroupLimitOverride { get; }
[JsonIgnore] public DateTimeZone Zone => DateTimeZoneProviders.Tzdb.GetZoneOrNull(UiTz); [JsonIgnore] public DateTimeZone Zone => DateTimeZoneProviders.Tzdb.GetZoneOrNull(UiTz);
} }

View File

@ -5,7 +5,7 @@ namespace PluralKit.Core {
public static readonly int MaxSystemNameLength = 100; public static readonly int MaxSystemNameLength = 100;
public static readonly int MaxSystemTagLength = MaxProxyNameLength - 1; public static readonly int MaxSystemTagLength = MaxProxyNameLength - 1;
public static readonly int MaxMemberCount = 1500; public static readonly int MaxMemberCount = 1000;
public static readonly int MaxMembersWarnThreshold = MaxMemberCount - 50; public static readonly int MaxMembersWarnThreshold = MaxMemberCount - 50;
public static readonly int MaxGroupCount = 250; public static readonly int MaxGroupCount = 250;
public static readonly int MaxDescriptionLength = 1000; public static readonly int MaxDescriptionLength = 1000;