159 lines
7.0 KiB
C#
159 lines
7.0 KiB
C#
using PrivaPub.ClientModels.Resources;
|
|||
|
|
|
||
|
|
using System.ComponentModel.DataAnnotations;
|
||
|
|
|
||
|
|
namespace PrivaPub.ClientModels.Admin
|
||
|
|
{
|
||
|
|
// The staff's acts on accounts and posts (completion program R6). Moderators silence and suspend personas here and
|
||
|
|
// accounts elsewhere, remove posts and resolve reports with one of those acts; administrators also change logins
|
||
|
|
// (roles, bans, deletions, two-factor sign-in). Every act is kept in the staff's log.
|
||
|
|
public static class ModerationActions
|
||
|
|
{
|
||
|
|
public const string None = "none";
|
||
|
|
public const string Silence = "silence";
|
||
|
|
public const string Unsilence = "unsilence";
|
||
|
|
public const string Suspend = "suspend";
|
||
|
|
public const string Unsuspend = "unsuspend";
|
||
|
|
public const string RemovePosts = "remove_posts";//a report's resolution only: the posts it names
|
||
|
|
|
||
|
|
public static bool IsAccountAction(string action) => action is Silence or Unsilence or Suspend or Unsuspend;
|
||
|
|
|
||
|
|
public static bool IsResolution(string action) => action is None or Silence or Suspend or RemovePosts;
|
||
|
|
}
|
||
|
|
|
||
|
|
// POST /clientapi/moderator/accounts/moderate: a persona here (its id) or an account elsewhere (its id here)
|
||
|
|
public class ModerateAccountForm
|
||
|
|
{
|
||
|
|
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
StringLength(64, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string AccountId { get; set; }
|
||
|
|
|
||
|
|
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
StringLength(16, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Action { get; set; }//ModerationActions: silence, unsilence, suspend, unsuspend
|
||
|
|
|
||
|
|
// the staff's own words: kept in the log and on the account, never shown to it
|
||
|
|
[StringLength(1000, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Note { get; set; }
|
||
|
|
|
||
|
|
// what a persona here is told with its warning (Mastodon's moderation_warning); nothing reaches an account elsewhere
|
||
|
|
[StringLength(1000, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Warning { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
// POST /clientapi/moderator/posts/remove: a post here is deleted as its author would (the deletion federates), a copy of
|
||
|
|
// a post elsewhere is taken down here only
|
||
|
|
public class RemovePostForm
|
||
|
|
{
|
||
|
|
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
StringLength(64, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string PostId { get; set; }
|
||
|
|
|
||
|
|
[StringLength(1000, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Note { get; set; }
|
||
|
|
|
||
|
|
[StringLength(1000, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Warning { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
// POST /clientapi/moderator/reports/{id}/resolve: the body is optional; without one, or with action none, the report is
|
||
|
|
// only marked resolved
|
||
|
|
public class ResolveReportForm
|
||
|
|
{
|
||
|
|
[StringLength(16, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Action { get; set; } = ModerationActions.None;//none, silence, suspend, remove_posts
|
||
|
|
|
||
|
|
[StringLength(1000, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Note { get; set; }
|
||
|
|
|
||
|
|
[StringLength(1000, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Warning { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
// an account as moderators see it: a persona here (never its login) or an account elsewhere, and what the staff did to it
|
||
|
|
public class ViewModeratedAccount
|
||
|
|
{
|
||
|
|
public string Id { get; set; }
|
||
|
|
public bool IsLocal { get; set; } = false;
|
||
|
|
public string UserName { get; set; }
|
||
|
|
public string DisplayName { get; set; }
|
||
|
|
public string Handle { get; set; }//user@host
|
||
|
|
public string Url { get; set; }//its actor's id
|
||
|
|
public string Domain { get; set; }
|
||
|
|
public DateTime? SilencedAt { get; set; }
|
||
|
|
public DateTime? SuspendedAt { get; set; }
|
||
|
|
public bool DomainSilenced { get; set; } = false;//an account elsewhere whose server is silenced: limited without its own silence
|
||
|
|
public bool DomainSuspended { get; set; } = false;
|
||
|
|
public string Note { get; set; }//the staff's last note on it
|
||
|
|
}
|
||
|
|
|
||
|
|
// GET /clientapi/moderator/accounts?q= and /clientapi/moderator/accounts/moderated?offset=&limit=: Next is the offset of
|
||
|
|
// the next page, null on the last
|
||
|
|
public class ViewModeratedAccountsPage
|
||
|
|
{
|
||
|
|
public List<ViewModeratedAccount> Items { get; set; } = [];
|
||
|
|
public int? Next { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
// a login as administrators see it (GET /clientapi/admin/roots), with its personas: only administrators ever read a login
|
||
|
|
// next to its personas
|
||
|
|
public class ViewAdminRoot
|
||
|
|
{
|
||
|
|
public string Id { get; set; }
|
||
|
|
public string UserName { get; set; }
|
||
|
|
public string Role { get; set; }//user, moderator, admin
|
||
|
|
public bool IsBanned { get; set; } = false;
|
||
|
|
public bool HasEmail { get; set; } = false;
|
||
|
|
public bool IsEmailValidated { get; set; } = false;
|
||
|
|
public bool HasTotp { get; set; } = false;
|
||
|
|
public bool IsYou { get; set; } = false;
|
||
|
|
public DateTime CreatedAt { get; set; }
|
||
|
|
public List<ViewAdminPersona> Personas { get; set; } = [];
|
||
|
|
}
|
||
|
|
|
||
|
|
public class ViewAdminPersona
|
||
|
|
{
|
||
|
|
public string Id { get; set; }
|
||
|
|
public string UserName { get; set; }
|
||
|
|
public string DisplayName { get; set; }
|
||
|
|
public string Handle { get; set; }
|
||
|
|
public DateTime? SilencedAt { get; set; }
|
||
|
|
public DateTime? SuspendedAt { get; set; }
|
||
|
|
public List<ViewAdminGroup> Groups { get; set; } = [];//the groups it owns
|
||
|
|
}
|
||
|
|
|
||
|
|
public class ViewAdminGroup
|
||
|
|
{
|
||
|
|
public string Id { get; set; }
|
||
|
|
public string UserName { get; set; }
|
||
|
|
public string Name { get; set; }
|
||
|
|
public bool IsCommunity { get; set; } = false;
|
||
|
|
public int MembersCount { get; set; } = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// newest first; Next is the `before` of the next page, null on the last
|
||
|
|
public class ViewAdminRootsPage
|
||
|
|
{
|
||
|
|
public List<ViewAdminRoot> Items { get; set; } = [];
|
||
|
|
public string Next { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
// POST /clientapi/admin/roots/{id}/role
|
||
|
|
public class RootRoleForm
|
||
|
|
{
|
||
|
|
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
StringLength(16, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Role { get; set; }//user, moderator, admin
|
||
|
|
}
|
||
|
|
|
||
|
|
// what can't be undone asks for the administrator's own password: deleting a persona or a group
|
||
|
|
public class AdminPasswordForm
|
||
|
|
{
|
||
|
|
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
Display(Name = "Password", ResourceType = typeof(FieldsNameResource))]
|
||
|
|
public string Password { get; set; }
|
||
|
|
|
||
|
|
[StringLength(1000, ErrorMessageResourceName = "MaxLengthString", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Note { get; set; }
|
||
|
|
}
|
||
|
|
}
|