public static SystemPatch WithAllPrivacy(this SystemPatch system, PrivacyLevel level) { foreach (var subject in Enum.GetValues(typeof(SystemPrivacySubject))) { WithPrivacy(system, (SystemPrivacySubject)subject, level); } return(system); }
private async Task <string> MakeAndSetNewToken(PKSystem system) { var patch = new SystemPatch { Token = StringUtils.GenerateToken() }; system = await _db.Execute(conn => conn.UpdateSystem(system.Id, patch)); return(system.Token); }
public async Task Color(Context ctx) { ctx.CheckSystem(); if (await ctx.MatchClear()) { var patch = new SystemPatch { Color = Partial <string> .Null() }; await _db.Execute(conn => _repo.UpdateSystem(conn, ctx.System.Id, patch)); await ctx.Reply($"{Emojis.Success} System color cleared."); } else if (!ctx.HasNext()) { if (ctx.System.Color == null) { await ctx.Reply( $"Your system does not have a color set. To set one, type `pk;system color <color>`."); } else { await ctx.Reply(embed : new EmbedBuilder() .Title("System color") .Color(ctx.System.Color.ToDiscordColor()) .Thumbnail(new($"https://fakeimg.pl/256x256/{ctx.System.Color}/?text=%20")) .Description($"Your system's color is **#{ctx.System.Color}**. To clear it, type `pk;s color -clear`.") .Build()); } } else { var color = ctx.RemainderOrNull(); if (color.StartsWith("#")) { color = color.Substring(1); } if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$")) { throw Errors.InvalidColorError(color); } var patch = new SystemPatch { Color = Partial <string> .Present(color.ToLowerInvariant()) }; await _db.Execute(conn => _repo.UpdateSystem(conn, ctx.System.Id, patch)); await ctx.Reply(embed : new EmbedBuilder() .Title($"{Emojis.Success} System color changed.") .Color(color.ToDiscordColor()) .Thumbnail(new($"https://fakeimg.pl/256x256/{color}/?text=%20")) .Build()); } }
public async Task Description(Context ctx) { ctx.CheckSystem(); if (ctx.MatchClear()) { var patch = new SystemPatch { Description = null }; await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, patch)); await ctx.Reply($"{Emojis.Success} System description cleared."); return; } var newDescription = ctx.RemainderOrNull()?.NormalizeLineEndSpacing(); if (newDescription == null) { if (ctx.System.Description == null) { await ctx.Reply("Your system does not have a description set. To set one, type `pk;s description <description>`."); } else if (ctx.MatchFlag("r", "raw")) { await ctx.Reply($"```\n{ctx.System.Description}\n```"); } else { await ctx.Reply(embed : new DiscordEmbedBuilder() .WithTitle("System description") .WithDescription(ctx.System.Description) .WithFooter("To print the description with formatting, type `pk;s description -raw`. To clear it, type `pk;s description -clear`. To change it, type `pk;s description <new description>`.") .Build()); } } else { if (newDescription.Length > Limits.MaxDescriptionLength) { throw Errors.DescriptionTooLongError(newDescription.Length); } var patch = new SystemPatch { Description = newDescription }; await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, patch)); await ctx.Reply($"{Emojis.Success} System description changed."); } }
public async Task <PKSystem> UpdateSystem(SystemId id, SystemPatch patch, IPKConnection?conn = null) { _logger.Information("Updated {SystemId}: {@SystemPatch}", id, patch); var query = patch.Apply(new Query("systems").Where("id", id)); var res = await _db.QueryFirst <PKSystem>(conn, query, "returning *"); _ = _dispatch.Dispatch(id, new UpdateDispatchData { Event = DispatchEvent.UPDATE_SYSTEM, EventData = patch.ToJson(), }); return(res); }
public static SystemPatch WithPrivacy(this SystemPatch system, SystemPrivacySubject subject, PrivacyLevel level) { // what do you mean switch expressions can't be statements >.> _ = subject switch { SystemPrivacySubject.Description => system.DescriptionPrivacy = level, SystemPrivacySubject.Front => system.FrontPrivacy = level, SystemPrivacySubject.FrontHistory => system.FrontHistoryPrivacy = level, SystemPrivacySubject.MemberList => system.MemberListPrivacy = level, SystemPrivacySubject.GroupList => system.GroupListPrivacy = level, _ => throw new ArgumentOutOfRangeException($"Unknown privacy subject {subject}") }; return(system); }
public async Task Name(Context ctx) { ctx.CheckSystem(); if (ctx.MatchClear()) { var clearPatch = new SystemPatch { Name = null }; await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, clearPatch)); await ctx.Reply($"{Emojis.Success} System name cleared."); return; } var newSystemName = ctx.RemainderOrNull(); if (newSystemName == null) { if (ctx.System.Name != null) { await ctx.Reply($"Your system's name is currently **{ctx.System.Name}**. Type `pk;system name -clear` to clear it."); } else { await ctx.Reply("Your system currently does not have a name. Type `pk;system name <name>` to set one."); } return; } if (newSystemName != null && newSystemName.Length > Limits.MaxSystemNameLength) { throw Errors.SystemNameTooLongError(newSystemName.Length); } var patch = new SystemPatch { Name = newSystemName }; await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, patch)); await ctx.Reply($"{Emojis.Success} System name changed."); }
public async Task Tag(Context ctx) { ctx.CheckSystem(); if (ctx.MatchClear()) { var patch = new SystemPatch { Tag = null }; await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, patch)); await ctx.Reply($"{Emojis.Success} System tag cleared."); } else if (!ctx.HasNext(skipFlags: false)) { if (ctx.System.Tag == null) { await ctx.Reply($"You currently have no system tag. To set one, type `pk;s tag <tag>`."); } else { await ctx.Reply($"Your current system tag is `{ctx.System.Tag}`. To change it, type `pk;s tag <tag>`. To clear it, type `pk;s tag -clear`."); } } else { var newTag = ctx.RemainderOrNull(skipFlags: false); if (newTag != null) { if (newTag.Length > Limits.MaxSystemTagLength) { throw Errors.SystemNameTooLongError(newTag.Length); } } var patch = new SystemPatch { Tag = newTag }; await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, patch)); await ctx.Reply($"{Emojis.Success} System tag changed. Member names will now end with `{newTag}` when proxied."); } }
public static SystemPatch ToSystemPatch(JObject o) { var patch = new SystemPatch(); if (o.ContainsKey("name")) { patch.Name = o.Value <string>("name").NullIfEmpty().BoundsCheckField(Limits.MaxSystemNameLength, "System name"); } if (o.ContainsKey("description")) { patch.Description = o.Value <string>("description").NullIfEmpty().BoundsCheckField(Limits.MaxDescriptionLength, "System description"); } if (o.ContainsKey("tag")) { patch.Tag = o.Value <string>("tag").NullIfEmpty().BoundsCheckField(Limits.MaxSystemTagLength, "System tag"); } if (o.ContainsKey("avatar_url")) { patch.AvatarUrl = o.Value <string>("avatar_url").NullIfEmpty().BoundsCheckField(Limits.MaxUriLength, "System avatar URL"); } if (o.ContainsKey("tz")) { patch.UiTz = o.Value <string>("tz") ?? "UTC"; } if (o.ContainsKey("description_privacy")) { patch.DescriptionPrivacy = o.Value <string>("description_privacy").ParsePrivacy("description"); } if (o.ContainsKey("member_list_privacy")) { patch.MemberListPrivacy = o.Value <string>("member_list_privacy").ParsePrivacy("member list"); } if (o.ContainsKey("front_privacy")) { patch.FrontPrivacy = o.Value <string>("front_privacy").ParsePrivacy("front"); } if (o.ContainsKey("front_history_privacy")) { patch.FrontHistoryPrivacy = o.Value <string>("front_history_privacy").ParsePrivacy("front history"); } return(patch); }
public async Task <ActionResult <JObject> > EditSystem([FromBody] JObject changes) { var system = await _repo.GetSystem(User.CurrentSystem()); var patch = SystemPatch.FromJSON(changes); patch.AssertIsValid(); if (patch.Errors.Count > 0) { var err = patch.Errors[0]; if (err is FieldTooLongError) { return(BadRequest($"Field {err.Key} is too long " + $"({(err as FieldTooLongError).ActualLength} > {(err as FieldTooLongError).MaxLength}).")); } return(BadRequest($"Field {err.Key} is invalid.")); } system = await _repo.UpdateSystem(system !.Id, patch); return(Ok(system.ToJson(User.ContextFor(system)))); }
public async Task <IActionResult> DoSystemPatch(string systemRef, [FromBody] JObject data) { var system = await ResolveSystem(systemRef); if (system == null) { throw Errors.SystemNotFound; } if (ContextFor(system) != LookupContext.ByOwner) { throw Errors.GenericMissingPermissions; } var patch = SystemPatch.FromJSON(data); patch.AssertIsValid(); if (patch.Errors.Count > 0) { throw new ModelParseError(patch.Errors); } var newSystem = await _repo.UpdateSystem(system.Id, patch); return(Ok(newSystem.ToJson(LookupContext.ByOwner))); }
private async Task <ImportResultNew> ImportPluralKit(JObject importFile) { var patch = SystemPatch.FromJSON(importFile, isImport: true); patch.AssertIsValid(); if (patch.Errors.Count > 0) { var err = patch.Errors[0]; if (err is FieldTooLongError) { throw new ImportException($"Field {err.Key} in export file is too long " + $"({(err as FieldTooLongError).ActualLength} > {(err as FieldTooLongError).MaxLength})."); } if (err.Text != null) { throw new ImportException(err.Text); } throw new ImportException($"Field {err.Key} in export file is invalid."); } await _repo.UpdateSystem(_system.Id, patch, _conn); if (importFile.ContainsKey("config")) { var configPatch = SystemConfigPatch.FromJson(importFile.Value <JObject>("config")); if (importFile.ContainsKey("timezone")) { configPatch.UiTz = importFile.Value <string>("timezone"); } configPatch.AssertIsValid(); if (configPatch.Errors.Count > 0) { throw new ImportException($"Field config.{patch.Errors[0].Key} in export file is invalid."); } await _repo.UpdateSystemConfig(_system.Id, configPatch, _conn); } var members = importFile.Value <JArray>("members"); var switches = importFile.Value <JArray>("switches"); var groups = importFile.Value <JArray>("groups"); var newMembers = members.Count(m => { var(found, _) = TryGetExistingMember(m.Value <string>("id"), m.Value <string>("name")); return(found == null); }); await AssertMemberLimitNotReached(newMembers); if (groups != null) { var newGroups = groups.Count(g => { var(found, _) = TryGetExistingGroup(g.Value <string>("id"), g.Value <string>("name")); return(found == null); }); await AssertGroupLimitNotReached(newGroups); } foreach (JObject member in members) { await ImportMember(member); } if (groups != null) { foreach (JObject group in groups) { await ImportGroup(group); } } if (switches.Any(sw => sw.Value <JArray>("members").Any(m => !_knownMemberIdentifiers.ContainsKey((string)m)))) { throw new ImportException("One or more switches include members that haven't been imported."); } await ImportSwitches(switches); return(_result); }