:drunk: Write shit code trying to split up the Auth (WIP)
This commit is contained in:
		| @@ -1,134 +0,0 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using System.ComponentModel.DataAnnotations.Schema; | ||||
| using System.Text.Json.Serialization; | ||||
| using DysonNetwork.Sphere.Activity; | ||||
| using DysonNetwork.Sphere.Storage; | ||||
| using NodaTime; | ||||
| using NpgsqlTypes; | ||||
|  | ||||
| namespace DysonNetwork.Sphere.Post; | ||||
|  | ||||
| public enum PostType | ||||
| { | ||||
|     Moment, | ||||
|     Article, | ||||
|     Video | ||||
| } | ||||
|  | ||||
| public enum PostVisibility | ||||
| { | ||||
|     Public, | ||||
|     Friends, | ||||
|     Unlisted, | ||||
|     Private | ||||
| } | ||||
|  | ||||
| public class Post : ModelBase, IIdentifiedResource, IActivity | ||||
| { | ||||
|     public Guid Id { get; set; } | ||||
|     [MaxLength(1024)] public string? Title { get; set; } | ||||
|     [MaxLength(4096)] public string? Description { get; set; } | ||||
|     [MaxLength(128)] public string? Language { get; set; } | ||||
|     public Instant? EditedAt { get; set; } | ||||
|     public Instant? PublishedAt { get; set; } | ||||
|     public PostVisibility Visibility { get; set; } = PostVisibility.Public; | ||||
|  | ||||
|     // ReSharper disable once EntityFramework.ModelValidation.UnlimitedStringLength | ||||
|     public string? Content { get; set; } | ||||
|  | ||||
|     public PostType Type { get; set; } | ||||
|     [Column(TypeName = "jsonb")] public Dictionary<string, object>? Meta { get; set; } | ||||
|     [Column(TypeName = "jsonb")] public List<ContentSensitiveMark>? SensitiveMarks { get; set; } = []; | ||||
|  | ||||
|     public int ViewsUnique { get; set; } | ||||
|     public int ViewsTotal { get; set; } | ||||
|     public int Upvotes { get; set; } | ||||
|     public int Downvotes { get; set; } | ||||
|     [NotMapped] public Dictionary<string, int> ReactionsCount { get; set; } = new(); | ||||
|     [NotMapped] public int RepliesCount { get; set; } | ||||
|  | ||||
|     public Guid? RepliedPostId { get; set; } | ||||
|     public Post? RepliedPost { get; set; } | ||||
|     public Guid? ForwardedPostId { get; set; } | ||||
|     public Post? ForwardedPost { get; set; } | ||||
|  | ||||
|     // Outdated fields, keep for backward compability | ||||
|     public ICollection<CloudFile> OutdatedAttachments { get; set; } = new List<CloudFile>(); | ||||
|     [Column(TypeName = "jsonb")] public List<CloudFileReferenceObject> Attachments { get; set; } = []; | ||||
|  | ||||
|     [JsonIgnore] public NpgsqlTsVector SearchVector { get; set; } = null!; | ||||
|  | ||||
|     public Guid PublisherId { get; set; } | ||||
|     public Publisher.Publisher Publisher { get; set; } = null!; | ||||
|  | ||||
|     public ICollection<PostReaction> Reactions { get; set; } = new List<PostReaction>(); | ||||
|     public ICollection<PostTag> Tags { get; set; } = new List<PostTag>(); | ||||
|     public ICollection<PostCategory> Categories { get; set; } = new List<PostCategory>(); | ||||
|     [JsonIgnore] public ICollection<PostCollection> Collections { get; set; } = new List<PostCollection>(); | ||||
|  | ||||
|     [JsonIgnore] public bool Empty => Content == null && Attachments.Count == 0 && ForwardedPostId == null; | ||||
|     [NotMapped] public bool IsTruncated { get; set; } = false; | ||||
|  | ||||
|     public string ResourceIdentifier => $"post/{Id}"; | ||||
|  | ||||
|     public Activity.Activity ToActivity() | ||||
|     { | ||||
|         return new Activity.Activity() | ||||
|         { | ||||
|             CreatedAt = PublishedAt ?? CreatedAt, | ||||
|             UpdatedAt = UpdatedAt, | ||||
|             DeletedAt = DeletedAt, | ||||
|             Id = Id, | ||||
|             Type = RepliedPostId is null ? "posts.new" : "posts.new.replies", | ||||
|             ResourceIdentifier = ResourceIdentifier, | ||||
|             Data = this | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| public class PostTag : ModelBase | ||||
| { | ||||
|     public Guid Id { get; set; } | ||||
|     [MaxLength(128)] public string Slug { get; set; } = null!; | ||||
|     [MaxLength(256)] public string? Name { get; set; } | ||||
|     [JsonIgnore] public ICollection<Post> Posts { get; set; } = new List<Post>(); | ||||
| } | ||||
|  | ||||
| public class PostCategory : ModelBase | ||||
| { | ||||
|     public Guid Id { get; set; } | ||||
|     [MaxLength(128)] public string Slug { get; set; } = null!; | ||||
|     [MaxLength(256)] public string? Name { get; set; } | ||||
|     [JsonIgnore] public ICollection<Post> Posts { get; set; } = new List<Post>(); | ||||
| } | ||||
|  | ||||
| public class PostCollection : ModelBase | ||||
| { | ||||
|     public Guid Id { get; set; } | ||||
|     [MaxLength(128)] public string Slug { get; set; } = null!; | ||||
|     [MaxLength(256)] public string? Name { get; set; } | ||||
|     [MaxLength(4096)] public string? Description { get; set; } | ||||
|  | ||||
|     public Publisher.Publisher Publisher { get; set; } = null!; | ||||
|  | ||||
|     public ICollection<Post> Posts { get; set; } = new List<Post>(); | ||||
| } | ||||
|  | ||||
| public enum PostReactionAttitude | ||||
| { | ||||
|     Positive, | ||||
|     Neutral, | ||||
|     Negative, | ||||
| } | ||||
|  | ||||
| public class PostReaction : ModelBase | ||||
| { | ||||
|     public Guid Id { get; set; } | ||||
|     [MaxLength(256)] public string Symbol { get; set; } = null!; | ||||
|     public PostReactionAttitude Attitude { get; set; } | ||||
|  | ||||
|     public Guid PostId { get; set; } | ||||
|     [JsonIgnore] public Post Post { get; set; } = null!; | ||||
|     public Guid AccountId { get; set; } | ||||
|     public Account.Account Account { get; set; } = null!; | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using System.Text.Json; | ||||
| using DysonNetwork.Sphere.Account; | ||||
| using DysonNetwork.Common.Models; | ||||
| using DysonNetwork.Sphere.Permission; | ||||
| using DysonNetwork.Sphere.Publisher; | ||||
| using DysonNetwork.Sphere.Storage; | ||||
| @@ -24,7 +24,7 @@ public class PostController( | ||||
|     : ControllerBase | ||||
| { | ||||
|     [HttpGet] | ||||
|     public async Task<ActionResult<List<Post>>> ListPosts( | ||||
|     public async Task<ActionResult<List<Common.Models.Post>>> ListPosts( | ||||
|         [FromQuery] int offset = 0, | ||||
|         [FromQuery] int take = 20, | ||||
|         [FromQuery(Name = "pub")] string? pubName = null | ||||
| @@ -63,7 +63,7 @@ public class PostController( | ||||
|     } | ||||
|  | ||||
|     [HttpGet("{id:guid}")] | ||||
|     public async Task<ActionResult<Post>> GetPost(Guid id) | ||||
|     public async Task<ActionResult<Common.Models.Post>> GetPost(Guid id) | ||||
|     { | ||||
|         HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue); | ||||
|         var currentUser = currentUserValue as Account.Account; | ||||
| @@ -87,7 +87,7 @@ public class PostController( | ||||
|     } | ||||
|  | ||||
|     [HttpGet("search")] | ||||
|     public async Task<ActionResult<List<Post>>> SearchPosts( | ||||
|     public async Task<ActionResult<List<Common.Models.Post>>> SearchPosts( | ||||
|         [FromQuery] string query, | ||||
|         [FromQuery] int offset = 0, | ||||
|         [FromQuery] int take = 20, | ||||
| @@ -131,7 +131,7 @@ public class PostController( | ||||
|     } | ||||
|  | ||||
|     [HttpGet("{id:guid}/replies")] | ||||
|     public async Task<ActionResult<List<Post>>> ListReplies(Guid id, [FromQuery] int offset = 0, | ||||
|     public async Task<ActionResult<List<Common.Models.Post>>> ListReplies(Guid id, [FromQuery] int offset = 0, | ||||
|         [FromQuery] int take = 20) | ||||
|     { | ||||
|         HttpContext.Items.TryGetValue("CurrentUser", out var currentUserValue); | ||||
| @@ -189,7 +189,7 @@ public class PostController( | ||||
|  | ||||
|     [HttpPost] | ||||
|     [RequiredPermission("global", "posts.create")] | ||||
|     public async Task<ActionResult<Post>> CreatePost( | ||||
|     public async Task<ActionResult<Common.Models.Post>> CreatePost( | ||||
|         [FromBody] PostRequest request, | ||||
|         [FromHeader(Name = "X-Pub")] string? publisherName | ||||
|     ) | ||||
| @@ -220,7 +220,7 @@ public class PostController( | ||||
|  | ||||
|         if (publisher is null) return BadRequest("Publisher was not found."); | ||||
|  | ||||
|         var post = new Post | ||||
|         var post = new Common.Models.Post | ||||
|         { | ||||
|             Title = request.Title, | ||||
|             Description = request.Description, | ||||
| @@ -327,7 +327,7 @@ public class PostController( | ||||
|     } | ||||
|  | ||||
|     [HttpPatch("{id:guid}")] | ||||
|     public async Task<ActionResult<Post>> UpdatePost(Guid id, [FromBody] PostRequest request) | ||||
|     public async Task<ActionResult<Common.Models.Post>> UpdatePost(Guid id, [FromBody] PostRequest request) | ||||
|     { | ||||
|         request.Content = TextSanitizer.Sanitize(request.Content); | ||||
|         if (string.IsNullOrWhiteSpace(request.Content) && request.Attachments is { Count: 0 }) | ||||
| @@ -376,7 +376,7 @@ public class PostController( | ||||
|     } | ||||
|  | ||||
|     [HttpDelete("{id:guid}")] | ||||
|     public async Task<ActionResult<Post>> DeletePost(Guid id) | ||||
|     public async Task<ActionResult<Common.Models.Post>> DeletePost(Guid id) | ||||
|     { | ||||
|         if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized(); | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| using System.Text.RegularExpressions; | ||||
| using DysonNetwork.Sphere.Account; | ||||
| using DysonNetwork.Common.Models; | ||||
| using DysonNetwork.Common.Services; | ||||
| using DysonNetwork.Sphere.Connection.WebReader; | ||||
| using DysonNetwork.Sphere.Localization; | ||||
| using DysonNetwork.Sphere.Publisher; | ||||
| @@ -23,7 +24,7 @@ public partial class PostService( | ||||
| { | ||||
|     private const string PostFileUsageIdentifier = "post"; | ||||
|  | ||||
|     private static List<Post> TruncatePostContent(List<Post> input) | ||||
|     private static List<Common.Models.Post> TruncatePostContent(List<Common.Models.Post> input) | ||||
|     { | ||||
|         const int maxLength = 256; | ||||
|         const int embedMaxLength = 80; | ||||
| @@ -53,7 +54,7 @@ public partial class PostService( | ||||
|         return input; | ||||
|     } | ||||
|  | ||||
|     public (string title, string content) ChopPostForNotification(Post post) | ||||
|     public (string title, string content) ChopPostForNotification(Common.Models.Post post) | ||||
|     { | ||||
|         var content = !string.IsNullOrEmpty(post.Description) | ||||
|             ? post.Description?.Length >= 40 ? post.Description[..37] + "..." : post.Description | ||||
| @@ -68,9 +69,9 @@ public partial class PostService( | ||||
|         return (title, content); | ||||
|     } | ||||
|  | ||||
|     public async Task<Post> PostAsync( | ||||
|     public async Task<Common.Models.Post> PostAsync( | ||||
|         Account.Account user, | ||||
|         Post post, | ||||
|         Common.Models.Post post, | ||||
|         List<string>? attachments = null, | ||||
|         List<string>? tags = null, | ||||
|         List<string>? categories = null | ||||
| @@ -191,8 +192,8 @@ public partial class PostService( | ||||
|         return post; | ||||
|     } | ||||
|  | ||||
|     public async Task<Post> UpdatePostAsync( | ||||
|         Post post, | ||||
|     public async Task<Common.Models.Post> UpdatePostAsync( | ||||
|         Common.Models.Post post, | ||||
|         List<string>? attachments = null, | ||||
|         List<string>? tags = null, | ||||
|         List<string>? categories = null, | ||||
| @@ -269,7 +270,7 @@ public partial class PostService( | ||||
|     [GeneratedRegex(@"https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]*[-A-Za-z0-9+&@#/%=~_|]")] | ||||
|     private static partial Regex GetLinkRegex(); | ||||
|  | ||||
|     public async Task<Post> PreviewPostLinkAsync(Post item) | ||||
|     public async Task<Common.Models.Post> PreviewPostLinkAsync(Common.Models.Post item) | ||||
|     { | ||||
|         if (item.Type != PostType.Moment || string.IsNullOrEmpty(item.Content)) return item; | ||||
|  | ||||
| @@ -328,7 +329,7 @@ public partial class PostService( | ||||
|     /// This method is designed to be called from a background task | ||||
|     /// </summary> | ||||
|     /// <param name="post">The post to process link previews for</param> | ||||
|     private async Task ProcessPostLinkPreviewAsync(Post post) | ||||
|     private async Task ProcessPostLinkPreviewAsync(Common.Models.Post post) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
| @@ -367,7 +368,7 @@ public partial class PostService( | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public async Task DeletePostAsync(Post post) | ||||
|     public async Task DeletePostAsync(Common.Models.Post post) | ||||
|     { | ||||
|         var postResourceId = $"post:{post.Id}"; | ||||
|  | ||||
| @@ -389,7 +390,7 @@ public partial class PostService( | ||||
|     /// <param name="isSelfReact">Indicate this reaction is by the original post himself</param> | ||||
|     /// <param name="sender">The account that creates this reaction</param> | ||||
|     public async Task<bool> ModifyPostVotes( | ||||
|         Post post, | ||||
|         Common.Models.Post post, | ||||
|         PostReaction reaction, | ||||
|         Account.Account sender, | ||||
|         bool isRemoving, | ||||
| @@ -528,10 +529,10 @@ public partial class PostService( | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public async Task<List<Post>> LoadPublishers(List<Post> posts) | ||||
|     public async Task<List<Common.Models.Post>> LoadPublishers(List<Common.Models.Post> posts) | ||||
|     { | ||||
|         var publisherIds = posts | ||||
|             .SelectMany<Post, Guid?>(e => | ||||
|             .SelectMany<Common.Models.Post, Guid?>(e => | ||||
|             [ | ||||
|                 e.PublisherId, | ||||
|                 e.RepliedPost?.PublisherId, | ||||
| @@ -563,7 +564,7 @@ public partial class PostService( | ||||
|         return posts; | ||||
|     } | ||||
|  | ||||
|     public async Task<List<Post>> LoadInteractive(List<Post> posts, Account.Account? currentUser = null) | ||||
|     public async Task<List<Common.Models.Post>> LoadInteractive(List<Common.Models.Post> posts, Account.Account? currentUser = null) | ||||
|     { | ||||
|         if (posts.Count == 0) return posts; | ||||
|  | ||||
| @@ -605,7 +606,7 @@ public partial class PostService( | ||||
|             ); | ||||
|     } | ||||
|  | ||||
|     public async Task<List<Post>> LoadPostInfo(List<Post> posts, Account.Account? currentUser = null, | ||||
|     public async Task<List<Common.Models.Post>> LoadPostInfo(List<Common.Models.Post> posts, Account.Account? currentUser = null, | ||||
|         bool truncate = false) | ||||
|     { | ||||
|         if (posts.Count == 0) return posts; | ||||
| @@ -619,7 +620,7 @@ public partial class PostService( | ||||
|         return posts; | ||||
|     } | ||||
|  | ||||
|     public async Task<Post> LoadPostInfo(Post post, Account.Account? currentUser = null, bool truncate = false) | ||||
|     public async Task<Common.Models.Post> LoadPostInfo(Common.Models.Post post, Account.Account? currentUser = null, bool truncate = false) | ||||
|     { | ||||
|         // Convert single post to list, process it, then return the single post | ||||
|         var posts = await LoadPostInfo([post], currentUser, truncate); | ||||
| @@ -629,8 +630,8 @@ public partial class PostService( | ||||
|  | ||||
| public static class PostQueryExtensions | ||||
| { | ||||
|     public static IQueryable<Post> FilterWithVisibility( | ||||
|         this IQueryable<Post> source, | ||||
|     public static IQueryable<Common.Models.Post> FilterWithVisibility( | ||||
|         this IQueryable<Common.Models.Post> source, | ||||
|         Account.Account? currentUser, | ||||
|         List<Guid> userFriends, | ||||
|         List<Publisher.Publisher> publishers, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user