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]
public async Task<ActionResult<JObject>> PostMember([FromBody] JObject properties)
{
var system = User.CurrentSystem();
if (!properties.ContainsKey("name"))
return BadRequest("Member name must be specified.");
var systemId = User.CurrentSystem();
await using var conn = await _db.Obtain();
var systemData = await _repo.GetSystem(conn, systemId);
// Enforce per-system member limit
var memberCount = await conn.QuerySingleAsync<int>("select count(*) from members where system = @System", new {System = system});
if (memberCount >= Limits.MaxMemberCount)
return BadRequest($"Member limit reached ({memberCount} / {Limits.MaxMemberCount}).");
var memberCount = await conn.QuerySingleAsync<int>("select count(*) from members where system = @System", new {System = systemId});
var memberLimit = systemData?.MemberLimitOverride ?? 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;
try
{

View File

@ -38,8 +38,9 @@ namespace PluralKit.Bot
// Check group cap
var existingGroupCount = await conn.QuerySingleAsync<int>("select count(*) from groups where system = @System", new { System = ctx.System.Id });
if (existingGroupCount >= 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.");
var groupLimit = ctx.System.GroupLimitOverride ?? Limits.MaxGroupCount;
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
var existingGroup = await _repo.GetGroupByName(conn, ctx.System.Id, groupName);

View File

@ -37,8 +37,9 @@ namespace PluralKit.Bot
// Enforce per-system member limit
var memberCount = await _repo.GetSystemMemberCount(conn, ctx.System.Id);
if (memberCount >= Limits.MaxMemberCount)
throw Errors.MemberLimitReachedError;
var memberLimit = ctx.System.MemberLimitOverride ?? Limits.MaxMemberCount;
if (memberCount >= memberLimit)
throw Errors.MemberLimitReachedError(memberLimit);
// Create the member
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 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 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 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
{
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 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 FrontHistoryPrivacy { get; }
public PrivacyLevel GroupListPrivacy { get; }
public int? MemberLimitOverride { get; }
public int? GroupLimitOverride { get; }
[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 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 MaxGroupCount = 250;
public static readonly int MaxDescriptionLength = 1000;