19
WatchIt.Common/WatchIt.Common.Model/Accounts/Account.cs
Normal file
19
WatchIt.Common/WatchIt.Common.Model/Accounts/Account.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
public abstract class Account
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonPropertyName("username")]
|
||||||
|
public required string Username { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("email")]
|
||||||
|
public required string Email { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("description")]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
public class AccountEmailRequest
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonPropertyName("new_email")]
|
||||||
|
public string NewEmail { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("password")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public void UpdateAccount(Database.Model.Account.Account account)
|
||||||
|
{
|
||||||
|
account.Email = NewEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
public class AccountPasswordRequest
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonPropertyName("old_password")]
|
||||||
|
public string OldPassword { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("new_password")]
|
||||||
|
public string NewPassword { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("new_password_confirmation")]
|
||||||
|
public string NewPasswordConfirmation { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
public class AccountProfileBackgroundRequest
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonPropertyName("id")]
|
||||||
|
public required Guid Id { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
[SetsRequiredMembers]
|
||||||
|
public AccountProfileBackgroundRequest(Guid id)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
public class AccountProfileInfoRequest
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonPropertyName("description")]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("gender_id")]
|
||||||
|
public short? GenderId { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public AccountProfileInfoRequest() { }
|
||||||
|
|
||||||
|
public AccountProfileInfoRequest(AccountResponse accountResponse)
|
||||||
|
{
|
||||||
|
Description = accountResponse.Description;
|
||||||
|
GenderId = accountResponse.Gender?.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public void UpdateAccount(Database.Model.Account.Account account)
|
||||||
|
{
|
||||||
|
account.Description = Description;
|
||||||
|
account.GenderId = GenderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
public class AccountProfilePictureRequest : AccountProfilePicture
|
||||||
|
{
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public AccountProfilePictureRequest() {}
|
||||||
|
|
||||||
|
[SetsRequiredMembers]
|
||||||
|
public AccountProfilePictureRequest(Picture image)
|
||||||
|
{
|
||||||
|
Image = image.Image;
|
||||||
|
MimeType = image.MimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public Database.Model.Account.AccountProfilePicture CreateMediaPosterImage() => new Database.Model.Account.AccountProfilePicture
|
||||||
|
{
|
||||||
|
Image = Image,
|
||||||
|
MimeType = MimeType,
|
||||||
|
};
|
||||||
|
|
||||||
|
public void UpdateMediaPosterImage(Database.Model.Account.AccountProfilePicture item)
|
||||||
|
{
|
||||||
|
item.Image = Image;
|
||||||
|
item.MimeType = MimeType;
|
||||||
|
item.UploadDate = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using WatchIt.Common.Query;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
public class AccountQueryParameters : QueryParameters<AccountResponse>
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[FromQuery(Name = "username")]
|
||||||
|
public string? Username { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "email")]
|
||||||
|
public string? Email { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "description")]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "gender_id")]
|
||||||
|
public short? GenderId { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "last_active")]
|
||||||
|
public DateOnly? LastActive { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "last_active_from")]
|
||||||
|
public DateOnly? LastActiveFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "last_active_to")]
|
||||||
|
public DateOnly? LastActiveTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "creation_date")]
|
||||||
|
public DateOnly? CreationDate { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "creation_date_from")]
|
||||||
|
public DateOnly? CreationDateFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "creation_date_to")]
|
||||||
|
public DateOnly? CreationDateTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "is_admin")]
|
||||||
|
public bool? IsAdmin { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
protected override bool IsMeetingConditions(AccountResponse item) =>
|
||||||
|
(
|
||||||
|
TestStringWithRegex(item.Username, Username)
|
||||||
|
&&
|
||||||
|
TestStringWithRegex(item.Email, Email)
|
||||||
|
&&
|
||||||
|
TestStringWithRegex(item.Description, Description)
|
||||||
|
&&
|
||||||
|
Test(item.Gender?.Id, GenderId)
|
||||||
|
&&
|
||||||
|
TestComparable(item.LastActive, LastActive, LastActiveFrom, LastActiveTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.CreationDate, CreationDate, CreationDateFrom, CreationDateTo)
|
||||||
|
&&
|
||||||
|
Test(item.IsAdmin, IsAdmin)
|
||||||
|
);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using WatchIt.Common.Model.Genders;
|
||||||
|
using WatchIt.Common.Query;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
public class AccountResponse : Account, IQueryOrderable<AccountResponse>
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public static IDictionary<string, Func<AccountResponse, IComparable>> OrderableProperties { get; } = new Dictionary<string, Func<AccountResponse, IComparable>>
|
||||||
|
{
|
||||||
|
{ "id", x => x.Id },
|
||||||
|
{ "username", x => x.Username },
|
||||||
|
{ "email", x => x.Email },
|
||||||
|
{ "description", x => x.Description },
|
||||||
|
{ "gender", x => x.Gender.Name },
|
||||||
|
{ "last_active", x => x.LastActive },
|
||||||
|
{ "creation_date", x => x.CreationDate },
|
||||||
|
{ "is_admin", x => x.IsAdmin }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
[JsonPropertyName("id")]
|
||||||
|
public required long Id { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("gender")]
|
||||||
|
public GenderResponse? Gender { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("last_active")]
|
||||||
|
public DateTime LastActive { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("creation_date")]
|
||||||
|
public DateTime CreationDate { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("is_admin")]
|
||||||
|
public bool IsAdmin { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public AccountResponse() {}
|
||||||
|
|
||||||
|
[SetsRequiredMembers]
|
||||||
|
public AccountResponse(Database.Model.Account.Account account)
|
||||||
|
{
|
||||||
|
Id = account.Id;
|
||||||
|
Username = account.Username;
|
||||||
|
Email = account.Email;
|
||||||
|
Description = account.Description;
|
||||||
|
Gender = account.Gender is not null ? new GenderResponse(account.Gender) : null;
|
||||||
|
LastActive = account.LastActive;
|
||||||
|
CreationDate = account.CreationDate;
|
||||||
|
IsAdmin = account.IsAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
public class AccountUsernameRequest
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonPropertyName("new_username")]
|
||||||
|
public string NewUsername { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("password")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public void UpdateAccount(Database.Model.Account.Account account)
|
||||||
|
{
|
||||||
|
account.Username = NewUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -30,7 +30,7 @@ public class RegisterResponse
|
|||||||
public RegisterResponse() {}
|
public RegisterResponse() {}
|
||||||
|
|
||||||
[SetsRequiredMembers]
|
[SetsRequiredMembers]
|
||||||
public RegisterResponse(Account account)
|
public RegisterResponse(Database.Model.Account.Account account)
|
||||||
{
|
{
|
||||||
Id = account.Id;
|
Id = account.Id;
|
||||||
Username = account.Username;
|
Username = account.Username;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class GenreResponse : Genre, IQueryOrderable<GenreResponse>
|
|||||||
|
|
||||||
|
|
||||||
[JsonPropertyName("id")]
|
[JsonPropertyName("id")]
|
||||||
public long Id { get; set; }
|
public short Id { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ public class MediaQueryParameters : QueryParameters<MediaResponse>
|
|||||||
[FromQuery(Name = "rating_count_to")]
|
[FromQuery(Name = "rating_count_to")]
|
||||||
public long? RatingCountTo { get; set; }
|
public long? RatingCountTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "genre")]
|
||||||
|
public IEnumerable<short>? Genres { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -78,6 +81,8 @@ public class MediaQueryParameters : QueryParameters<MediaResponse>
|
|||||||
TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo)
|
TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo)
|
||||||
&&
|
&&
|
||||||
TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo)
|
TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo)
|
||||||
|
&&
|
||||||
|
TestContains(Genres, item.Genres.Select(x => x.Id))
|
||||||
);
|
);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using WatchIt.Common.Model.Genres;
|
||||||
using WatchIt.Common.Model.Rating;
|
using WatchIt.Common.Model.Rating;
|
||||||
using WatchIt.Common.Query;
|
using WatchIt.Common.Query;
|
||||||
|
using WatchIt.Database.Model.Rating;
|
||||||
|
|
||||||
namespace WatchIt.Common.Model.Media;
|
namespace WatchIt.Common.Model.Media;
|
||||||
|
|
||||||
@@ -32,6 +34,9 @@ public class MediaResponse : Media, IQueryOrderable<MediaResponse>
|
|||||||
[JsonPropertyName("rating")]
|
[JsonPropertyName("rating")]
|
||||||
public RatingResponse Rating { get; set; }
|
public RatingResponse Rating { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("genres")]
|
||||||
|
public IEnumerable<GenreResponse> Genres { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -51,7 +56,10 @@ public class MediaResponse : Media, IQueryOrderable<MediaResponse>
|
|||||||
ReleaseDate = media.ReleaseDate;
|
ReleaseDate = media.ReleaseDate;
|
||||||
Length = media.Length;
|
Length = media.Length;
|
||||||
Type = mediaType;
|
Type = mediaType;
|
||||||
Rating = RatingResponse.Create(media.RatingMedia);
|
Rating = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(media.RatingMedia, x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
Genres = media.Genres.Select(x => new GenreResponse(x)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ public class MovieQueryParameters : QueryParameters<MovieResponse>
|
|||||||
[FromQuery(Name = "rating_count_to")]
|
[FromQuery(Name = "rating_count_to")]
|
||||||
public long? RatingCountTo { get; set; }
|
public long? RatingCountTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "genre")]
|
||||||
|
public IEnumerable<short>? Genres { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -84,6 +87,8 @@ public class MovieQueryParameters : QueryParameters<MovieResponse>
|
|||||||
TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo)
|
TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo)
|
||||||
&&
|
&&
|
||||||
TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo)
|
TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo)
|
||||||
|
&&
|
||||||
|
TestContains(item.Genres.Select(x => x.Id), Genres)
|
||||||
);
|
);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using WatchIt.Common.Query;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Movies;
|
||||||
|
|
||||||
|
public class MovieRatedQueryParameters : QueryParameters<MovieRatedResponse>
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[FromQuery(Name = "title")]
|
||||||
|
public string? Title { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "original_title")]
|
||||||
|
public string? OriginalTitle { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "description")]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "release_date")]
|
||||||
|
public DateOnly? ReleaseDate { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "release_date_from")]
|
||||||
|
public DateOnly? ReleaseDateFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "release_date_to")]
|
||||||
|
public DateOnly? ReleaseDateTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "length")]
|
||||||
|
public short? Length { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "length_from")]
|
||||||
|
public short? LengthFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "length_to")]
|
||||||
|
public short? LengthTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "budget")]
|
||||||
|
public decimal? Budget { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "budget_from")]
|
||||||
|
public decimal? BudgetFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "budget_to")]
|
||||||
|
public decimal? BudgetTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_average")]
|
||||||
|
public decimal? RatingAverage { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_average_from")]
|
||||||
|
public decimal? RatingAverageFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_average_to")]
|
||||||
|
public decimal? RatingAverageTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_count")]
|
||||||
|
public long? RatingCount { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_count_from")]
|
||||||
|
public long? RatingCountFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_count_to")]
|
||||||
|
public long? RatingCountTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "genre")]
|
||||||
|
public IEnumerable<short>? Genres { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating")]
|
||||||
|
public decimal? UserRating { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_from")]
|
||||||
|
public decimal? UserRatingFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_to")]
|
||||||
|
public decimal? UserRatingTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_date")]
|
||||||
|
public DateOnly? UserRatingDate { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_date_from")]
|
||||||
|
public DateOnly? UserRatingDateFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_date_to")]
|
||||||
|
public DateOnly? UserRatingDateTo { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
protected override bool IsMeetingConditions(MovieRatedResponse item) =>
|
||||||
|
(
|
||||||
|
TestStringWithRegex(item.Title, Title)
|
||||||
|
&&
|
||||||
|
TestStringWithRegex(item.OriginalTitle, OriginalTitle)
|
||||||
|
&&
|
||||||
|
TestStringWithRegex(item.Description, Description)
|
||||||
|
&&
|
||||||
|
TestComparable(item.ReleaseDate, ReleaseDate, ReleaseDateFrom, ReleaseDateTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.Length, Length, LengthFrom, LengthTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo)
|
||||||
|
&&
|
||||||
|
TestContains(Genres, item.Genres.Select(x => x.Id))
|
||||||
|
&&
|
||||||
|
TestComparable((decimal)item.UserRating, UserRating, UserRatingFrom, UserRatingTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.UserRatingDate, UserRatingDate, UserRatingDateFrom, UserRatingDateTo)
|
||||||
|
);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using WatchIt.Common.Model.Genres;
|
||||||
|
using WatchIt.Common.Model.Rating;
|
||||||
|
using WatchIt.Common.Query;
|
||||||
|
using WatchIt.Database.Model.Media;
|
||||||
|
using WatchIt.Database.Model.Rating;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Movies;
|
||||||
|
|
||||||
|
public class MovieRatedResponse : MovieResponse, IQueryOrderable<MovieRatedResponse>
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public static IDictionary<string, Func<MovieRatedResponse, IComparable>> OrderableProperties { get; } = new Dictionary<string, Func<MovieRatedResponse, IComparable>>
|
||||||
|
{
|
||||||
|
{ "id", x => x.Id },
|
||||||
|
{ "title", x => x.Title },
|
||||||
|
{ "original_title", x => x.OriginalTitle },
|
||||||
|
{ "description", x => x.Description },
|
||||||
|
{ "release_date", x => x.ReleaseDate },
|
||||||
|
{ "length", x => x.Length },
|
||||||
|
{ "budget", x => x.Budget },
|
||||||
|
{ "rating.average", x => x.Rating.Average },
|
||||||
|
{ "rating.count", x => x.Rating.Count },
|
||||||
|
{ "user_rating", x => x.UserRating },
|
||||||
|
{ "user_rating_date", x => x.UserRatingDate }
|
||||||
|
};
|
||||||
|
|
||||||
|
[JsonPropertyName("user_rating")]
|
||||||
|
public short UserRating { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("user_rating_date")]
|
||||||
|
public DateTime UserRatingDate { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public MovieRatedResponse() { }
|
||||||
|
|
||||||
|
[SetsRequiredMembers]
|
||||||
|
public MovieRatedResponse(MediaMovie mediaMovie, RatingMedia response)
|
||||||
|
{
|
||||||
|
Id = mediaMovie.Media.Id;
|
||||||
|
Title = mediaMovie.Media.Title;
|
||||||
|
OriginalTitle = mediaMovie.Media.OriginalTitle;
|
||||||
|
Description = mediaMovie.Media.Description;
|
||||||
|
ReleaseDate = mediaMovie.Media.ReleaseDate;
|
||||||
|
Length = mediaMovie.Media.Length;
|
||||||
|
Budget = mediaMovie.Budget;
|
||||||
|
Rating = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(mediaMovie.Media.RatingMedia, x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
Genres = mediaMovie.Media.Genres.Select(x => new GenreResponse(x)).ToList();
|
||||||
|
UserRating = response.Rating;
|
||||||
|
UserRatingDate = response.Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using WatchIt.Common.Model.Genres;
|
||||||
using WatchIt.Common.Model.Rating;
|
using WatchIt.Common.Model.Rating;
|
||||||
using WatchIt.Common.Query;
|
using WatchIt.Common.Query;
|
||||||
using WatchIt.Database.Model.Media;
|
using WatchIt.Database.Model.Media;
|
||||||
@@ -31,6 +32,9 @@ public class MovieResponse : Movie, IQueryOrderable<MovieResponse>
|
|||||||
[JsonPropertyName("rating")]
|
[JsonPropertyName("rating")]
|
||||||
public RatingResponse Rating { get; set; }
|
public RatingResponse Rating { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("genres")]
|
||||||
|
public IEnumerable<GenreResponse> Genres { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -50,7 +54,10 @@ public class MovieResponse : Movie, IQueryOrderable<MovieResponse>
|
|||||||
ReleaseDate = mediaMovie.Media.ReleaseDate;
|
ReleaseDate = mediaMovie.Media.ReleaseDate;
|
||||||
Length = mediaMovie.Media.Length;
|
Length = mediaMovie.Media.Length;
|
||||||
Budget = mediaMovie.Budget;
|
Budget = mediaMovie.Budget;
|
||||||
Rating = RatingResponse.Create(mediaMovie.Media.RatingMedia);
|
Rating = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(mediaMovie.Media.RatingMedia, x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
Genres = mediaMovie.Media.Genres.Select(x => new GenreResponse(x)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using WatchIt.Common.Query;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Persons;
|
||||||
|
|
||||||
|
public class PersonRatedQueryParameters : QueryParameters<PersonRatedResponse>
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[FromQuery(Name = "name")]
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "full_name")]
|
||||||
|
public string? FullName { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "description")]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "birth_date")]
|
||||||
|
public DateOnly? BirthDate { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "birth_date_from")]
|
||||||
|
public DateOnly? BirthDateFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "birth_date_to")]
|
||||||
|
public DateOnly? BirthDateTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "death_date")]
|
||||||
|
public DateOnly? DeathDate { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "death_date_from")]
|
||||||
|
public DateOnly? DeathDateFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "death_date_to")]
|
||||||
|
public DateOnly? DeathDateTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "gender_id")]
|
||||||
|
public short? GenderId { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_average")]
|
||||||
|
public decimal? RatingAverage { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_average_from")]
|
||||||
|
public decimal? RatingAverageFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_average_to")]
|
||||||
|
public decimal? RatingAverageTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_count")]
|
||||||
|
public long? RatingCount { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_count_from")]
|
||||||
|
public long? RatingCountFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_count_to")]
|
||||||
|
public long? RatingCountTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_average")]
|
||||||
|
public decimal? UserRatingAverage { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_average_from")]
|
||||||
|
public decimal? UserRatingAverageFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_average_to")]
|
||||||
|
public decimal? UserRatingAverageTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_count")]
|
||||||
|
public long? UserRatingCount { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_count_from")]
|
||||||
|
public long? UserRatingCountFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_count_to")]
|
||||||
|
public long? UserRatingCountTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_date")]
|
||||||
|
public DateOnly? UserRatingLastDate { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_date_from")]
|
||||||
|
public DateOnly? UserRatingLastDateFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_date_to")]
|
||||||
|
public DateOnly? UserRatingLastDateTo { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
protected override bool IsMeetingConditions(PersonRatedResponse item) =>
|
||||||
|
(
|
||||||
|
TestStringWithRegex(item.Name, Name)
|
||||||
|
&&
|
||||||
|
TestStringWithRegex(item.FullName, FullName)
|
||||||
|
&&
|
||||||
|
TestStringWithRegex(item.Description, Description)
|
||||||
|
&&
|
||||||
|
TestComparable(item.BirthDate, BirthDate, BirthDateFrom, BirthDateTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.DeathDate, DeathDate, DeathDateFrom, DeathDateTo)
|
||||||
|
&&
|
||||||
|
Test(item.Gender?.Id, GenderId)
|
||||||
|
&&
|
||||||
|
TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.UserRating.Average, UserRatingAverage, UserRatingAverageFrom, UserRatingAverageTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.UserRating.Count, UserRatingCount, UserRatingCountFrom, UserRatingCountTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.UserRatingLastDate, UserRatingLastDate, UserRatingLastDateFrom, UserRatingLastDateTo)
|
||||||
|
);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using WatchIt.Common.Model.Genders;
|
||||||
|
using WatchIt.Common.Model.Rating;
|
||||||
|
using WatchIt.Common.Query;
|
||||||
|
using WatchIt.Database.Model.Rating;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Persons;
|
||||||
|
|
||||||
|
public class PersonRatedResponse : PersonResponse, IQueryOrderable<PersonRatedResponse>
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public static IDictionary<string, Func<PersonRatedResponse, IComparable>> OrderableProperties { get; } = new Dictionary<string, Func<PersonRatedResponse, IComparable>>
|
||||||
|
{
|
||||||
|
{ "id", x => x.Id },
|
||||||
|
{ "name", x => x.Name },
|
||||||
|
{ "full_name", x => x.FullName },
|
||||||
|
{ "description", x => x.Description },
|
||||||
|
{ "birth_date", x => x.BirthDate },
|
||||||
|
{ "death_date", x => x.BirthDate },
|
||||||
|
{ "gender", x => x.Gender.Name },
|
||||||
|
{ "rating.average", x => x.Rating.Average },
|
||||||
|
{ "rating.count", x => x.Rating.Count },
|
||||||
|
{ "user_rating.average", x => x.UserRating.Average },
|
||||||
|
{ "user_rating.count", x => x.UserRating.Count },
|
||||||
|
{ "user_rating_last_date", x => x.UserRatingLastDate }
|
||||||
|
};
|
||||||
|
|
||||||
|
[JsonPropertyName("user_rating")]
|
||||||
|
public RatingResponse UserRating { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("user_rating_last_date")]
|
||||||
|
public DateTime UserRatingLastDate { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public PersonRatedResponse() { }
|
||||||
|
|
||||||
|
[SetsRequiredMembers]
|
||||||
|
public PersonRatedResponse(Database.Model.Person.Person person, IEnumerable<RatingPersonActorRole> actorUserRatings, IEnumerable<RatingPersonCreatorRole> creatorUserRatings)
|
||||||
|
{
|
||||||
|
Id = person.Id;
|
||||||
|
Name = person.Name;
|
||||||
|
FullName = person.FullName;
|
||||||
|
Description = person.Description;
|
||||||
|
BirthDate = person.BirthDate;
|
||||||
|
DeathDate = person.DeathDate;
|
||||||
|
Gender = person.Gender is not null ? new GenderResponse(person.Gender) : null;
|
||||||
|
Rating = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(person.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole), x => x.Rating)
|
||||||
|
.Add(person.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole), x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
UserRating = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(actorUserRatings, x => x.Rating)
|
||||||
|
.Add(creatorUserRatings, x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
UserRatingLastDate = actorUserRatings.Select(x => x.Date)
|
||||||
|
.Union(creatorUserRatings.Select(x => x.Date))
|
||||||
|
.Max();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ using System.Text.Json.Serialization;
|
|||||||
using WatchIt.Common.Model.Genders;
|
using WatchIt.Common.Model.Genders;
|
||||||
using WatchIt.Common.Model.Rating;
|
using WatchIt.Common.Model.Rating;
|
||||||
using WatchIt.Common.Query;
|
using WatchIt.Common.Query;
|
||||||
|
using WatchIt.Database.Model.Rating;
|
||||||
|
|
||||||
namespace WatchIt.Common.Model.Persons;
|
namespace WatchIt.Common.Model.Persons;
|
||||||
|
|
||||||
@@ -53,7 +54,10 @@ public class PersonResponse : Person, IQueryOrderable<PersonResponse>
|
|||||||
BirthDate = person.BirthDate;
|
BirthDate = person.BirthDate;
|
||||||
DeathDate = person.DeathDate;
|
DeathDate = person.DeathDate;
|
||||||
Gender = person.Gender is not null ? new GenderResponse(person.Gender) : null;
|
Gender = person.Gender is not null ? new GenderResponse(person.Gender) : null;
|
||||||
Rating = RatingResponse.Create(person.PersonActorRoles, person.PersonCreatorRoles);
|
Rating = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(person.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole), x => x.Rating)
|
||||||
|
.Add(person.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole), x => x.Rating)
|
||||||
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -25,35 +25,11 @@ public class RatingResponse
|
|||||||
public RatingResponse() {}
|
public RatingResponse() {}
|
||||||
|
|
||||||
[SetsRequiredMembers]
|
[SetsRequiredMembers]
|
||||||
private RatingResponse(long ratingSum, long ratingCount)
|
internal RatingResponse(long ratingSum, long ratingCount)
|
||||||
{
|
{
|
||||||
Average = ratingCount > 0 ? (decimal)ratingSum / ratingCount : 0;
|
Average = ratingCount > 0 ? (decimal)ratingSum / ratingCount : 0;
|
||||||
Count = ratingCount;
|
Count = ratingCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RatingResponse Create(long ratingSum, long ratingCount) => new RatingResponse(ratingSum, ratingCount);
|
|
||||||
|
|
||||||
public static RatingResponse Create(IEnumerable<RatingMedia> ratingMedia) => Create(ratingMedia, x => x.Rating);
|
|
||||||
|
|
||||||
public static RatingResponse Create(IEnumerable<RatingPersonActorRole> ratingPersonActorRoles) => Create(ratingPersonActorRoles, x => x.Rating);
|
|
||||||
|
|
||||||
public static RatingResponse Create(IEnumerable<RatingPersonCreatorRole> ratingPersonCreatorRoles) => Create(ratingPersonCreatorRoles, x => x.Rating);
|
|
||||||
|
|
||||||
public static RatingResponse Create<T>(IEnumerable<T> ratingList, Func<T, short> ratingSelector) => new RatingResponse(ratingList.Sum(x => ratingSelector(x)), ratingList.Count());
|
|
||||||
|
|
||||||
public static RatingResponse Create(IEnumerable<PersonActorRole> personActorRoles, IEnumerable<PersonCreatorRole> personCreatorRoles)
|
|
||||||
{
|
|
||||||
IEnumerable<RatingPersonActorRole> ratingsActorRoles = personActorRoles.SelectMany(x => x.RatingPersonActorRole);
|
|
||||||
IEnumerable<RatingPersonCreatorRole> ratingsCreatorRoles = personCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole);
|
|
||||||
return Create(ratingsActorRoles, ratingsCreatorRoles);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RatingResponse Create(IEnumerable<RatingPersonActorRole> ratingsActorRoles, IEnumerable<RatingPersonCreatorRole> ratingsCreatorRoles)
|
|
||||||
{
|
|
||||||
long ratingSum = ratingsActorRoles.Sum(x => x.Rating) + ratingsCreatorRoles.Sum(x => x.Rating);
|
|
||||||
long ratingCount = ratingsActorRoles.Count() + ratingsCreatorRoles.Count();
|
|
||||||
return new RatingResponse(ratingSum, ratingCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
namespace WatchIt.Common.Model.Rating;
|
||||||
|
|
||||||
|
public class RatingResponseBuilder
|
||||||
|
{
|
||||||
|
#region FIELDS
|
||||||
|
|
||||||
|
private long _sum;
|
||||||
|
private long _count;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
private RatingResponseBuilder() { }
|
||||||
|
|
||||||
|
public static RatingResponseBuilder Initialize() => new RatingResponseBuilder();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public RatingResponseBuilder Add<T>(IEnumerable<T> collection, Func<T, short> selector)
|
||||||
|
{
|
||||||
|
_sum += collection.Sum(x => selector(x));
|
||||||
|
_count += collection.Count();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public RatingResponse Build() => new RatingResponse(_sum, _count);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -55,6 +55,9 @@ public class SeriesQueryParameters : QueryParameters<SeriesResponse>
|
|||||||
[FromQuery(Name = "rating_count_to")]
|
[FromQuery(Name = "rating_count_to")]
|
||||||
public long? RatingCountTo { get; set; }
|
public long? RatingCountTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "genre")]
|
||||||
|
public IEnumerable<short>? Genres { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -78,6 +81,8 @@ public class SeriesQueryParameters : QueryParameters<SeriesResponse>
|
|||||||
TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo)
|
TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo)
|
||||||
&&
|
&&
|
||||||
TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo)
|
TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo)
|
||||||
|
&&
|
||||||
|
TestContains(item.Genres.Select(x => x.Id), Genres)
|
||||||
);
|
);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using WatchIt.Common.Query;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Series;
|
||||||
|
|
||||||
|
public class SeriesRatedQueryParameters : QueryParameters<SeriesRatedResponse>
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[FromQuery(Name = "title")]
|
||||||
|
public string? Title { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "original_title")]
|
||||||
|
public string? OriginalTitle { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "description")]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "release_date")]
|
||||||
|
public DateOnly? ReleaseDate { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "release_date_from")]
|
||||||
|
public DateOnly? ReleaseDateFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "release_date_to")]
|
||||||
|
public DateOnly? ReleaseDateTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "length")]
|
||||||
|
public short? Length { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "length_from")]
|
||||||
|
public short? LengthFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "length_to")]
|
||||||
|
public short? LengthTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "has_ended")]
|
||||||
|
public bool? HasEnded { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_average")]
|
||||||
|
public decimal? RatingAverage { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_average_from")]
|
||||||
|
public decimal? RatingAverageFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_average_to")]
|
||||||
|
public decimal? RatingAverageTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_count")]
|
||||||
|
public long? RatingCount { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_count_from")]
|
||||||
|
public long? RatingCountFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "rating_count_to")]
|
||||||
|
public long? RatingCountTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "genre")]
|
||||||
|
public IEnumerable<short>? Genres { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating")]
|
||||||
|
public decimal? UserRating { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_from")]
|
||||||
|
public decimal? UserRatingFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_to")]
|
||||||
|
public decimal? UserRatingTo { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_date")]
|
||||||
|
public DateOnly? UserRatingDate { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_date_from")]
|
||||||
|
public DateOnly? UserRatingDateFrom { get; set; }
|
||||||
|
|
||||||
|
[FromQuery(Name = "user_rating_date_to")]
|
||||||
|
public DateOnly? UserRatingDateTo { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
protected override bool IsMeetingConditions(SeriesRatedResponse item) =>
|
||||||
|
(
|
||||||
|
TestStringWithRegex(item.Title, Title)
|
||||||
|
&&
|
||||||
|
TestStringWithRegex(item.OriginalTitle, OriginalTitle)
|
||||||
|
&&
|
||||||
|
TestStringWithRegex(item.Description, Description)
|
||||||
|
&&
|
||||||
|
TestComparable(item.ReleaseDate, ReleaseDate, ReleaseDateFrom, ReleaseDateTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.Length, Length, LengthFrom, LengthTo)
|
||||||
|
&&
|
||||||
|
Test(item.HasEnded, HasEnded)
|
||||||
|
&&
|
||||||
|
TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo)
|
||||||
|
&&
|
||||||
|
TestContains(item.Genres.Select(x => x.Id), Genres)
|
||||||
|
&&
|
||||||
|
TestComparable((decimal)item.UserRating, UserRating, UserRatingFrom, UserRatingTo)
|
||||||
|
&&
|
||||||
|
TestComparable(item.UserRatingDate, UserRatingDate, UserRatingDateFrom, UserRatingDateTo)
|
||||||
|
);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using WatchIt.Common.Model.Genres;
|
||||||
|
using WatchIt.Common.Model.Rating;
|
||||||
|
using WatchIt.Common.Query;
|
||||||
|
using WatchIt.Database.Model.Media;
|
||||||
|
using WatchIt.Database.Model.Rating;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Series;
|
||||||
|
|
||||||
|
public class SeriesRatedResponse : SeriesResponse, IQueryOrderable<SeriesRatedResponse>
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public static IDictionary<string, Func<SeriesRatedResponse, IComparable>> OrderableProperties { get; } = new Dictionary<string, Func<SeriesRatedResponse, IComparable>>
|
||||||
|
{
|
||||||
|
{ "id", x => x.Id },
|
||||||
|
{ "title", x => x.Title },
|
||||||
|
{ "original_title", x => x.OriginalTitle },
|
||||||
|
{ "description", x => x.Description },
|
||||||
|
{ "release_date", x => x.ReleaseDate },
|
||||||
|
{ "length", x => x.Length },
|
||||||
|
{ "has_ended", x => x.HasEnded },
|
||||||
|
{ "rating.average", x => x.Rating.Average },
|
||||||
|
{ "rating.count", x => x.Rating.Count },
|
||||||
|
{ "user_rating", x => x.UserRating },
|
||||||
|
{ "user_rating_date", x => x.UserRatingDate }
|
||||||
|
};
|
||||||
|
|
||||||
|
[JsonPropertyName("user_rating")]
|
||||||
|
public short UserRating { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("user_rating_date")]
|
||||||
|
public DateTime UserRatingDate { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public SeriesRatedResponse() { }
|
||||||
|
|
||||||
|
[SetsRequiredMembers]
|
||||||
|
public SeriesRatedResponse(MediaSeries mediaSeries, RatingMedia response)
|
||||||
|
{
|
||||||
|
Id = mediaSeries.Media.Id;
|
||||||
|
Title = mediaSeries.Media.Title;
|
||||||
|
OriginalTitle = mediaSeries.Media.OriginalTitle;
|
||||||
|
Description = mediaSeries.Media.Description;
|
||||||
|
ReleaseDate = mediaSeries.Media.ReleaseDate;
|
||||||
|
Length = mediaSeries.Media.Length;
|
||||||
|
HasEnded = mediaSeries.HasEnded;
|
||||||
|
Rating = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(mediaSeries.Media.RatingMedia, x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
Genres = mediaSeries.Media.Genres.Select(x => new GenreResponse(x)).ToList();
|
||||||
|
UserRating = response.Rating;
|
||||||
|
UserRatingDate = response.Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using WatchIt.Common.Model.Genres;
|
||||||
using WatchIt.Common.Model.Rating;
|
using WatchIt.Common.Model.Rating;
|
||||||
using WatchIt.Common.Query;
|
using WatchIt.Common.Query;
|
||||||
using WatchIt.Database.Model.Media;
|
using WatchIt.Database.Model.Media;
|
||||||
@@ -31,6 +32,9 @@ public class SeriesResponse : Series, IQueryOrderable<SeriesResponse>
|
|||||||
[JsonPropertyName("rating")]
|
[JsonPropertyName("rating")]
|
||||||
public RatingResponse Rating { get; set; }
|
public RatingResponse Rating { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("genres")]
|
||||||
|
public IEnumerable<GenreResponse> Genres { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -50,7 +54,10 @@ public class SeriesResponse : Series, IQueryOrderable<SeriesResponse>
|
|||||||
ReleaseDate = mediaSeries.Media.ReleaseDate;
|
ReleaseDate = mediaSeries.Media.ReleaseDate;
|
||||||
Length = mediaSeries.Media.Length;
|
Length = mediaSeries.Media.Length;
|
||||||
HasEnded = mediaSeries.HasEnded;
|
HasEnded = mediaSeries.HasEnded;
|
||||||
Rating = RatingResponse.Create(mediaSeries.Media.RatingMedia);
|
Rating = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(mediaSeries.Media.RatingMedia, x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
Genres = mediaSeries.Media.Genres.Select(x => new GenreResponse(x)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Globalization;
|
using System.Collections;
|
||||||
|
using System.Globalization;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
@@ -39,13 +40,16 @@ public abstract class QueryParameters
|
|||||||
FromQueryAttribute? attribute = property.GetCustomAttributes<FromQueryAttribute>(true).FirstOrDefault();
|
FromQueryAttribute? attribute = property.GetCustomAttributes<FromQueryAttribute>(true).FirstOrDefault();
|
||||||
if (value is not null && attribute is not null)
|
if (value is not null && attribute is not null)
|
||||||
{
|
{
|
||||||
string valueString = (value switch
|
if (value is IEnumerable enumerable and not string)
|
||||||
{
|
{
|
||||||
decimal d => d.ToString(CultureInfo.InvariantCulture),
|
IEnumerable<string> arrayQueryElements = enumerable.Cast<object>().Select(x => QueryElementToString(attribute.Name!, x.ToString()));
|
||||||
_ => value.ToString()
|
queries.AddRange(arrayQueryElements);
|
||||||
})!;
|
}
|
||||||
string query = $"{attribute.Name}={valueString}";
|
else
|
||||||
queries.Add(query);
|
{
|
||||||
|
string query = QueryElementToString(attribute.Name!, value);
|
||||||
|
queries.Add(query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +62,18 @@ public abstract class QueryParameters
|
|||||||
|
|
||||||
#region PRIVATE METHODS
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
private string QueryElementToString(string name, object value)
|
||||||
|
{
|
||||||
|
string valueString = (value switch
|
||||||
|
{
|
||||||
|
decimal d => d.ToString(CultureInfo.InvariantCulture),
|
||||||
|
_ => value.ToString()
|
||||||
|
})!;
|
||||||
|
string query = $"{name}={valueString}";
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected static bool Test<T>(T? property, T? query) =>
|
protected static bool Test<T>(T? property, T? query) =>
|
||||||
(
|
(
|
||||||
query is null
|
query is null
|
||||||
@@ -113,6 +129,15 @@ public abstract class QueryParameters
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
protected static bool TestContains<T>(IEnumerable<T>? shouldBeInCollection, IEnumerable<T>? collection) =>
|
||||||
|
(
|
||||||
|
collection is null
|
||||||
|
||
|
||||||
|
shouldBeInCollection is null
|
||||||
|
||
|
||||||
|
shouldBeInCollection.All(collection.Contains)
|
||||||
|
);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,5 +30,9 @@ public class RatingMediaConfiguration : IEntityTypeConfiguration<RatingMedia>
|
|||||||
|
|
||||||
builder.Property(x => x.Rating)
|
builder.Property(x => x.Rating)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
builder.Property(x => x.Date)
|
||||||
|
.IsRequired()
|
||||||
|
.HasDefaultValueSql("now()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,5 +30,9 @@ public class RatingMediaSeriesEpisodeConfiguration : IEntityTypeConfiguration<Ra
|
|||||||
|
|
||||||
builder.Property(x => x.Rating)
|
builder.Property(x => x.Rating)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
builder.Property(x => x.Date)
|
||||||
|
.IsRequired()
|
||||||
|
.HasDefaultValueSql("now()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,5 +30,9 @@ public class RatingMediaSeriesSeasonConfiguration : IEntityTypeConfiguration<Rat
|
|||||||
|
|
||||||
builder.Property(x => x.Rating)
|
builder.Property(x => x.Rating)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
builder.Property(x => x.Date)
|
||||||
|
.IsRequired()
|
||||||
|
.HasDefaultValueSql("now()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,5 +32,9 @@ public class RatingPersonActorRoleConfiguration : IEntityTypeConfiguration<Ratin
|
|||||||
|
|
||||||
builder.Property(x => x.Rating)
|
builder.Property(x => x.Rating)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
builder.Property(x => x.Date)
|
||||||
|
.IsRequired()
|
||||||
|
.HasDefaultValueSql("now()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,5 +32,9 @@ public class RatingPersonCreatorRoleConfiguration : IEntityTypeConfiguration<Rat
|
|||||||
|
|
||||||
builder.Property(x => x.Rating)
|
builder.Property(x => x.Rating)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
builder.Property(x => x.Date)
|
||||||
|
.IsRequired()
|
||||||
|
.HasDefaultValueSql("now()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,9 +15,9 @@ public class Account
|
|||||||
public short? GenderId { get; set; }
|
public short? GenderId { get; set; }
|
||||||
public Guid? ProfilePictureId { get; set; }
|
public Guid? ProfilePictureId { get; set; }
|
||||||
public Guid? BackgroundPictureId { get; set; }
|
public Guid? BackgroundPictureId { get; set; }
|
||||||
public required byte[] Password { get; set; }
|
public byte[] Password { get; set; }
|
||||||
public required string LeftSalt { get; set; }
|
public string LeftSalt { get; set; }
|
||||||
public required string RightSalt { get; set; }
|
public string RightSalt { get; set; }
|
||||||
public bool IsAdmin { get; set; } = false;
|
public bool IsAdmin { get; set; } = false;
|
||||||
public DateTime CreationDate { get; set; }
|
public DateTime CreationDate { get; set; }
|
||||||
public DateTime LastActive { get; set; }
|
public DateTime LastActive { get; set; }
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public class RatingMedia
|
|||||||
public required long MediaId { get; set; }
|
public required long MediaId { get; set; }
|
||||||
public required long AccountId { get; set; }
|
public required long AccountId { get; set; }
|
||||||
public required short Rating { get; set; }
|
public required short Rating { get; set; }
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public class RatingMediaSeriesEpisode
|
|||||||
public required Guid MediaSeriesEpisodeId { get; set; }
|
public required Guid MediaSeriesEpisodeId { get; set; }
|
||||||
public required long AccountId { get; set; }
|
public required long AccountId { get; set; }
|
||||||
public required short Rating { get; set; }
|
public required short Rating { get; set; }
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public class RatingMediaSeriesSeason
|
|||||||
public required Guid MediaSeriesSeasonId { get; set; }
|
public required Guid MediaSeriesSeasonId { get; set; }
|
||||||
public required long AccountId { get; set; }
|
public required long AccountId { get; set; }
|
||||||
public required short Rating { get; set; }
|
public required short Rating { get; set; }
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public class RatingPersonActorRole
|
|||||||
public required Guid PersonActorRoleId { get; set; }
|
public required Guid PersonActorRoleId { get; set; }
|
||||||
public required long AccountId { get; set; }
|
public required long AccountId { get; set; }
|
||||||
public required short Rating { get; set; }
|
public required short Rating { get; set; }
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public class RatingPersonCreatorRole
|
|||||||
public required Guid PersonCreatorRoleId { get; set; }
|
public required Guid PersonCreatorRoleId { get; set; }
|
||||||
public required long AccountId { get; set; }
|
public required long AccountId { get; set; }
|
||||||
public required short Rating { get; set; }
|
public required short Rating { get; set; }
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
1416
WatchIt.Database/WatchIt.Database/Migrations/20241102132802_RatingDate.Designer.cs
generated
Normal file
1416
WatchIt.Database/WatchIt.Database/Migrations/20241102132802_RatingDate.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,92 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace WatchIt.Database.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class RatingDate : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "Date",
|
||||||
|
table: "RatingsPersonCreatorRole",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: false,
|
||||||
|
defaultValueSql: "now()");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "Date",
|
||||||
|
table: "RatingsPersonActorRole",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: false,
|
||||||
|
defaultValueSql: "now()");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "Date",
|
||||||
|
table: "RatingsMediaSeriesSeason",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: false,
|
||||||
|
defaultValueSql: "now()");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "Date",
|
||||||
|
table: "RatingsMediaSeriesEpisode",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: false,
|
||||||
|
defaultValueSql: "now()");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "Date",
|
||||||
|
table: "RatingsMedia",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: false,
|
||||||
|
defaultValueSql: "now()");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "RoleName",
|
||||||
|
table: "PersonActorRoles",
|
||||||
|
type: "character varying(100)",
|
||||||
|
maxLength: 100,
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "text");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Date",
|
||||||
|
table: "RatingsPersonCreatorRole");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Date",
|
||||||
|
table: "RatingsPersonActorRole");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Date",
|
||||||
|
table: "RatingsMediaSeriesSeason");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Date",
|
||||||
|
table: "RatingsMediaSeriesEpisode");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Date",
|
||||||
|
table: "RatingsMedia");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "RoleName",
|
||||||
|
table: "PersonActorRoles",
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "character varying(100)",
|
||||||
|
oldMaxLength: 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -108,9 +108,9 @@ namespace WatchIt.Database.Migrations
|
|||||||
Email = "root@watch.it",
|
Email = "root@watch.it",
|
||||||
IsAdmin = true,
|
IsAdmin = true,
|
||||||
LastActive = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
LastActive = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
LeftSalt = "@(0PF{b6Ot?HO*:yF5`L",
|
LeftSalt = "YuJiv1\"R'*0odl8${\\|S",
|
||||||
Password = new byte[] { 254, 122, 19, 59, 187, 100, 174, 87, 55, 108, 14, 10, 123, 186, 129, 243, 145, 136, 152, 220, 72, 170, 196, 93, 54, 88, 192, 115, 128, 76, 133, 9, 181, 99, 181, 8, 102, 123, 197, 251, 85, 167, 146, 28, 116, 249, 118, 87, 146, 8, 194, 238, 127, 19, 33, 28, 14, 222, 218, 170, 74, 40, 223, 232 },
|
Password = new byte[] { 215, 154, 186, 191, 12, 223, 76, 105, 137, 67, 41, 138, 26, 3, 38, 36, 0, 71, 40, 84, 153, 152, 105, 239, 55, 60, 164, 15, 99, 175, 133, 175, 227, 245, 102, 9, 171, 119, 16, 234, 97, 179, 70, 29, 120, 112, 241, 91, 209, 91, 228, 164, 52, 244, 36, 207, 147, 60, 124, 66, 77, 252, 129, 151 },
|
||||||
RightSalt = "=pt,3T0#CfC1[}Zfp{/u",
|
RightSalt = "oT2N=y7^5,2o'+N>d}~!",
|
||||||
Username = "root"
|
Username = "root"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -607,7 +607,8 @@ namespace WatchIt.Database.Migrations
|
|||||||
|
|
||||||
b.Property<string>("RoleName")
|
b.Property<string>("RoleName")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("text");
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -766,6 +767,11 @@ namespace WatchIt.Database.Migrations
|
|||||||
b.Property<long>("AccountId")
|
b.Property<long>("AccountId")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasDefaultValueSql("now()");
|
||||||
|
|
||||||
b.Property<long>("MediaId")
|
b.Property<long>("MediaId")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
@@ -793,6 +799,11 @@ namespace WatchIt.Database.Migrations
|
|||||||
b.Property<long>("AccountId")
|
b.Property<long>("AccountId")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasDefaultValueSql("now()");
|
||||||
|
|
||||||
b.Property<Guid>("MediaSeriesEpisodeId")
|
b.Property<Guid>("MediaSeriesEpisodeId")
|
||||||
.HasColumnType("uuid");
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
@@ -820,6 +831,11 @@ namespace WatchIt.Database.Migrations
|
|||||||
b.Property<long>("AccountId")
|
b.Property<long>("AccountId")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasDefaultValueSql("now()");
|
||||||
|
|
||||||
b.Property<Guid>("MediaSeriesSeasonId")
|
b.Property<Guid>("MediaSeriesSeasonId")
|
||||||
.HasColumnType("uuid");
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
@@ -847,6 +863,11 @@ namespace WatchIt.Database.Migrations
|
|||||||
b.Property<long>("AccountId")
|
b.Property<long>("AccountId")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasDefaultValueSql("now()");
|
||||||
|
|
||||||
b.Property<Guid>("PersonActorRoleId")
|
b.Property<Guid>("PersonActorRoleId")
|
||||||
.HasColumnType("uuid");
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
@@ -874,6 +895,11 @@ namespace WatchIt.Database.Migrations
|
|||||||
b.Property<long>("AccountId")
|
b.Property<long>("AccountId")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasDefaultValueSql("now()");
|
||||||
|
|
||||||
b.Property<Guid>("PersonCreatorRoleId")
|
b.Property<Guid>("PersonCreatorRoleId")
|
||||||
.HasColumnType("uuid");
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using WatchIt.Common.Model.Accounts;
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Common.Model.Movies;
|
||||||
|
using WatchIt.Common.Model.Persons;
|
||||||
|
using WatchIt.Common.Model.Photos;
|
||||||
|
using WatchIt.Common.Model.Series;
|
||||||
using WatchIt.WebAPI.Services.Controllers.Accounts;
|
using WatchIt.WebAPI.Services.Controllers.Accounts;
|
||||||
|
|
||||||
namespace WatchIt.WebAPI.Controllers;
|
namespace WatchIt.WebAPI.Controllers;
|
||||||
@@ -10,6 +15,8 @@ namespace WatchIt.WebAPI.Controllers;
|
|||||||
[Route("accounts")]
|
[Route("accounts")]
|
||||||
public class AccountsController(IAccountsControllerService accountsControllerService) : ControllerBase
|
public class AccountsController(IAccountsControllerService accountsControllerService) : ControllerBase
|
||||||
{
|
{
|
||||||
|
#region Basic
|
||||||
|
|
||||||
[HttpPost("register")]
|
[HttpPost("register")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[ProducesResponseType(typeof(RegisterResponse), StatusCodes.Status201Created)]
|
[ProducesResponseType(typeof(RegisterResponse), StatusCodes.Status201Created)]
|
||||||
@@ -23,7 +30,7 @@ public class AccountsController(IAccountsControllerService accountsControllerSer
|
|||||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
public async Task<ActionResult> Authenticate([FromBody]AuthenticateRequest body) => await accountsControllerService.Authenticate(body);
|
public async Task<ActionResult> Authenticate([FromBody]AuthenticateRequest body) => await accountsControllerService.Authenticate(body);
|
||||||
|
|
||||||
[HttpPost("authenticate-refresh")]
|
[HttpPost("authenticate_refresh")]
|
||||||
[Authorize(AuthenticationSchemes = "refresh")]
|
[Authorize(AuthenticationSchemes = "refresh")]
|
||||||
[ProducesResponseType(typeof(AuthenticateResponse), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(AuthenticateResponse), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
@@ -35,10 +42,114 @@ public class AccountsController(IAccountsControllerService accountsControllerSer
|
|||||||
[ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)]
|
[ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)]
|
||||||
public async Task<ActionResult> Logout() => await accountsControllerService.Logout();
|
public async Task<ActionResult> Logout() => await accountsControllerService.Logout();
|
||||||
|
|
||||||
[HttpGet("{id}/profile-picture")]
|
#endregion
|
||||||
|
|
||||||
|
#region Profile picture
|
||||||
|
|
||||||
|
[HttpGet("{id}/profile_picture")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[ProducesResponseType(typeof(AccountProfilePictureResponse), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(AccountProfilePictureResponse), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<ActionResult> GetAccountProfilePicture([FromRoute(Name = "id")]long id) => await accountsControllerService.GetAccountProfilePicture(id);
|
public async Task<ActionResult> GetAccountProfilePicture([FromRoute(Name = "id")]long id) => await accountsControllerService.GetAccountProfilePicture(id);
|
||||||
|
|
||||||
|
[HttpPut("profile_picture")]
|
||||||
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
|
[ProducesResponseType(typeof(AccountProfilePictureResponse), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
public async Task<ActionResult> PutAccountProfilePicture([FromBody]AccountProfilePictureRequest body) => await accountsControllerService.PutAccountProfilePicture(body);
|
||||||
|
|
||||||
|
[HttpDelete("profile_picture")]
|
||||||
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
public async Task<ActionResult> DeleteAccountProfilePicture() => await accountsControllerService.DeleteAccountProfilePicture();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Profile background
|
||||||
|
|
||||||
|
[HttpGet("{id}/profile_background")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[ProducesResponseType(typeof(PhotoResponse), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult> GetAccountProfileBackground([FromRoute(Name = "id")]long id) => await accountsControllerService.GetAccountProfileBackground(id);
|
||||||
|
|
||||||
|
[HttpPut("profile_background")]
|
||||||
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
|
[ProducesResponseType(typeof(PhotoResponse), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
public async Task<ActionResult> PutAccountProfileBackground([FromBody]AccountProfileBackgroundRequest body) => await accountsControllerService.PutAccountProfileBackground(body);
|
||||||
|
|
||||||
|
[HttpDelete("profile_background")]
|
||||||
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
public async Task<ActionResult> DeleteAccountProfileBackground() => await accountsControllerService.DeleteAccountProfileBackground();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Info
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<AccountResponse>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<ActionResult> GetAccounts(AccountQueryParameters query) => await accountsControllerService.GetAccounts(query);
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[ProducesResponseType(typeof(AccountResponse), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult> GetAccount([FromRoute]long id) => await accountsControllerService.GetAccount(id);
|
||||||
|
|
||||||
|
[HttpPut("profile_info")]
|
||||||
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult> PutAccountProfileInfo([FromBody]AccountProfileInfoRequest data) => await accountsControllerService.PutAccountProfileInfo(data);
|
||||||
|
|
||||||
|
[HttpPatch("username")]
|
||||||
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
|
public async Task<ActionResult> PatchAccountUsername([FromBody]AccountUsernameRequest data) => await accountsControllerService.PatchAccountUsername(data);
|
||||||
|
|
||||||
|
[HttpPatch("email")]
|
||||||
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
|
public async Task<ActionResult> PatchAccountEmail([FromBody]AccountEmailRequest data) => await accountsControllerService.PatchAccountEmail(data);
|
||||||
|
|
||||||
|
[HttpPatch("password")]
|
||||||
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
|
public async Task<ActionResult> PatchAccountPassword([FromBody]AccountPasswordRequest data) => await accountsControllerService.PatchAccountPassword(data);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[HttpGet("{id}/movies")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<MovieRatedResponse>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult> GetAccountRatedMovies([FromRoute]long id, MovieRatedQueryParameters query) => await accountsControllerService.GetAccountRatedMovies(id, query);
|
||||||
|
|
||||||
|
[HttpGet("{id}/series")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<SeriesRatedResponse>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult> GetAccountRatedSeries([FromRoute]long id, SeriesRatedQueryParameters query) => await accountsControllerService.GetAccountRatedSeries(id, query);
|
||||||
|
|
||||||
|
[HttpGet("{id}/persons")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PersonRatedResponse>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult> GetAccountRatedPersons([FromRoute]long id, PersonRatedQueryParameters query) => await accountsControllerService.GetAccountRatedPersons(id, query);
|
||||||
}
|
}
|
||||||
@@ -5,13 +5,22 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using SimpleToolkit.Extensions;
|
using SimpleToolkit.Extensions;
|
||||||
using WatchIt.Common.Model.Accounts;
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Common.Model.Media;
|
||||||
|
using WatchIt.Common.Model.Movies;
|
||||||
|
using WatchIt.Common.Model.Persons;
|
||||||
|
using WatchIt.Common.Model.Photos;
|
||||||
|
using WatchIt.Common.Model.Series;
|
||||||
using WatchIt.Database;
|
using WatchIt.Database;
|
||||||
using WatchIt.Database.Model.Account;
|
using WatchIt.Database.Model.Account;
|
||||||
|
using WatchIt.Database.Model.Media;
|
||||||
|
using WatchIt.Database.Model.Rating;
|
||||||
using WatchIt.WebAPI.Services.Controllers.Common;
|
using WatchIt.WebAPI.Services.Controllers.Common;
|
||||||
using WatchIt.WebAPI.Services.Utility.Tokens;
|
using WatchIt.WebAPI.Services.Utility.Tokens;
|
||||||
using WatchIt.WebAPI.Services.Utility.Tokens.Exceptions;
|
using WatchIt.WebAPI.Services.Utility.Tokens.Exceptions;
|
||||||
using WatchIt.WebAPI.Services.Utility.User;
|
using WatchIt.WebAPI.Services.Utility.User;
|
||||||
|
using Account = WatchIt.Database.Model.Account.Account;
|
||||||
using AccountProfilePicture = WatchIt.Common.Model.Accounts.AccountProfilePicture;
|
using AccountProfilePicture = WatchIt.Common.Model.Accounts.AccountProfilePicture;
|
||||||
|
using Person = WatchIt.Database.Model.Person.Person;
|
||||||
|
|
||||||
namespace WatchIt.WebAPI.Services.Controllers.Accounts;
|
namespace WatchIt.WebAPI.Services.Controllers.Accounts;
|
||||||
|
|
||||||
@@ -24,20 +33,17 @@ public class AccountsControllerService(
|
|||||||
{
|
{
|
||||||
#region PUBLIC METHODS
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
#region Basic
|
||||||
|
|
||||||
public async Task<RequestResult> Register(RegisterRequest data)
|
public async Task<RequestResult> Register(RegisterRequest data)
|
||||||
{
|
{
|
||||||
string leftSalt = StringExtensions.CreateRandom(20);
|
|
||||||
string rightSalt = StringExtensions.CreateRandom(20);
|
|
||||||
byte[] hash = ComputeHash(data.Password, leftSalt, rightSalt);
|
|
||||||
|
|
||||||
Account account = new Account
|
Account account = new Account
|
||||||
{
|
{
|
||||||
Username = data.Username,
|
Username = data.Username,
|
||||||
Email = data.Email,
|
Email = data.Email,
|
||||||
Password = hash,
|
|
||||||
LeftSalt = leftSalt,
|
|
||||||
RightSalt = rightSalt,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SetPassword(account, data.Password);
|
||||||
await database.Accounts.AddAsync(account);
|
await database.Accounts.AddAsync(account);
|
||||||
await database.SaveChangesAsync();
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
@@ -61,6 +67,9 @@ public class AccountsControllerService(
|
|||||||
RefreshToken = await refreshTokenTask,
|
RefreshToken = await refreshTokenTask,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
account.LastActive = DateTime.UtcNow;
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
logger.LogInformation($"Account with ID {account.Id} was authenticated");
|
logger.LogInformation($"Account with ID {account.Id} was authenticated");
|
||||||
return RequestResult.Ok(response);
|
return RequestResult.Ok(response);
|
||||||
}
|
}
|
||||||
@@ -90,6 +99,9 @@ public class AccountsControllerService(
|
|||||||
|
|
||||||
string accessToken = await tokensService.CreateAccessTokenAsync(token.Account);
|
string accessToken = await tokensService.CreateAccessTokenAsync(token.Account);
|
||||||
|
|
||||||
|
token.Account.LastActive = DateTime.UtcNow;
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
logger.LogInformation($"Account with ID {token.AccountId} was authenticated by token refreshing");
|
logger.LogInformation($"Account with ID {token.AccountId} was authenticated by token refreshing");
|
||||||
return RequestResult.Ok(new AuthenticateResponse
|
return RequestResult.Ok(new AuthenticateResponse
|
||||||
{
|
{
|
||||||
@@ -111,6 +123,10 @@ public class AccountsControllerService(
|
|||||||
return RequestResult.NoContent();
|
return RequestResult.NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Profile picture
|
||||||
|
|
||||||
public async Task<RequestResult> GetAccountProfilePicture(long id)
|
public async Task<RequestResult> GetAccountProfilePicture(long id)
|
||||||
{
|
{
|
||||||
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
@@ -129,6 +145,224 @@ public class AccountsControllerService(
|
|||||||
return RequestResult.Ok(picture);
|
return RequestResult.Ok(picture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> PutAccountProfilePicture(AccountProfilePictureRequest data)
|
||||||
|
{
|
||||||
|
Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId());
|
||||||
|
Database.Model.Account.AccountProfilePicture? picture = account.ProfilePicture;
|
||||||
|
|
||||||
|
if (picture is null)
|
||||||
|
{
|
||||||
|
picture = data.CreateMediaPosterImage();
|
||||||
|
await database.AccountProfilePictures.AddAsync(picture);
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
|
account.ProfilePictureId = picture.Id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.UpdateMediaPosterImage(picture);
|
||||||
|
}
|
||||||
|
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
|
AccountProfilePictureResponse returnData = new AccountProfilePictureResponse(picture);
|
||||||
|
return RequestResult.Ok(returnData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> DeleteAccountProfilePicture()
|
||||||
|
{
|
||||||
|
Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId());
|
||||||
|
Database.Model.Account.AccountProfilePicture? picture = account.ProfilePicture;
|
||||||
|
|
||||||
|
if (picture is not null)
|
||||||
|
{
|
||||||
|
account.ProfilePictureId = null;
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
|
database.AccountProfilePictures.Attach(picture);
|
||||||
|
database.AccountProfilePictures.Remove(picture);
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
return RequestResult.NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Profile background
|
||||||
|
|
||||||
|
public async Task<RequestResult> GetAccountProfileBackground(long id)
|
||||||
|
{
|
||||||
|
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
|
if (account is null)
|
||||||
|
{
|
||||||
|
return RequestResult.BadRequest()
|
||||||
|
.AddValidationError("id", "Account with this id does not exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account.BackgroundPicture is null)
|
||||||
|
{
|
||||||
|
return RequestResult.NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
PhotoResponse response = new PhotoResponse(account.BackgroundPicture);
|
||||||
|
return RequestResult.Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> PutAccountProfileBackground(AccountProfileBackgroundRequest data)
|
||||||
|
{
|
||||||
|
Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId());
|
||||||
|
|
||||||
|
account.BackgroundPictureId = data.Id;
|
||||||
|
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
|
PhotoResponse returnData = new PhotoResponse(account.BackgroundPicture!);
|
||||||
|
return RequestResult.Ok(returnData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> DeleteAccountProfileBackground()
|
||||||
|
{
|
||||||
|
Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId());
|
||||||
|
|
||||||
|
if (account.BackgroundPicture is not null)
|
||||||
|
{
|
||||||
|
account.BackgroundPictureId = null;
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
return RequestResult.NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Info
|
||||||
|
|
||||||
|
public async Task<RequestResult> GetAccounts(AccountQueryParameters query)
|
||||||
|
{
|
||||||
|
IEnumerable<Account> accounts = await database.Accounts.ToListAsync();
|
||||||
|
IEnumerable<AccountResponse> accountsData = accounts.Select(x => new AccountResponse(x));
|
||||||
|
accountsData = query.PrepareData(accountsData);
|
||||||
|
return RequestResult.Ok(accountsData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> GetAccount(long id)
|
||||||
|
{
|
||||||
|
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
|
if (account is null)
|
||||||
|
{
|
||||||
|
return RequestResult.NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountResponse profileInfoResponse = new AccountResponse(account);
|
||||||
|
return RequestResult.Ok(profileInfoResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> PutAccountProfileInfo(AccountProfileInfoRequest data)
|
||||||
|
{
|
||||||
|
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == userService.GetUserId());
|
||||||
|
if (account is null)
|
||||||
|
{
|
||||||
|
return RequestResult.NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
data.UpdateAccount(account);
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
|
return RequestResult.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> PatchAccountUsername(AccountUsernameRequest data)
|
||||||
|
{
|
||||||
|
Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId());
|
||||||
|
|
||||||
|
if (!ComputeHash(data.Password, account.LeftSalt, account.RightSalt).SequenceEqual(account.Password))
|
||||||
|
{
|
||||||
|
return RequestResult.Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
|
data.UpdateAccount(account);
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
|
return RequestResult.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> PatchAccountEmail(AccountEmailRequest data)
|
||||||
|
{
|
||||||
|
Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId());
|
||||||
|
|
||||||
|
if (!ComputeHash(data.Password, account.LeftSalt, account.RightSalt).SequenceEqual(account.Password))
|
||||||
|
{
|
||||||
|
return RequestResult.Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
|
data.UpdateAccount(account);
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
|
return RequestResult.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> PatchAccountPassword(AccountPasswordRequest data)
|
||||||
|
{
|
||||||
|
Account account = await database.Accounts.FirstAsync(x => x.Id == userService.GetUserId());
|
||||||
|
|
||||||
|
if (!ComputeHash(data.OldPassword, account.LeftSalt, account.RightSalt).SequenceEqual(account.Password))
|
||||||
|
{
|
||||||
|
return RequestResult.Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
|
SetPassword(account, data.NewPassword);
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
|
return RequestResult.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public async Task<RequestResult> GetAccountRatedMovies(long id, MovieRatedQueryParameters query)
|
||||||
|
{
|
||||||
|
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
|
if (account is null)
|
||||||
|
{
|
||||||
|
return RequestResult.NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<MovieRatedResponse> response = account.RatingMedia.Join(database.MediaMovies, x => x.MediaId, x => x.Id, (x, y) => new MovieRatedResponse(y, x));
|
||||||
|
response = query.PrepareData(response);
|
||||||
|
return RequestResult.Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> GetAccountRatedSeries(long id, SeriesRatedQueryParameters query)
|
||||||
|
{
|
||||||
|
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
|
if (account is null)
|
||||||
|
{
|
||||||
|
return RequestResult.NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<SeriesRatedResponse> response = account.RatingMedia.Join(database.MediaSeries, x => x.MediaId, x => x.Id, (x, y) => new SeriesRatedResponse(y, x));
|
||||||
|
response = query.PrepareData(response);
|
||||||
|
return RequestResult.Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> GetAccountRatedPersons(long id, PersonRatedQueryParameters query)
|
||||||
|
{
|
||||||
|
Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
|
if (account is null)
|
||||||
|
{
|
||||||
|
return RequestResult.NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<RatingPersonActorRole> actorRolesRatings = account.RatingPersonActorRole;
|
||||||
|
IEnumerable<RatingPersonCreatorRole> creatorRolesRatings = account.RatingPersonCreatorRole;
|
||||||
|
IEnumerable<Person> persons = actorRolesRatings.Select(x => x.PersonActorRole.Person)
|
||||||
|
.Union(creatorRolesRatings.Select(x => x.PersonCreatorRole.Person));
|
||||||
|
|
||||||
|
IEnumerable<PersonRatedResponse> response = persons.Select(x => new PersonRatedResponse(x, actorRolesRatings.Where(y => y.PersonActorRole.Person.Id == x.Id), creatorRolesRatings.Where(y => y.PersonCreatorRole.Person.Id == x.Id)));
|
||||||
|
response = query.PrepareData(response);
|
||||||
|
return RequestResult.Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -137,5 +371,16 @@ public class AccountsControllerService(
|
|||||||
|
|
||||||
protected byte[] ComputeHash(string password, string leftSalt, string rightSalt) => SHA512.HashData(Encoding.UTF8.GetBytes($"{leftSalt}{password}{rightSalt}"));
|
protected byte[] ComputeHash(string password, string leftSalt, string rightSalt) => SHA512.HashData(Encoding.UTF8.GetBytes($"{leftSalt}{password}{rightSalt}"));
|
||||||
|
|
||||||
|
private void SetPassword(Account account, string password)
|
||||||
|
{
|
||||||
|
string leftSalt = StringExtensions.CreateRandom(20);
|
||||||
|
string rightSalt = StringExtensions.CreateRandom(20);
|
||||||
|
byte[] hash = ComputeHash(password, leftSalt, rightSalt);
|
||||||
|
|
||||||
|
account.Password = hash;
|
||||||
|
account.LeftSalt = leftSalt;
|
||||||
|
account.RightSalt = rightSalt;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
using WatchIt.Common.Model.Accounts;
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Common.Model.Media;
|
||||||
|
using WatchIt.Common.Model.Movies;
|
||||||
|
using WatchIt.Common.Model.Persons;
|
||||||
|
using WatchIt.Common.Model.Series;
|
||||||
using WatchIt.WebAPI.Services.Controllers.Common;
|
using WatchIt.WebAPI.Services.Controllers.Common;
|
||||||
|
|
||||||
namespace WatchIt.WebAPI.Services.Controllers.Accounts;
|
namespace WatchIt.WebAPI.Services.Controllers.Accounts;
|
||||||
@@ -10,4 +14,18 @@ public interface IAccountsControllerService
|
|||||||
Task<RequestResult> AuthenticateRefresh();
|
Task<RequestResult> AuthenticateRefresh();
|
||||||
Task<RequestResult> Logout();
|
Task<RequestResult> Logout();
|
||||||
Task<RequestResult> GetAccountProfilePicture(long id);
|
Task<RequestResult> GetAccountProfilePicture(long id);
|
||||||
|
Task<RequestResult> PutAccountProfilePicture(AccountProfilePictureRequest data);
|
||||||
|
Task<RequestResult> DeleteAccountProfilePicture();
|
||||||
|
Task<RequestResult> GetAccountProfileBackground(long id);
|
||||||
|
Task<RequestResult> PutAccountProfileBackground(AccountProfileBackgroundRequest data);
|
||||||
|
Task<RequestResult> DeleteAccountProfileBackground();
|
||||||
|
Task<RequestResult> GetAccounts(AccountQueryParameters query);
|
||||||
|
Task<RequestResult> GetAccount(long id);
|
||||||
|
Task<RequestResult> PutAccountProfileInfo(AccountProfileInfoRequest data);
|
||||||
|
Task<RequestResult> PatchAccountUsername(AccountUsernameRequest data);
|
||||||
|
Task<RequestResult> PatchAccountEmail(AccountEmailRequest data);
|
||||||
|
Task<RequestResult> PatchAccountPassword(AccountPasswordRequest data);
|
||||||
|
Task<RequestResult> GetAccountRatedMovies(long id, MovieRatedQueryParameters query);
|
||||||
|
Task<RequestResult> GetAccountRatedSeries(long id, SeriesRatedQueryParameters query);
|
||||||
|
Task<RequestResult> GetAccountRatedPersons(long id, PersonRatedQueryParameters query);
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,9 @@ public class MediaControllerService(DatabaseContext database, IUserService userS
|
|||||||
return RequestResult.NotFound();
|
return RequestResult.NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
RatingResponse ratingResponse = RatingResponse.Create(item.RatingMedia);
|
RatingResponse ratingResponse = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(item.RatingMedia, x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
|
||||||
return RequestResult.Ok(ratingResponse);
|
return RequestResult.Ok(ratingResponse);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -335,7 +335,10 @@ public class PersonsControllerService : IPersonsControllerService
|
|||||||
return RequestResult.NotFound();
|
return RequestResult.NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
RatingResponse ratingResponse = RatingResponse.Create(item.PersonActorRoles, item.PersonCreatorRoles);
|
RatingResponse ratingResponse = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(item.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole), x => x.Rating)
|
||||||
|
.Add(item.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole), x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
|
||||||
return RequestResult.Ok(ratingResponse);
|
return RequestResult.Ok(ratingResponse);
|
||||||
}
|
}
|
||||||
@@ -348,9 +351,10 @@ public class PersonsControllerService : IPersonsControllerService
|
|||||||
return RequestResult.NotFound();
|
return RequestResult.NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<RatingPersonActorRole> actorRoleRatings = item.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole).Where(x => x.AccountId == userId);
|
RatingResponse ratingResponse = RatingResponseBuilder.Initialize()
|
||||||
IEnumerable<RatingPersonCreatorRole> creatorRoleRatings = item.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole).Where(x => x.AccountId == userId);
|
.Add(item.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole).Where(x => x.AccountId == userId), x => x.Rating)
|
||||||
RatingResponse ratingResponse = RatingResponse.Create(actorRoleRatings, creatorRoleRatings);
|
.Add(item.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole).Where(x => x.AccountId == userId), x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
|
||||||
return RequestResult.Ok(ratingResponse);
|
return RequestResult.Ok(ratingResponse);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,9 @@ public class RolesControllerService : IRolesControllerService
|
|||||||
return RequestResult.NotFound();
|
return RequestResult.NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
RatingResponse ratingResponse = RatingResponse.Create(item.RatingPersonActorRole);
|
RatingResponse ratingResponse = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(item.RatingPersonActorRole, x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
|
||||||
return RequestResult.Ok(ratingResponse);
|
return RequestResult.Ok(ratingResponse);
|
||||||
}
|
}
|
||||||
@@ -281,7 +283,9 @@ public class RolesControllerService : IRolesControllerService
|
|||||||
return RequestResult.NotFound();
|
return RequestResult.NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
RatingResponse ratingResponse = RatingResponse.Create(item.RatingPersonCreatorRole);
|
RatingResponse ratingResponse = RatingResponseBuilder.Initialize()
|
||||||
|
.Add(item.RatingPersonCreatorRole, x => x.Rating)
|
||||||
|
.Build();
|
||||||
|
|
||||||
return RequestResult.Ok(ratingResponse);
|
return RequestResult.Ok(ratingResponse);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Security.Claims;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Security.Claims;
|
||||||
using WatchIt.Database;
|
using WatchIt.Database;
|
||||||
|
|
||||||
namespace WatchIt.WebAPI.Services.Utility.User;
|
namespace WatchIt.WebAPI.Services.Utility.User;
|
||||||
@@ -53,5 +54,17 @@ public class UserValidator
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UserValidator MustHaveId(long id)
|
||||||
|
{
|
||||||
|
Claim adminClaim = _claimsPrincipal.FindFirst(x => x.Type == JwtRegisteredClaimNames.Sub)!;
|
||||||
|
if (adminClaim.Value == id.ToString())
|
||||||
|
{
|
||||||
|
IsValid = false;
|
||||||
|
_validationErrors.Add("User have wrong id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Database;
|
||||||
|
|
||||||
|
namespace WatchIt.WebAPI.Validators.Accounts;
|
||||||
|
|
||||||
|
public class AccountEmailRequestValidator : AbstractValidator<AccountEmailRequest>
|
||||||
|
{
|
||||||
|
public AccountEmailRequestValidator(DatabaseContext database)
|
||||||
|
{
|
||||||
|
RuleFor(x => x.NewEmail).EmailAddress()
|
||||||
|
.CannotBeIn(database.Accounts, x => x.Email)
|
||||||
|
.WithMessage("Email was already used");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Database;
|
||||||
|
|
||||||
|
namespace WatchIt.WebAPI.Validators.Accounts;
|
||||||
|
|
||||||
|
public class AccountPasswordRequestValidator : AbstractValidator<AccountPasswordRequest>
|
||||||
|
{
|
||||||
|
public AccountPasswordRequestValidator(DatabaseContext database)
|
||||||
|
{
|
||||||
|
RuleFor(x => x.NewPassword).MinimumLength(8)
|
||||||
|
.Must(x => x.Any(char.IsUpper)).WithMessage("Password must contain at least one uppercase letter.")
|
||||||
|
.Must(x => x.Any(char.IsLower)).WithMessage("Password must contain at least one lowercase letter.")
|
||||||
|
.Must(x => x.Any(char.IsDigit)).WithMessage("Password must contain at least one digit.")
|
||||||
|
.Equal(x => x.NewPasswordConfirmation);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Database;
|
||||||
|
|
||||||
|
namespace WatchIt.WebAPI.Validators.Accounts;
|
||||||
|
|
||||||
|
public class AccountProfileBackgroundRequestValidator : AbstractValidator<AccountProfileBackgroundRequest>
|
||||||
|
{
|
||||||
|
public AccountProfileBackgroundRequestValidator(DatabaseContext database)
|
||||||
|
{
|
||||||
|
RuleFor(x => x.Id).MustBeIn(database.MediaPhotoImages.Where(x => x.MediaPhotoImageBackground != null), x => x.Id)
|
||||||
|
.WithMessage("Image has to be background");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Database;
|
||||||
|
|
||||||
|
namespace WatchIt.WebAPI.Validators.Accounts;
|
||||||
|
|
||||||
|
public class AccountProfileInfoRequestValidator : AbstractValidator<AccountProfileInfoRequest>
|
||||||
|
{
|
||||||
|
public AccountProfileInfoRequestValidator(DatabaseContext database)
|
||||||
|
{
|
||||||
|
RuleFor(x => x.Description).MaximumLength(1000);
|
||||||
|
When(x => x.GenderId.HasValue, () =>
|
||||||
|
{
|
||||||
|
RuleFor(x => x.GenderId!.Value).MustBeIn(database.Genders.Select(x => x.Id));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
|
namespace WatchIt.WebAPI.Validators.Accounts;
|
||||||
|
|
||||||
|
public class AccountProfilePictureRequestValidator : AbstractValidator<AccountProfilePictureRequest>
|
||||||
|
{
|
||||||
|
public AccountProfilePictureRequestValidator()
|
||||||
|
{
|
||||||
|
RuleFor(x => x.Image).NotEmpty();
|
||||||
|
RuleFor(x => x.MimeType).Matches(@"\w+/.+").WithMessage("Incorrect mimetype");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Database;
|
||||||
|
|
||||||
|
namespace WatchIt.WebAPI.Validators.Accounts;
|
||||||
|
|
||||||
|
public class AccountUsernameRequestValidator : AbstractValidator<AccountUsernameRequest>
|
||||||
|
{
|
||||||
|
public AccountUsernameRequestValidator(DatabaseContext database)
|
||||||
|
{
|
||||||
|
RuleFor(x => x.NewUsername).MinimumLength(5)
|
||||||
|
.MaximumLength(50)
|
||||||
|
.CannotBeIn(database.Accounts, x => x.Username)
|
||||||
|
.WithMessage("Username is already used");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,6 +46,7 @@ public static class Program
|
|||||||
|
|
||||||
while (!dbContext.Database.CanConnect())
|
while (!dbContext.Database.CanConnect())
|
||||||
{
|
{
|
||||||
|
app.Logger.LogInformation("Waiting for database...");
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using WatchIt.Website.Services.Utility.Tokens;
|
using WatchIt.Website.Services.Client.Accounts;
|
||||||
using WatchIt.Website.Services.WebAPI.Accounts;
|
using WatchIt.Website.Services.Tokens;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.Utility.Authentication;
|
namespace WatchIt.Website.Services.Authentication;
|
||||||
|
|
||||||
public class AuthenticationService : IAuthenticationService
|
public class AuthenticationService : IAuthenticationService
|
||||||
{
|
{
|
||||||
@@ -13,7 +13,7 @@ public class AuthenticationService : IAuthenticationService
|
|||||||
private readonly AuthenticationStateProvider _authenticationStateProvider;
|
private readonly AuthenticationStateProvider _authenticationStateProvider;
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly ITokensService _tokensService;
|
private readonly ITokensService _tokensService;
|
||||||
private readonly IAccountsWebAPIService _accountsWebAPIService;
|
private readonly IAccountsClientService _accountsClientService;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -21,12 +21,12 @@ public class AuthenticationService : IAuthenticationService
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public AuthenticationService(AuthenticationStateProvider authenticationStateProvider, HttpClient httpClient, ITokensService tokensService, IAccountsWebAPIService accountsWebAPIService)
|
public AuthenticationService(AuthenticationStateProvider authenticationStateProvider, HttpClient httpClient, ITokensService tokensService, IAccountsClientService accountsClientService)
|
||||||
{
|
{
|
||||||
_authenticationStateProvider = authenticationStateProvider;
|
_authenticationStateProvider = authenticationStateProvider;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_tokensService = tokensService;
|
_tokensService = tokensService;
|
||||||
_accountsWebAPIService = accountsWebAPIService;
|
_accountsClientService = accountsClientService;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -65,7 +65,7 @@ public class AuthenticationService : IAuthenticationService
|
|||||||
if (refreshToken is not null)
|
if (refreshToken is not null)
|
||||||
{
|
{
|
||||||
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("refresh", refreshToken.Replace("\"", ""));
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("refresh", refreshToken.Replace("\"", ""));
|
||||||
await _accountsWebAPIService.Logout();
|
await _accountsClientService.Logout();
|
||||||
_httpClient.DefaultRequestHeaders.Authorization = null;
|
_httpClient.DefaultRequestHeaders.Authorization = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Authentication;
|
namespace WatchIt.Website.Services.Authentication;
|
||||||
|
|
||||||
public interface IAuthenticationService
|
public interface IAuthenticationService
|
||||||
{
|
{
|
||||||
@@ -4,10 +4,10 @@ using System.Text.Json;
|
|||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using WatchIt.Common.Model.Accounts;
|
using WatchIt.Common.Model.Accounts;
|
||||||
using WatchIt.Website.Services.Utility.Tokens;
|
using WatchIt.Website.Services.Tokens;
|
||||||
using WatchIt.Website.Services.WebAPI.Accounts;
|
using WatchIt.Website.Services.Client.Accounts;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.Utility.Authentication;
|
namespace WatchIt.Website.Services.Authentication;
|
||||||
|
|
||||||
public class JWTAuthenticationStateProvider : AuthenticationStateProvider
|
public class JWTAuthenticationStateProvider : AuthenticationStateProvider
|
||||||
{
|
{
|
||||||
@@ -18,7 +18,7 @@ public class JWTAuthenticationStateProvider : AuthenticationStateProvider
|
|||||||
private readonly ILogger<JWTAuthenticationStateProvider> _logger;
|
private readonly ILogger<JWTAuthenticationStateProvider> _logger;
|
||||||
|
|
||||||
private readonly ITokensService _tokensService;
|
private readonly ITokensService _tokensService;
|
||||||
private readonly IAccountsWebAPIService _accountsService;
|
private readonly IAccountsClientService _accountsService;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ public class JWTAuthenticationStateProvider : AuthenticationStateProvider
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public JWTAuthenticationStateProvider(HttpClient httpClient, ILogger<JWTAuthenticationStateProvider> logger, ITokensService tokensService, IAccountsWebAPIService accountsService)
|
public JWTAuthenticationStateProvider(HttpClient httpClient, ILogger<JWTAuthenticationStateProvider> logger, ITokensService tokensService, IAccountsClientService accountsService)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Authentication;
|
namespace WatchIt.Website.Services.Authentication;
|
||||||
|
|
||||||
public class User
|
public class User
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.AspNetCore.Components.Authorization">
|
||||||
|
<HintPath>..\..\..\..\..\..\..\Program Files\dotnet\shared\Microsoft.AspNetCore.App\8.0.10\Microsoft.AspNetCore.Components.Authorization.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\WatchIt.Website.Services.Client\WatchIt.Website.Services.Client.csproj" />
|
||||||
|
<ProjectReference Include="..\WatchIt.Website.Services.Tokens\WatchIt.Website.Services.Tokens.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,288 @@
|
|||||||
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Common.Model.Movies;
|
||||||
|
using WatchIt.Common.Model.Persons;
|
||||||
|
using WatchIt.Common.Model.Photos;
|
||||||
|
using WatchIt.Common.Model.Series;
|
||||||
|
using WatchIt.Common.Services.HttpClient;
|
||||||
|
using WatchIt.Website.Services.Configuration;
|
||||||
|
using WatchIt.Website.Services.Tokens;
|
||||||
|
|
||||||
|
namespace WatchIt.Website.Services.Client.Accounts;
|
||||||
|
|
||||||
|
public class AccountsClientService(IHttpClientService httpClientService, IConfigurationService configurationService, ITokensService tokensService) : BaseClientService(configurationService), IAccountsClientService
|
||||||
|
{
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public async Task Register(RegisterRequest data, Action<RegisterResponse>? createdAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.Register);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Post, url)
|
||||||
|
{
|
||||||
|
Body = data,
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(createdAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Authenticate(AuthenticateRequest data, Action<AuthenticateResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.Authenticate);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Post, url)
|
||||||
|
{
|
||||||
|
Body = data,
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AuthenticateRefresh(Action<AuthenticateResponse>? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.AuthenticateRefresh);
|
||||||
|
string? token = await tokensService.GetRefreshToken();
|
||||||
|
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Post, url);
|
||||||
|
request.Headers.Add("Authorization", $"Bearer {token}");
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.RegisterActionFor403Forbidden(forbiddenAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Logout(Action? successAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.Logout);
|
||||||
|
string? token = await tokensService.GetRefreshToken();
|
||||||
|
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Delete, url);
|
||||||
|
request.Headers.Add("Authorization", $"Bearer {token}");
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task GetAccountProfilePicture(long id, Action<AccountProfilePictureResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountProfilePicture, id);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Get, url);
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor404NotFound(notFoundAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PutAccountProfilePicture(AccountProfilePictureRequest data, Action<AccountProfilePictureResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.PutAccountProfilePicture);
|
||||||
|
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Put, url)
|
||||||
|
{
|
||||||
|
Body = data
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAccountProfilePicture(Action? successAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.DeleteAccountProfilePicture);
|
||||||
|
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Delete, url);
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task GetAccountProfileBackground(long id, Action<PhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountProfileBackground, id);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Get, url);
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor404NotFound(notFoundAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PutAccountProfileBackground(AccountProfileBackgroundRequest data, Action<PhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.PutAccountProfileBackground);
|
||||||
|
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Put, url)
|
||||||
|
{
|
||||||
|
Body = data
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteAccountProfileBackground(Action? successAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.DeleteAccountProfileBackground);
|
||||||
|
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Delete, url);
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task GetAccounts(AccountQueryParameters query, Action<IEnumerable<AccountResponse>>? successAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccounts);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Get, url)
|
||||||
|
{
|
||||||
|
Query = query
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task GetAccount(long id, Action<AccountResponse>? successAction = null, Action? notFoundAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccount, id);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Get, url);
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor404NotFound(notFoundAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PutAccountProfileInfo(AccountProfileInfoRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.PutAccountProfileInfo);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Put, url)
|
||||||
|
{
|
||||||
|
Body = data,
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PatchAccountUsername(AccountUsernameRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.PatchAccountUsername);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Patch, url)
|
||||||
|
{
|
||||||
|
Body = data,
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PatchAccountEmail(AccountEmailRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.PatchAccountEmail);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Patch, url)
|
||||||
|
{
|
||||||
|
Body = data,
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task PatchAccountPassword(AccountPasswordRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.PatchAccountPassword);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Patch, url)
|
||||||
|
{
|
||||||
|
Body = data,
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor400BadRequest(badRequestAction)
|
||||||
|
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query, Action<IEnumerable<MovieRatedResponse>>? successAction = null, Action? notFoundAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountRatedMovies, id);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Get, url)
|
||||||
|
{
|
||||||
|
Query = query
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor404NotFound(notFoundAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters query, Action<IEnumerable<SeriesRatedResponse>>? successAction = null, Action? notFoundAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountRatedSeries, id);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Get, url)
|
||||||
|
{
|
||||||
|
Query = query
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor404NotFound(notFoundAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task GetAccountRatedPersons(long id, PersonRatedQueryParameters query, Action<IEnumerable<PersonRatedResponse>>? successAction = null, Action? notFoundAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountRatedPersons, id);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Get, url)
|
||||||
|
{
|
||||||
|
Query = query
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor404NotFound(notFoundAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
protected override string GetServiceBase() => EndpointsConfiguration.Accounts.Base;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
using WatchIt.Common.Model.Movies;
|
||||||
|
using WatchIt.Common.Model.Persons;
|
||||||
|
using WatchIt.Common.Model.Photos;
|
||||||
|
using WatchIt.Common.Model.Series;
|
||||||
|
|
||||||
|
namespace WatchIt.Website.Services.Client.Accounts;
|
||||||
|
|
||||||
|
public interface IAccountsClientService
|
||||||
|
{
|
||||||
|
Task Register(RegisterRequest data, Action<RegisterResponse>? createdAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null);
|
||||||
|
Task Authenticate(AuthenticateRequest data, Action<AuthenticateResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task AuthenticateRefresh(Action<AuthenticateResponse>? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null);
|
||||||
|
Task Logout(Action? successAction = null);
|
||||||
|
Task GetAccountProfilePicture(long id, Action<AccountProfilePictureResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null);
|
||||||
|
Task PutAccountProfilePicture(AccountProfilePictureRequest data, Action<AccountProfilePictureResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task DeleteAccountProfilePicture(Action? successAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task GetAccountProfileBackground(long id, Action<PhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null);
|
||||||
|
Task PutAccountProfileBackground(AccountProfileBackgroundRequest data, Action<PhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task DeleteAccountProfileBackground(Action? successAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task GetAccounts(AccountQueryParameters query, Action<IEnumerable<AccountResponse>>? successAction = null);
|
||||||
|
Task GetAccount(long id, Action<AccountResponse>? successAction = null, Action? notFoundAction = null);
|
||||||
|
Task PutAccountProfileInfo(AccountProfileInfoRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task PatchAccountUsername(AccountUsernameRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task PatchAccountEmail(AccountEmailRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task PatchAccountPassword(AccountPasswordRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null);
|
||||||
|
Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query, Action<IEnumerable<MovieRatedResponse>>? successAction = null, Action? notFoundAction = null);
|
||||||
|
Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters query, Action<IEnumerable<SeriesRatedResponse>>? successAction = null, Action? notFoundAction = null);
|
||||||
|
Task GetAccountRatedPersons(long id, PersonRatedQueryParameters query, Action<IEnumerable<PersonRatedResponse>>? successAction = null, Action? notFoundAction = null);
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.WebAPI.Common;
|
namespace WatchIt.Website.Services.Client;
|
||||||
|
|
||||||
public enum AuthorizationType
|
public enum AuthorizationType
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
using WatchIt.Website.Services.Utility.Configuration;
|
using WatchIt.Website.Services.Configuration;
|
||||||
using WatchIt.Website.Services.Utility.Configuration.Model;
|
using WatchIt.Website.Services.Configuration.Model;
|
||||||
using WatchIt.Website.Services.Utility.Tokens;
|
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Common;
|
namespace WatchIt.Website.Services.Client;
|
||||||
|
|
||||||
public abstract class BaseWebAPIService
|
public abstract class BaseClientService
|
||||||
{
|
{
|
||||||
#region SERVICES
|
#region SERVICES
|
||||||
|
|
||||||
@@ -24,7 +23,7 @@ public abstract class BaseWebAPIService
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
protected BaseWebAPIService(IConfigurationService configurationService)
|
protected BaseClientService(IConfigurationService configurationService)
|
||||||
{
|
{
|
||||||
_configurationService = configurationService;
|
_configurationService = configurationService;
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
using WatchIt.Common.Model.Genders;
|
using WatchIt.Common.Model.Genders;
|
||||||
using WatchIt.Common.Services.HttpClient;
|
using WatchIt.Common.Services.HttpClient;
|
||||||
using WatchIt.Website.Services.Utility.Configuration;
|
using WatchIt.Website.Services.Configuration;
|
||||||
using WatchIt.Website.Services.WebAPI.Common;
|
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Genders;
|
namespace WatchIt.Website.Services.Client.Genders;
|
||||||
|
|
||||||
public class GendersWebAPIService : BaseWebAPIService, IGendersWebAPIService
|
public class GendersClientService : BaseClientService, IGendersClientService
|
||||||
{
|
{
|
||||||
#region SERVICES
|
#region SERVICES
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ public class GendersWebAPIService : BaseWebAPIService, IGendersWebAPIService
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public GendersWebAPIService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
public GendersClientService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
||||||
{
|
{
|
||||||
_httpClientService = httpClientService;
|
_httpClientService = httpClientService;
|
||||||
_configurationService = configurationService;
|
_configurationService = configurationService;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using WatchIt.Common.Model.Genders;
|
using WatchIt.Common.Model.Genders;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Genders;
|
namespace WatchIt.Website.Services.Client.Genders;
|
||||||
|
|
||||||
public interface IGendersWebAPIService
|
public interface IGendersClientService
|
||||||
{
|
{
|
||||||
Task GetAllGenders(GenderQueryParameters? query = null, Action<IEnumerable<GenderResponse>>? successAction = null);
|
Task GetAllGenders(GenderQueryParameters? query = null, Action<IEnumerable<GenderResponse>>? successAction = null);
|
||||||
Task GetGender(long id, Action<GenderResponse>? successAction = null, Action? notFoundAction = null);
|
Task GetGender(long id, Action<GenderResponse>? successAction = null, Action? notFoundAction = null);
|
||||||
@@ -4,9 +4,9 @@ using WatchIt.Common.Model.Photos;
|
|||||||
using WatchIt.Common.Model.Rating;
|
using WatchIt.Common.Model.Rating;
|
||||||
using WatchIt.Common.Model.Roles;
|
using WatchIt.Common.Model.Roles;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Media;
|
namespace WatchIt.Website.Services.Client.Media;
|
||||||
|
|
||||||
public interface IMediaWebAPIService
|
public interface IMediaClientService
|
||||||
{
|
{
|
||||||
Task GetAllMedia(MediaQueryParameters? query = null, Action<IEnumerable<MediaResponse>>? successAction = null);
|
Task GetAllMedia(MediaQueryParameters? query = null, Action<IEnumerable<MediaResponse>>? successAction = null);
|
||||||
Task GetMedia(long mediaId, Action<MediaResponse>? successAction = null, Action? notFoundAction = null);
|
Task GetMedia(long mediaId, Action<MediaResponse>? successAction = null, Action? notFoundAction = null);
|
||||||
@@ -4,13 +4,11 @@ using WatchIt.Common.Model.Photos;
|
|||||||
using WatchIt.Common.Model.Rating;
|
using WatchIt.Common.Model.Rating;
|
||||||
using WatchIt.Common.Model.Roles;
|
using WatchIt.Common.Model.Roles;
|
||||||
using WatchIt.Common.Services.HttpClient;
|
using WatchIt.Common.Services.HttpClient;
|
||||||
using WatchIt.Website.Services.Utility.Configuration;
|
using WatchIt.Website.Services.Configuration;
|
||||||
using WatchIt.Website.Services.Utility.Configuration.Model;
|
|
||||||
using WatchIt.Website.Services.WebAPI.Common;
|
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Media;
|
namespace WatchIt.Website.Services.Client.Media;
|
||||||
|
|
||||||
public class MediaWebAPIService : BaseWebAPIService, IMediaWebAPIService
|
public class MediaClientService : BaseClientService, IMediaClientService
|
||||||
{
|
{
|
||||||
#region FIELDS
|
#region FIELDS
|
||||||
|
|
||||||
@@ -22,7 +20,7 @@ public class MediaWebAPIService : BaseWebAPIService, IMediaWebAPIService
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public MediaWebAPIService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
public MediaClientService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
||||||
{
|
{
|
||||||
_httpClientService = httpClientService;
|
_httpClientService = httpClientService;
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using WatchIt.Common.Model.Movies;
|
using WatchIt.Common.Model.Movies;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Movies;
|
namespace WatchIt.Website.Services.Client.Movies;
|
||||||
|
|
||||||
public interface IMoviesWebAPIService
|
public interface IMoviesClientService
|
||||||
{
|
{
|
||||||
Task GetAllMovies(MovieQueryParameters? query = null, Action<IEnumerable<MovieResponse>>? successAction = null);
|
Task GetAllMovies(MovieQueryParameters? query = null, Action<IEnumerable<MovieResponse>>? successAction = null);
|
||||||
Task PostMovie(MovieRequest data, Action<MovieResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null);
|
Task PostMovie(MovieRequest data, Action<MovieResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null);
|
||||||
@@ -3,12 +3,11 @@ using Microsoft.AspNetCore.Components;
|
|||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using WatchIt.Common.Model.Movies;
|
using WatchIt.Common.Model.Movies;
|
||||||
using WatchIt.Common.Services.HttpClient;
|
using WatchIt.Common.Services.HttpClient;
|
||||||
using WatchIt.Website.Services.Utility.Configuration;
|
using WatchIt.Website.Services.Configuration;
|
||||||
using WatchIt.Website.Services.WebAPI.Common;
|
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Movies;
|
namespace WatchIt.Website.Services.Client.Movies;
|
||||||
|
|
||||||
public class MoviesWebAPIService : BaseWebAPIService, IMoviesWebAPIService
|
public class MoviesClientService : BaseClientService, IMoviesClientService
|
||||||
{
|
{
|
||||||
#region SERVICES
|
#region SERVICES
|
||||||
|
|
||||||
@@ -21,7 +20,7 @@ public class MoviesWebAPIService : BaseWebAPIService, IMoviesWebAPIService
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public MoviesWebAPIService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
public MoviesClientService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
||||||
{
|
{
|
||||||
_httpClientService = httpClientService;
|
_httpClientService = httpClientService;
|
||||||
_configurationService = configurationService;
|
_configurationService = configurationService;
|
||||||
@@ -2,9 +2,9 @@ using WatchIt.Common.Model.Persons;
|
|||||||
using WatchIt.Common.Model.Rating;
|
using WatchIt.Common.Model.Rating;
|
||||||
using WatchIt.Common.Model.Roles;
|
using WatchIt.Common.Model.Roles;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Persons;
|
namespace WatchIt.Website.Services.Client.Persons;
|
||||||
|
|
||||||
public interface IPersonsWebAPIService
|
public interface IPersonsClientService
|
||||||
{
|
{
|
||||||
Task GetAllPersons(PersonQueryParameters? query = null, Action<IEnumerable<PersonResponse>>? successAction = null);
|
Task GetAllPersons(PersonQueryParameters? query = null, Action<IEnumerable<PersonResponse>>? successAction = null);
|
||||||
Task GetPerson(long id, Action<PersonResponse>? successAction = null, Action? notFoundAction = null);
|
Task GetPerson(long id, Action<PersonResponse>? successAction = null, Action? notFoundAction = null);
|
||||||
@@ -5,12 +5,11 @@ using WatchIt.Common.Model.Persons;
|
|||||||
using WatchIt.Common.Model.Rating;
|
using WatchIt.Common.Model.Rating;
|
||||||
using WatchIt.Common.Model.Roles;
|
using WatchIt.Common.Model.Roles;
|
||||||
using WatchIt.Common.Services.HttpClient;
|
using WatchIt.Common.Services.HttpClient;
|
||||||
using WatchIt.Website.Services.Utility.Configuration;
|
using WatchIt.Website.Services.Configuration;
|
||||||
using WatchIt.Website.Services.WebAPI.Common;
|
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Persons;
|
namespace WatchIt.Website.Services.Client.Persons;
|
||||||
|
|
||||||
public class PersonsWebAPIService : BaseWebAPIService, IPersonsWebAPIService
|
public class PersonsClientService : BaseClientService, IPersonsClientService
|
||||||
{
|
{
|
||||||
#region SERVICES
|
#region SERVICES
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@ public class PersonsWebAPIService : BaseWebAPIService, IPersonsWebAPIService
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public PersonsWebAPIService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
public PersonsClientService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
||||||
{
|
{
|
||||||
_httpClientService = httpClientService;
|
_httpClientService = httpClientService;
|
||||||
_configurationService = configurationService;
|
_configurationService = configurationService;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using WatchIt.Common.Model.Photos;
|
using WatchIt.Common.Model.Photos;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Photos;
|
namespace WatchIt.Website.Services.Client.Photos;
|
||||||
|
|
||||||
public interface IPhotosWebAPIService
|
public interface IPhotosClientService
|
||||||
{
|
{
|
||||||
Task GetPhotoRandomBackground(Action<PhotoResponse>? successAction = null, Action? notFoundAction = null);
|
Task GetPhotoRandomBackground(Action<PhotoResponse>? successAction = null, Action? notFoundAction = null);
|
||||||
Task DeletePhoto(Guid id, Action? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null, Action? notFoundAction = null);
|
Task DeletePhoto(Guid id, Action? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null, Action? notFoundAction = null);
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
using WatchIt.Common.Model.Photos;
|
using WatchIt.Common.Model.Photos;
|
||||||
using WatchIt.Common.Services.HttpClient;
|
using WatchIt.Common.Services.HttpClient;
|
||||||
using WatchIt.Website.Services.Utility.Configuration;
|
using WatchIt.Website.Services.Configuration;
|
||||||
using WatchIt.Website.Services.WebAPI.Common;
|
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Photos;
|
namespace WatchIt.Website.Services.Client.Photos;
|
||||||
|
|
||||||
public class PhotosWebAPIService : BaseWebAPIService, IPhotosWebAPIService
|
public class PhotosClientService : BaseClientService, IPhotosClientService
|
||||||
{
|
{
|
||||||
#region FIELDS
|
#region FIELDS
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ public class PhotosWebAPIService : BaseWebAPIService, IPhotosWebAPIService
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public PhotosWebAPIService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
public PhotosClientService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
||||||
{
|
{
|
||||||
_httpClientService = httpClientService;
|
_httpClientService = httpClientService;
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using WatchIt.Common.Model.Rating;
|
using WatchIt.Common.Model.Rating;
|
||||||
using WatchIt.Common.Model.Roles;
|
using WatchIt.Common.Model.Roles;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Roles;
|
namespace WatchIt.Website.Services.Client.Roles;
|
||||||
|
|
||||||
public interface IRolesWebAPIService
|
public interface IRolesClientService
|
||||||
{
|
{
|
||||||
Task GetActorRole(Guid id, Action<ActorRoleResponse>? successAction = null, Action? notFoundAction = null);
|
Task GetActorRole(Guid id, Action<ActorRoleResponse>? successAction = null, Action? notFoundAction = null);
|
||||||
Task PutActorRole(Guid id, ActorRoleUniversalRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null, Action? notFoundAction = null);
|
Task PutActorRole(Guid id, ActorRoleUniversalRequest data, Action? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null, Action? notFoundAction = null);
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
using WatchIt.Common.Model.Rating;
|
using WatchIt.Common.Model.Rating;
|
||||||
using WatchIt.Common.Model.Roles;
|
using WatchIt.Common.Model.Roles;
|
||||||
using WatchIt.Common.Services.HttpClient;
|
using WatchIt.Common.Services.HttpClient;
|
||||||
using WatchIt.Website.Services.Utility.Configuration;
|
using WatchIt.Website.Services.Configuration;
|
||||||
using WatchIt.Website.Services.WebAPI.Common;
|
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Roles;
|
namespace WatchIt.Website.Services.Client.Roles;
|
||||||
|
|
||||||
public class RolesWebAPIService : BaseWebAPIService, IRolesWebAPIService
|
public class RolesClientService : BaseClientService, IRolesClientService
|
||||||
{
|
{
|
||||||
#region SERVICES
|
#region SERVICES
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ public class RolesWebAPIService : BaseWebAPIService, IRolesWebAPIService
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public RolesWebAPIService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
public RolesClientService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
||||||
{
|
{
|
||||||
_httpClientService = httpClientService;
|
_httpClientService = httpClientService;
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using WatchIt.Common.Model.Series;
|
using WatchIt.Common.Model.Series;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Series;
|
namespace WatchIt.Website.Services.Client.Series;
|
||||||
|
|
||||||
public interface ISeriesWebAPIService
|
public interface ISeriesClientService
|
||||||
{
|
{
|
||||||
Task GetAllSeries(SeriesQueryParameters? query = null, Action<IEnumerable<SeriesResponse>>? successAction = null);
|
Task GetAllSeries(SeriesQueryParameters? query = null, Action<IEnumerable<SeriesResponse>>? successAction = null);
|
||||||
Task GetSeries(long id, Action<SeriesResponse>? successAction = null, Action? notFoundAction = null);
|
Task GetSeries(long id, Action<SeriesResponse>? successAction = null, Action? notFoundAction = null);
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using WatchIt.Common.Model.Series;
|
using WatchIt.Common.Model.Series;
|
||||||
using WatchIt.Common.Services.HttpClient;
|
using WatchIt.Common.Services.HttpClient;
|
||||||
using WatchIt.Website.Services.Utility.Configuration;
|
using WatchIt.Website.Services.Configuration;
|
||||||
using WatchIt.Website.Services.WebAPI.Common;
|
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.WebAPI.Series;
|
namespace WatchIt.Website.Services.Client.Series;
|
||||||
|
|
||||||
public class SeriesWebAPIService : BaseWebAPIService, ISeriesWebAPIService
|
public class SeriesClientService : BaseClientService, ISeriesClientService
|
||||||
{
|
{
|
||||||
#region SERVICES
|
#region SERVICES
|
||||||
|
|
||||||
@@ -19,7 +18,7 @@ public class SeriesWebAPIService : BaseWebAPIService, ISeriesWebAPIService
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public SeriesWebAPIService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
public SeriesClientService(IHttpClientService httpClientService, IConfigurationService configurationService) : base(configurationService)
|
||||||
{
|
{
|
||||||
_httpClientService = httpClientService;
|
_httpClientService = httpClientService;
|
||||||
_configurationService = configurationService;
|
_configurationService = configurationService;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\WatchIt.Common\WatchIt.Common.Model\WatchIt.Common.Model.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\WatchIt.Common\WatchIt.Common.Services\WatchIt.Common.Services.HttpClient\WatchIt.Common.Services.HttpClient.csproj" />
|
||||||
|
<ProjectReference Include="..\WatchIt.Website.Services.Tokens\WatchIt.Website.Services.Tokens.csproj" />
|
||||||
|
<ProjectReference Include="..\WatchIt.Website.Services.Configuration\WatchIt.Website.Services.Configuration.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using WatchIt.Website.Services.Utility.Configuration.Model;
|
using WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.Utility.Configuration;
|
namespace WatchIt.Website.Services.Configuration;
|
||||||
|
|
||||||
public class ConfigurationService(IConfiguration configuration) : IConfigurationService
|
public class ConfigurationService(IConfiguration configuration) : IConfigurationService
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
|
namespace WatchIt.Website.Services.Configuration;
|
||||||
|
|
||||||
|
public interface IConfigurationService
|
||||||
|
{
|
||||||
|
ConfigurationData Data { get; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
|
public class Accounts
|
||||||
|
{
|
||||||
|
public string Base { get; set; }
|
||||||
|
public string Register { get; set; }
|
||||||
|
public string Authenticate { get; set; }
|
||||||
|
public string AuthenticateRefresh { get; set; }
|
||||||
|
public string Logout { get; set; }
|
||||||
|
public string GetAccountProfilePicture { get; set; }
|
||||||
|
public string PutAccountProfilePicture { get; set; }
|
||||||
|
public string DeleteAccountProfilePicture { get; set; }
|
||||||
|
public string GetAccountProfileBackground { get; set; }
|
||||||
|
public string PutAccountProfileBackground { get; set; }
|
||||||
|
public string DeleteAccountProfileBackground { get; set; }
|
||||||
|
public string GetAccounts { get; set; }
|
||||||
|
public string GetAccount { get; set; }
|
||||||
|
public string PutAccountProfileInfo { get; set; }
|
||||||
|
public string PatchAccountUsername { get; set; }
|
||||||
|
public string PatchAccountEmail { get; set; }
|
||||||
|
public string PatchAccountPassword { get; set; }
|
||||||
|
public string GetAccountRatedMovies { get; set; }
|
||||||
|
public string GetAccountRatedSeries { get; set; }
|
||||||
|
public string GetAccountRatedPersons { get; set; }
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class ConfigurationData
|
public class ConfigurationData
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Endpoints
|
public class Endpoints
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Genders
|
public class Genders
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Genres
|
public class Genres
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class LogLevel
|
public class LogLevel
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Logging
|
public class Logging
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Media
|
public class Media
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Movies
|
public class Movies
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Persons
|
public class Persons
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Photos
|
public class Photos
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Roles
|
public class Roles
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Series
|
public class Series
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class StorageKeys
|
public class StorageKeys
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WatchIt.Website.Services.Utility.Configuration.Model;
|
namespace WatchIt.Website.Services.Configuration.Model;
|
||||||
|
|
||||||
public class Style
|
public class Style
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using WatchIt.Common.Model.Accounts;
|
using WatchIt.Common.Model.Accounts;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.Utility.Tokens;
|
namespace WatchIt.Website.Services.Tokens;
|
||||||
|
|
||||||
public interface ITokensService
|
public interface ITokensService
|
||||||
{
|
{
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
|
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using WatchIt.Common.Model.Accounts;
|
using WatchIt.Common.Model.Accounts;
|
||||||
using WatchIt.Website.Services.Utility.Configuration;
|
using WatchIt.Website.Services.Configuration;
|
||||||
|
|
||||||
namespace WatchIt.Website.Services.Utility.Tokens;
|
namespace WatchIt.Website.Services.Tokens;
|
||||||
|
|
||||||
public class TokensService : ITokensService
|
public class TokensService : ITokensService
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\WatchIt.Common\WatchIt.Common.Model\WatchIt.Common.Model.csproj" />
|
||||||
|
<ProjectReference Include="..\WatchIt.Website.Services.Configuration\WatchIt.Website.Services.Configuration.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user