mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
CodingStyle: Fixing more issues
This commit is contained in:
parent
d3a03771dd
commit
aec2a8f51a
@ -10,7 +10,7 @@ using Kyoo.Abstractions.Models.Exceptions;
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface to interract with the database. Every repository is mapped through here.
|
||||
/// An interface to interact with the database. Every repository is mapped through here.
|
||||
/// </summary>
|
||||
public interface ILibraryManager
|
||||
{
|
||||
@ -20,7 +20,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <typeparam name="T">The type you want</typeparam>
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
/// <returns>The repository corresponding</returns>
|
||||
IRepository<T> GetRepository<T>() where T : class, IResource;
|
||||
IRepository<T> GetRepository<T>()
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle libraries.
|
||||
@ -28,7 +29,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
ILibraryRepository LibraryRepository { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository that handle libraries's items (a wrapper arround shows & collections).
|
||||
/// The repository that handle libraries items (a wrapper around shows & collections).
|
||||
/// </summary>
|
||||
ILibraryItemRepository LibraryItemRepository { get; }
|
||||
|
||||
@ -90,7 +91,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
/// <returns>The resource found</returns>
|
||||
[ItemNotNull]
|
||||
Task<T> Get<T>(int id) where T : class, IResource;
|
||||
Task<T> Get<T>(int id)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Get the resource by it's slug
|
||||
@ -100,7 +102,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
/// <returns>The resource found</returns>
|
||||
[ItemNotNull]
|
||||
Task<T> Get<T>(string slug) where T : class, IResource;
|
||||
Task<T> Get<T>(string slug)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Get the resource by a filter function.
|
||||
@ -110,7 +113,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
/// <returns>The first resource found that match the where function</returns>
|
||||
[ItemNotNull]
|
||||
Task<T> Get<T>(Expression<Func<T, bool>> where) where T : class, IResource;
|
||||
Task<T> Get<T>(Expression<Func<T, bool>> where)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Get a season from it's showID and it's seasonNumber
|
||||
@ -161,7 +165,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <typeparam name="T">The type of the resource</typeparam>
|
||||
/// <returns>The resource found</returns>
|
||||
[ItemCanBeNull]
|
||||
Task<T> GetOrDefault<T>(int id) where T : class, IResource;
|
||||
Task<T> GetOrDefault<T>(int id)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Get the resource by it's slug or null if it is not found.
|
||||
@ -170,7 +175,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <typeparam name="T">The type of the resource</typeparam>
|
||||
/// <returns>The resource found</returns>
|
||||
[ItemCanBeNull]
|
||||
Task<T> GetOrDefault<T>(string slug) where T : class, IResource;
|
||||
Task<T> GetOrDefault<T>(string slug)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Get the resource by a filter function or null if it is not found.
|
||||
@ -179,7 +185,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <typeparam name="T">The type of the resource</typeparam>
|
||||
/// <returns>The first resource found that match the where function</returns>
|
||||
[ItemCanBeNull]
|
||||
Task<T> GetOrDefault<T>(Expression<Func<T, bool>> where) where T : class, IResource;
|
||||
Task<T> GetOrDefault<T>(Expression<Func<T, bool>> where)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Get a season from it's showID and it's seasonNumber or null if it is not found.
|
||||
@ -219,20 +226,19 @@ namespace Kyoo.Abstractions.Controllers
|
||||
[ItemCanBeNull]
|
||||
Task<Episode> GetOrDefault(string showSlug, int seasonNumber, int episodeNumber);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Load a related resource
|
||||
/// </summary>
|
||||
/// <param name="obj">The source object.</param>
|
||||
/// <param name="member">A getter function for the member to load</param>
|
||||
/// <param name="force">
|
||||
/// <c>true</c> if you want to load the relation even if it is not null, <c>false</c> otherwise.
|
||||
/// <c>true</c> if you want to load the relation even if it is not null, <c>false</c> otherwise.
|
||||
/// </param>
|
||||
/// <typeparam name="T">The type of the source object</typeparam>
|
||||
/// <typeparam name="T2">The related resource's type</typeparam>
|
||||
/// <returns>The param <see cref="obj"/></returns>
|
||||
/// <seealso cref="Load{T,T2}(T, System.Linq.Expressions.Expression{System.Func{T,System.Collections.Generic.ICollection{T2}}}, bool)"/>
|
||||
/// <seealso cref="Load{T}(T, System.String, bool)"/>
|
||||
/// <seealso cref="Load{T}(T, string, bool)"/>
|
||||
/// <seealso cref="Load(IResource, string, bool)"/>
|
||||
Task<T> Load<T, T2>([NotNull] T obj, Expression<Func<T, T2>> member, bool force = false)
|
||||
where T : class, IResource
|
||||
@ -244,13 +250,13 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <param name="obj">The source object.</param>
|
||||
/// <param name="member">A getter function for the member to load</param>
|
||||
/// <param name="force">
|
||||
/// <c>true</c> if you want to load the relation even if it is not null, <c>false</c> otherwise.
|
||||
/// <c>true</c> if you want to load the relation even if it is not null, <c>false</c> otherwise.
|
||||
/// </param>
|
||||
/// <typeparam name="T">The type of the source object</typeparam>
|
||||
/// <typeparam name="T2">The related resource's type</typeparam>
|
||||
/// <returns>The param <see cref="obj"/></returns>
|
||||
/// <seealso cref="Load{T,T2}(T, System.Linq.Expressions.Expression{System.Func{T,T2}}, bool)"/>
|
||||
/// <seealso cref="Load{T}(T, System.String, bool)"/>
|
||||
/// <seealso cref="Load{T}(T, string, bool)"/>
|
||||
/// <seealso cref="Load(IResource, string, bool)"/>
|
||||
Task<T> Load<T, T2>([NotNull] T obj, Expression<Func<T, ICollection<T2>>> member, bool force = false)
|
||||
where T : class, IResource
|
||||
@ -262,7 +268,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <param name="obj">The source object.</param>
|
||||
/// <param name="memberName">The name of the resource to load (case sensitive)</param>
|
||||
/// <param name="force">
|
||||
/// <c>true</c> if you want to load the relation even if it is not null, <c>false</c> otherwise.
|
||||
/// <c>true</c> if you want to load the relation even if it is not null, <c>false</c> otherwise.
|
||||
/// </param>
|
||||
/// <typeparam name="T">The type of the source object</typeparam>
|
||||
/// <returns>The param <see cref="obj"/></returns>
|
||||
@ -273,24 +279,25 @@ namespace Kyoo.Abstractions.Controllers
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Load a related resource without specifing it's type.
|
||||
/// Load a related resource without specifying it's type.
|
||||
/// </summary>
|
||||
/// <param name="obj">The source object.</param>
|
||||
/// <param name="memberName">The name of the resource to load (case sensitive)</param>
|
||||
/// <param name="force">
|
||||
/// <c>true</c> if you want to load the relation even if it is not null, <c>false</c> otherwise.
|
||||
/// <c>true</c> if you want to load the relation even if it is not null, <c>false</c> otherwise.
|
||||
/// </param>
|
||||
/// <seealso cref="Load{T,T2}(T, System.Linq.Expressions.Expression{System.Func{T,T2}}, bool)"/>
|
||||
/// <seealso cref="Load{T,T2}(T, System.Linq.Expressions.Expression{System.Func{T,System.Collections.Generic.ICollection{T2}}}, bool)"/>
|
||||
/// <seealso cref="Load{T}(T, System.String, bool)"/>
|
||||
/// <seealso cref="Load{T}(T, string, bool)"/>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task Load([NotNull] IResource obj, string memberName, bool force = false);
|
||||
|
||||
/// <summary>
|
||||
/// Get items (A wrapper arround shows or collections) from a library.
|
||||
/// Get items (A wrapper around shows or collections) from a library.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the library</param>
|
||||
/// <param name="where">A filter function</param>
|
||||
/// <param name="sort">Sort informations (sort order & sort by)</param>
|
||||
/// <param name="sort">Sort information (sort order & sort by)</param>
|
||||
/// <param name="limit">How many items to return and where to start</param>
|
||||
/// <returns>A list of items that match every filters</returns>
|
||||
Task<ICollection<LibraryItem>> GetItemsFromLibrary(int id,
|
||||
@ -299,7 +306,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
Pagination limit = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get items (A wrapper arround shows or collections) from a library.
|
||||
/// Get items (A wrapper around shows or collections) from a library.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the library</param>
|
||||
/// <param name="where">A filter function</param>
|
||||
@ -313,11 +320,11 @@ namespace Kyoo.Abstractions.Controllers
|
||||
) => GetItemsFromLibrary(id, where, new Sort<LibraryItem>(sort), limit);
|
||||
|
||||
/// <summary>
|
||||
/// Get items (A wrapper arround shows or collections) from a library.
|
||||
/// Get items (A wrapper around shows or collections) from a library.
|
||||
/// </summary>
|
||||
/// <param name="slug">The slug of the library</param>
|
||||
/// <param name="where">A filter function</param>
|
||||
/// <param name="sort">Sort informations (sort order & sort by)</param>
|
||||
/// <param name="sort">Sort information (sort order & sort by)</param>
|
||||
/// <param name="limit">How many items to return and where to start</param>
|
||||
/// <returns>A list of items that match every filters</returns>
|
||||
Task<ICollection<LibraryItem>> GetItemsFromLibrary(string slug,
|
||||
@ -326,7 +333,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
Pagination limit = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get items (A wrapper arround shows or collections) from a library.
|
||||
/// Get items (A wrapper around shows or collections) from a library.
|
||||
/// </summary>
|
||||
/// <param name="slug">The slug of the library</param>
|
||||
/// <param name="where">A filter function</param>
|
||||
@ -339,13 +346,12 @@ namespace Kyoo.Abstractions.Controllers
|
||||
Pagination limit = default
|
||||
) => GetItemsFromLibrary(slug, where, new Sort<LibraryItem>(sort), limit);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get people's roles from a show.
|
||||
/// </summary>
|
||||
/// <param name="showID">The ID of the show</param>
|
||||
/// <param name="where">A filter function</param>
|
||||
/// <param name="sort">Sort informations (sort order & sort by)</param>
|
||||
/// <param name="sort">Sort information (sort order & sort by)</param>
|
||||
/// <param name="limit">How many items to return and where to start</param>
|
||||
/// <returns>A list of items that match every filters</returns>
|
||||
Task<ICollection<PeopleRole>> GetPeopleFromShow(int showID,
|
||||
@ -372,7 +378,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// </summary>
|
||||
/// <param name="showSlug">The slug of the show</param>
|
||||
/// <param name="where">A filter function</param>
|
||||
/// <param name="sort">Sort informations (sort order & sort by)</param>
|
||||
/// <param name="sort">Sort information (sort order & sort by)</param>
|
||||
/// <param name="limit">How many items to return and where to start</param>
|
||||
/// <returns>A list of items that match every filters</returns>
|
||||
Task<ICollection<PeopleRole>> GetPeopleFromShow(string showSlug,
|
||||
@ -394,13 +400,12 @@ namespace Kyoo.Abstractions.Controllers
|
||||
Pagination limit = default
|
||||
) => GetPeopleFromShow(showSlug, where, new Sort<PeopleRole>(sort), limit);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get people's roles from a person.
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the person</param>
|
||||
/// <param name="where">A filter function</param>
|
||||
/// <param name="sort">Sort informations (sort order & sort by)</param>
|
||||
/// <param name="sort">Sort information (sort order & sort by)</param>
|
||||
/// <param name="limit">How many items to return and where to start</param>
|
||||
/// <returns>A list of items that match every filters</returns>
|
||||
Task<ICollection<PeopleRole>> GetRolesFromPeople(int id,
|
||||
@ -427,7 +432,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// </summary>
|
||||
/// <param name="slug">The slug of the person</param>
|
||||
/// <param name="where">A filter function</param>
|
||||
/// <param name="sort">Sort informations (sort order & sort by)</param>
|
||||
/// <param name="sort">Sort information (sort order & sort by)</param>
|
||||
/// <param name="limit">How many items to return and where to start</param>
|
||||
/// <returns>A list of items that match every filters</returns>
|
||||
Task<ICollection<PeopleRole>> GetRolesFromPeople(string slug,
|
||||
@ -449,13 +454,13 @@ namespace Kyoo.Abstractions.Controllers
|
||||
Pagination limit = default
|
||||
) => GetRolesFromPeople(slug, where, new Sort<PeopleRole>(sort), limit);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Setup relations between a show, a library and a collection
|
||||
/// </summary>
|
||||
/// <param name="showID">The show's ID to setup relations with</param>
|
||||
/// <param name="libraryID">The library's ID to setup relations with (optional)</param>
|
||||
/// <param name="collectionID">The collection's ID to setup relations with (optional)</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task AddShowLink(int showID, int? libraryID, int? collectionID);
|
||||
|
||||
/// <summary>
|
||||
@ -464,19 +469,21 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <param name="show">The show to setup relations with</param>
|
||||
/// <param name="library">The library to setup relations with (optional)</param>
|
||||
/// <param name="collection">The collection to setup relations with (optional)</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task AddShowLink([NotNull] Show show, Library library, Collection collection);
|
||||
|
||||
/// <summary>
|
||||
/// Get all resources with filters
|
||||
/// </summary>
|
||||
/// <param name="where">A filter function</param>
|
||||
/// <param name="sort">Sort informations (sort order & sort by)</param>
|
||||
/// <param name="sort">Sort information (sort order & sort by)</param>
|
||||
/// <param name="limit">How many items to return and where to start</param>
|
||||
/// <typeparam name="T">The type of resources to load</typeparam>
|
||||
/// <returns>A list of resources that match every filters</returns>
|
||||
Task<ICollection<T>> GetAll<T>(Expression<Func<T, bool>> where = null,
|
||||
Sort<T> sort = default,
|
||||
Pagination limit = default) where T : class, IResource;
|
||||
Pagination limit = default)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Get all resources with filters
|
||||
@ -488,7 +495,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <returns>A list of resources that match every filters</returns>
|
||||
Task<ICollection<T>> GetAll<T>([Optional] Expression<Func<T, bool>> where,
|
||||
Expression<Func<T, object>> sort,
|
||||
Pagination limit = default) where T : class, IResource
|
||||
Pagination limit = default)
|
||||
where T : class, IResource
|
||||
{
|
||||
return GetAll(where, new Sort<T>(sort), limit);
|
||||
}
|
||||
@ -499,7 +507,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <param name="where">A filter function</param>
|
||||
/// <typeparam name="T">The type of resources to load</typeparam>
|
||||
/// <returns>A list of resources that match every filters</returns>
|
||||
Task<int> GetCount<T>(Expression<Func<T, bool>> where = null) where T : class, IResource;
|
||||
Task<int> GetCount<T>(Expression<Func<T, bool>> where = null)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Search for a resource
|
||||
@ -507,15 +516,17 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <param name="query">The search query</param>
|
||||
/// <typeparam name="T">The type of resources</typeparam>
|
||||
/// <returns>A list of 20 items that match the search query</returns>
|
||||
Task<ICollection<T>> Search<T>(string query) where T : class, IResource;
|
||||
Task<ICollection<T>> Search<T>(string query)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new resource.
|
||||
/// </summary>
|
||||
/// <param name="item">The item to register</param>
|
||||
/// <typeparam name="T">The type of resource</typeparam>
|
||||
/// <returns>The resource registers and completed by database's informations (related items & so on)</returns>
|
||||
Task<T> Create<T>([NotNull] T item) where T : class, IResource;
|
||||
/// <returns>The resource registers and completed by database's information (related items & so on)</returns>
|
||||
Task<T> Create<T>([NotNull] T item)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new resource if it does not exist already. If it does, the existing value is returned instead.
|
||||
@ -523,17 +534,19 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <param name="item">The item to register</param>
|
||||
/// <typeparam name="T">The type of resource</typeparam>
|
||||
/// <returns>The newly created item or the existing value if it existed.</returns>
|
||||
Task<T> CreateIfNotExists<T>([NotNull] T item) where T : class, IResource;
|
||||
Task<T> CreateIfNotExists<T>([NotNull] T item)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Edit a resource
|
||||
/// </summary>
|
||||
/// <param name="item">The resourcce to edit, it's ID can't change.</param>
|
||||
/// <param name="item">The resource to edit, it's ID can't change.</param>
|
||||
/// <param name="resetOld">Should old properties of the resource be discarded or should null values considered as not changed?</param>
|
||||
/// <typeparam name="T">The type of resources</typeparam>
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
/// <returns>The resource edited and completed by database's informations (related items & so on)</returns>
|
||||
Task<T> Edit<T>(T item, bool resetOld) where T : class, IResource;
|
||||
/// <returns>The resource edited and completed by database's information (related items & so on)</returns>
|
||||
Task<T> Edit<T>(T item, bool resetOld)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Delete a resource.
|
||||
@ -541,7 +554,9 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <param name="item">The resource to delete</param>
|
||||
/// <typeparam name="T">The type of resource to delete</typeparam>
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
Task Delete<T>(T item) where T : class, IResource;
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task Delete<T>(T item)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Delete a resource by it's ID.
|
||||
@ -549,7 +564,9 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <param name="id">The id of the resource to delete</param>
|
||||
/// <typeparam name="T">The type of resource to delete</typeparam>
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
Task Delete<T>(int id) where T : class, IResource;
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task Delete<T>(int id)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
/// Delete a resource by it's slug.
|
||||
@ -557,6 +574,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <param name="slug">The slug of the resource to delete</param>
|
||||
/// <typeparam name="T">The type of resource to delete</typeparam>
|
||||
/// <exception cref="ItemNotFoundException">If the item is not found</exception>
|
||||
Task Delete<T>(string slug) where T : class, IResource;
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task Delete<T>(string slug)
|
||||
where T : class, IResource;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using Kyoo.Abstractions.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Abstractions.Models;
|
||||
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
@ -30,6 +30,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// Merging metadata is the job of Kyoo, a complex <typeparamref name="T"/> is given
|
||||
/// to make a precise search and give you every available properties, not to discard properties.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The type of resource to retrieve metadata for.</typeparam>
|
||||
/// <returns>A new <typeparamref name="T"/> containing metadata from your provider or null</returns>
|
||||
[ItemCanBeNull]
|
||||
Task<T> Get<T>([NotNull] T item)
|
||||
@ -39,6 +40,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// Search for a specific type of items with a given query.
|
||||
/// </summary>
|
||||
/// <param name="query">The search query to use.</param>
|
||||
/// <typeparam name="T">The type of resource to search metadata for.</typeparam>
|
||||
/// <returns>The list of items that could be found on this specific provider.</returns>
|
||||
[ItemNotNull]
|
||||
Task<ICollection<T>> Search<T>(string query)
|
||||
@ -62,7 +64,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
|
||||
/// <summary>
|
||||
/// Since this is a composite and not a real provider, no metadata is available.
|
||||
/// It is not meant to be stored or selected. This class will handle merge based on what is required.
|
||||
/// It is not meant to be stored or selected. This class will handle merge based on what is required.
|
||||
/// </summary>
|
||||
public Provider Provider => null;
|
||||
|
||||
|
29
Kyoo.Abstractions/Controllers/IPermissionValidator.cs
Normal file
29
Kyoo.Abstractions/Controllers/IPermissionValidator.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Kyoo.Abstractions.Models.Permissions;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace Kyoo.Abstractions.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// A service to validate permissions.
|
||||
/// </summary>
|
||||
public interface IPermissionValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an IAuthorizationFilter that will be used to validate permissions.
|
||||
/// This can registered with any lifetime.
|
||||
/// </summary>
|
||||
/// <param name="attribute">The permission attribute to validate.</param>
|
||||
/// <returns>An authorization filter used to validate the permission.</returns>
|
||||
IFilterMetadata Create(PermissionAttribute attribute);
|
||||
|
||||
/// <summary>
|
||||
/// Create an IAuthorizationFilter that will be used to validate permissions.
|
||||
/// This can registered with any lifetime.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// A partial attribute to validate. See <see cref="PartialPermissionAttribute"/>.
|
||||
/// </param>
|
||||
/// <returns>An authorization filter used to validate the permission.</returns>
|
||||
IFilterMetadata Create(PartialPermissionAttribute attribute);
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <c>true</c> if the plugin should be enabled, <c>false</c> otherwise.
|
||||
/// If a plugin is not enabled, no configure method will be called.
|
||||
/// This allow one to enable a plugin if a specific configuration value is set or if the environment contains
|
||||
/// the right settings.
|
||||
/// the right settings.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default, a plugin is always enabled. This method can be overriden to change this behavior.
|
||||
|
@ -19,8 +19,9 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// The count of items to return.
|
||||
/// </summary>
|
||||
public int Count { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Where to start? Using the given sort
|
||||
/// Where to start? Using the given sort.
|
||||
/// </summary>
|
||||
public int AfterID { get; }
|
||||
|
||||
@ -53,6 +54,7 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// The sort key. This member will be used to sort the results.
|
||||
/// </summary>
|
||||
public Expression<Func<T, object>> Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// If this is set to true, items will be sorted in descend order else, they will be sorted in ascendant order.
|
||||
/// </summary>
|
||||
@ -121,7 +123,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// A common repository for every resources.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The resource's type that this repository manage.</typeparam>
|
||||
public interface IRepository<T> : IBaseRepository where T : class, IResource
|
||||
public interface IRepository<T> : IBaseRepository
|
||||
where T : class, IResource
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a resource from it's ID.
|
||||
|
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Permissions
|
||||
{
|
||||
/// <summary>
|
||||
/// Specify one part of a permissions needed for the API (the kind or the type).
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class PartialPermissionAttribute : Attribute, IFilterFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The needed permission type.
|
||||
/// </summary>
|
||||
public string Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The needed permission kind.
|
||||
/// </summary>
|
||||
public Kind Kind { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ask a permission to run an action.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// With this attribute, you can only specify a type or a kind.
|
||||
/// To have a valid permission attribute, you must specify the kind and the permission using two attributes.
|
||||
/// Those attributes can be dispatched at different places (one on the class, one on the method for example).
|
||||
/// If you don't put exactly two of those attributes, the permission attribute will be ill-formed and will
|
||||
/// lead to unspecified behaviors.
|
||||
/// </remarks>
|
||||
/// <param name="type">
|
||||
/// The type of the action
|
||||
/// (if the type ends with api, it will be removed. This allow you to use nameof(YourApi)).
|
||||
/// </param>
|
||||
public PartialPermissionAttribute(string type)
|
||||
{
|
||||
if (type.EndsWith("API", StringComparison.OrdinalIgnoreCase))
|
||||
type = type[..^3];
|
||||
Type = type.ToLower();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ask a permission to run an action.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// With this attribute, you can only specify a type or a kind.
|
||||
/// To have a valid permission attribute, you must specify the kind and the permission using two attributes.
|
||||
/// Those attributes can be dispatched at different places (one on the class, one on the method for example).
|
||||
/// If you don't put exactly two of those attributes, the permission attribute will be ill-formed and will
|
||||
/// lead to unspecified behaviors.
|
||||
/// </remarks>
|
||||
/// <param name="permission">The kind of permission needed.</param>
|
||||
public PartialPermissionAttribute(Kind permission)
|
||||
{
|
||||
Kind = permission;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
|
||||
{
|
||||
return serviceProvider.GetRequiredService<IPermissionValidator>().Create(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsReusable => true;
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Permissions
|
||||
{
|
||||
/// <summary>
|
||||
/// The kind of permission needed.
|
||||
/// </summary>
|
||||
public enum Kind
|
||||
{
|
||||
/// <summary>
|
||||
/// Allow the user to read for this kind of data.
|
||||
/// </summary>
|
||||
Read,
|
||||
|
||||
/// <summary>
|
||||
/// Allow the user to write for this kind of data.
|
||||
/// </summary>
|
||||
Write,
|
||||
|
||||
/// <summary>
|
||||
/// Allow the user to create this kind of data.
|
||||
/// </summary>
|
||||
Create,
|
||||
|
||||
/// <summary>
|
||||
/// Allow the user to delete this kind od data.
|
||||
/// </summary>
|
||||
Delete
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The group of the permission.
|
||||
/// </summary>
|
||||
public enum Group
|
||||
{
|
||||
/// <summary>
|
||||
/// Allow all operations on basic items types.
|
||||
/// </summary>
|
||||
Overall,
|
||||
|
||||
/// <summary>
|
||||
/// Allow operation on sensitive items like libraries path, configurations and so on.
|
||||
/// </summary>
|
||||
Admin
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify permissions needed for the API.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class PermissionAttribute : Attribute, IFilterFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The needed permission as string.
|
||||
/// </summary>
|
||||
public string Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The needed permission kind.
|
||||
/// </summary>
|
||||
public Kind Kind { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The group of this permission.
|
||||
/// </summary>
|
||||
public Group Group { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ask a permission to run an action.
|
||||
/// </summary>
|
||||
/// <param name="type">
|
||||
/// The type of the action
|
||||
/// (if the type ends with api, it will be removed. This allow you to use nameof(YourApi)).
|
||||
/// </param>
|
||||
/// <param name="permission">The kind of permission needed.</param>
|
||||
/// <param name="group">
|
||||
/// The group of this permission (allow grouped permission like overall.read
|
||||
/// for all read permissions of this group).
|
||||
/// </param>
|
||||
public PermissionAttribute(string type, Kind permission, Group group = Group.Overall)
|
||||
{
|
||||
if (type.EndsWith("API", StringComparison.OrdinalIgnoreCase))
|
||||
type = type[..^3];
|
||||
Type = type.ToLower();
|
||||
Kind = permission;
|
||||
Group = group;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
|
||||
{
|
||||
return serviceProvider.GetRequiredService<IPermissionValidator>().Create(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsReusable => true;
|
||||
|
||||
/// <summary>
|
||||
/// Return this permission attribute as a string.
|
||||
/// </summary>
|
||||
/// <returns>The string representation.</returns>
|
||||
public string AsPermissionString()
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,172 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Abstractions.Models.Permissions
|
||||
{
|
||||
/// <summary>
|
||||
/// The kind of permission needed.
|
||||
/// </summary>
|
||||
public enum Kind
|
||||
{
|
||||
Read,
|
||||
Write,
|
||||
Create,
|
||||
Delete
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The group of the permission.
|
||||
/// </summary>
|
||||
public enum Group
|
||||
{
|
||||
Overall,
|
||||
Admin
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify permissions needed for the API.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class PermissionAttribute : Attribute, IFilterFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The needed permission as string.
|
||||
/// </summary>
|
||||
public string Type { get; }
|
||||
/// <summary>
|
||||
/// The needed permission kind.
|
||||
/// </summary>
|
||||
public Kind Kind { get; }
|
||||
/// <summary>
|
||||
/// The group of this permission
|
||||
/// </summary>
|
||||
public Group Group { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ask a permission to run an action.
|
||||
/// </summary>
|
||||
/// <param name="type">
|
||||
/// The type of the action
|
||||
/// (if the type ends with api, it will be removed. This allow you to use nameof(YourApi)).
|
||||
/// </param>
|
||||
/// <param name="permission">The kind of permission needed</param>
|
||||
/// <param name="group">
|
||||
/// The group of this permission (allow grouped permission like overall.read
|
||||
/// for all read permissions of this group)
|
||||
/// </param>
|
||||
public PermissionAttribute(string type, Kind permission, Group group = Group.Overall)
|
||||
{
|
||||
if (type.EndsWith("API", StringComparison.OrdinalIgnoreCase))
|
||||
type = type[..^3];
|
||||
Type = type.ToLower();
|
||||
Kind = permission;
|
||||
Group = group;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
|
||||
{
|
||||
return serviceProvider.GetRequiredService<IPermissionValidator>().Create(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsReusable => true;
|
||||
|
||||
/// <summary>
|
||||
/// Return this permission attribute as a string
|
||||
/// </summary>
|
||||
/// <returns>The string representation.</returns>
|
||||
public string AsPermissionString()
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify one part of a permissions needed for the API (the kind or the type).
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class PartialPermissionAttribute : Attribute, IFilterFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The needed permission type.
|
||||
/// </summary>
|
||||
public string Type { get; }
|
||||
/// <summary>
|
||||
/// The needed permission kind.
|
||||
/// </summary>
|
||||
public Kind Kind { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ask a permission to run an action.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// With this attribute, you can only specify a type or a kind.
|
||||
/// To have a valid permission attribute, you must specify the kind and the permission using two attributes.
|
||||
/// Those attributes can be dispatched at different places (one on the class, one on the method for example).
|
||||
/// If you don't put exactly two of those attributes, the permission attribute will be ill-formed and will
|
||||
/// lead to unspecified behaviors.
|
||||
/// </remarks>
|
||||
/// <param name="type">
|
||||
/// The type of the action
|
||||
/// (if the type ends with api, it will be removed. This allow you to use nameof(YourApi)).
|
||||
/// </param>
|
||||
public PartialPermissionAttribute(string type)
|
||||
{
|
||||
if (type.EndsWith("API", StringComparison.OrdinalIgnoreCase))
|
||||
type = type[..^3];
|
||||
Type = type.ToLower();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ask a permission to run an action.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// With this attribute, you can only specify a type or a kind.
|
||||
/// To have a valid permission attribute, you must specify the kind and the permission using two attributes.
|
||||
/// Those attributes can be dispatched at different places (one on the class, one on the method for example).
|
||||
/// If you don't put exactly two of those attributes, the permission attribute will be ill-formed and will
|
||||
/// lead to unspecified behaviors.
|
||||
/// </remarks>
|
||||
/// <param name="permission">The kind of permission needed</param>
|
||||
public PartialPermissionAttribute(Kind permission)
|
||||
{
|
||||
Kind = permission;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
|
||||
{
|
||||
return serviceProvider.GetRequiredService<IPermissionValidator>().Create(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsReusable => true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A service to validate permissions
|
||||
/// </summary>
|
||||
public interface IPermissionValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an IAuthorizationFilter that will be used to validate permissions.
|
||||
/// This can registered with any lifetime.
|
||||
/// </summary>
|
||||
/// <param name="attribute">The permission attribute to validate</param>
|
||||
/// <returns>An authorization filter used to validate the permission</returns>
|
||||
IFilterMetadata Create(PermissionAttribute attribute);
|
||||
|
||||
/// <summary>
|
||||
/// Create an IAuthorizationFilter that will be used to validate permissions.
|
||||
/// This can registered with any lifetime.
|
||||
/// </summary>
|
||||
/// <param name="attribute">
|
||||
/// A partial attribute to validate. See <see cref="PartialPermissionAttribute"/>.
|
||||
/// </param>
|
||||
/// <returns>An authorization filter used to validate the permission</returns>
|
||||
IFilterMetadata Create(PartialPermissionAttribute attribute);
|
||||
}
|
||||
}
|
@ -50,7 +50,7 @@ namespace Kyoo.Abstractions.Models
|
||||
public string TrailerUrl => Images?.GetValueOrDefault(Models.Images.Trailer);
|
||||
|
||||
/// <summary>
|
||||
/// The date this show started airing. It can be null if this is unknown.
|
||||
/// The date this show started airing. It can be null if this is unknown.
|
||||
/// </summary>
|
||||
public DateTime? StartAir { get; set; }
|
||||
|
||||
@ -103,6 +103,7 @@ namespace Kyoo.Abstractions.Models
|
||||
/// The ID of the Studio that made this show.
|
||||
/// </summary>
|
||||
[SerializeIgnore] public int? StudioID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Studio that made this show.
|
||||
/// This must be explicitly loaded via a call to <see cref="ILibraryManager.Load"/>.
|
||||
@ -145,19 +146,48 @@ namespace Kyoo.Abstractions.Models
|
||||
public void OnMerge(object merged)
|
||||
{
|
||||
if (People != null)
|
||||
{
|
||||
foreach (PeopleRole link in People)
|
||||
link.Show = this;
|
||||
}
|
||||
|
||||
if (Seasons != null)
|
||||
{
|
||||
foreach (Season season in Seasons)
|
||||
season.Show = this;
|
||||
}
|
||||
|
||||
if (Episodes != null)
|
||||
{
|
||||
foreach (Episode episode in Episodes)
|
||||
episode.Show = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The enum containing show's status.
|
||||
/// </summary>
|
||||
public enum Status { Unknown, Finished, Airing, Planned }
|
||||
public enum Status
|
||||
{
|
||||
/// <summary>
|
||||
/// The status of the show is not known.
|
||||
/// </summary>
|
||||
Unknown,
|
||||
|
||||
/// <summary>
|
||||
/// The show has finished airing.
|
||||
/// </summary>
|
||||
Finished,
|
||||
|
||||
/// <summary>
|
||||
/// The show is still actively airing.
|
||||
/// </summary>
|
||||
Airing,
|
||||
|
||||
/// <summary>
|
||||
/// This show has not aired yet but has been announced.
|
||||
/// </summary>
|
||||
Planned
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ namespace Kyoo.Authentication
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterType<PermissionValidatorFactory>().As<IPermissionValidator>().SingleInstance();
|
||||
builder.RegisterType<PermissionValidator>().As<IPermissionValidator>().SingleInstance();
|
||||
|
||||
DefaultCorsPolicyService cors = new(_logger)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Permissions;
|
||||
using Kyoo.Authentication.Models;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
@ -17,7 +18,7 @@ namespace Kyoo.Authentication
|
||||
/// A permission validator to validate permission with user Permission array
|
||||
/// or the default array from the configurations if the user is not logged.
|
||||
/// </summary>
|
||||
public class PermissionValidatorFactory : IPermissionValidator
|
||||
public class PermissionValidator : IPermissionValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// The permissions options to retrieve default permissions.
|
||||
@ -25,10 +26,10 @@ namespace Kyoo.Authentication
|
||||
private readonly IOptionsMonitor<PermissionOption> _options;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new factory with the given options
|
||||
/// Create a new factory with the given options.
|
||||
/// </summary>
|
||||
/// <param name="options">The option containing default values.</param>
|
||||
public PermissionValidatorFactory(IOptionsMonitor<PermissionOption> options)
|
||||
public PermissionValidator(IOptionsMonitor<PermissionOption> options)
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
@ -36,46 +37,49 @@ namespace Kyoo.Authentication
|
||||
/// <inheritdoc />
|
||||
public IFilterMetadata Create(PermissionAttribute attribute)
|
||||
{
|
||||
return new PermissionValidator(attribute.Type, attribute.Kind, attribute.Group, _options);
|
||||
return new PermissionValidatorFilter(attribute.Type, attribute.Kind, attribute.Group, _options);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IFilterMetadata Create(PartialPermissionAttribute attribute)
|
||||
{
|
||||
return new PermissionValidator((object)attribute.Type ?? attribute.Kind, _options);
|
||||
return new PermissionValidatorFilter((object)attribute.Type ?? attribute.Kind, _options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The authorization filter used by <see cref="PermissionValidatorFactory"/>
|
||||
/// The authorization filter used by <see cref="PermissionValidator"/>.
|
||||
/// </summary>
|
||||
private class PermissionValidator : IAsyncAuthorizationFilter
|
||||
private class PermissionValidatorFilter : IAsyncAuthorizationFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// The permission to validate
|
||||
/// The permission to validate.
|
||||
/// </summary>
|
||||
private readonly string _permission;
|
||||
|
||||
/// <summary>
|
||||
/// The kind of permission needed
|
||||
/// The kind of permission needed.
|
||||
/// </summary>
|
||||
private readonly Kind? _kind;
|
||||
|
||||
/// <summary>
|
||||
/// The group of he permission
|
||||
/// The group of he permission.
|
||||
/// </summary>
|
||||
private readonly Group _group = Group.Overall;
|
||||
|
||||
/// <summary>
|
||||
/// The permissions options to retrieve default permissions.
|
||||
/// </summary>
|
||||
private readonly IOptionsMonitor<PermissionOption> _options;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new permission validator with the given options
|
||||
/// Create a new permission validator with the given options.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to validate</param>
|
||||
/// <param name="kind">The kind of permission needed</param>
|
||||
/// <param name="group">The group of the permission</param>
|
||||
/// <param name="permission">The permission to validate.</param>
|
||||
/// <param name="kind">The kind of permission needed.</param>
|
||||
/// <param name="group">The group of the permission.</param>
|
||||
/// <param name="options">The option containing default values.</param>
|
||||
public PermissionValidator(string permission, Kind kind, Group group, IOptionsMonitor<PermissionOption> options)
|
||||
public PermissionValidatorFilter(string permission, Kind kind, Group group,
|
||||
IOptionsMonitor<PermissionOption> options)
|
||||
{
|
||||
_permission = permission;
|
||||
_kind = kind;
|
||||
@ -84,11 +88,11 @@ namespace Kyoo.Authentication
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new permission validator with the given options
|
||||
/// Create a new permission validator with the given options.
|
||||
/// </summary>
|
||||
/// <param name="partialInfo">The partial permission to validate</param>
|
||||
/// <param name="partialInfo">The partial permission to validate.</param>
|
||||
/// <param name="options">The option containing default values.</param>
|
||||
public PermissionValidator(object partialInfo, IOptionsMonitor<PermissionOption> options)
|
||||
public PermissionValidatorFilter(object partialInfo, IOptionsMonitor<PermissionOption> options)
|
||||
{
|
||||
if (partialInfo is Kind kind)
|
||||
_kind = kind;
|
||||
@ -99,7 +103,6 @@ namespace Kyoo.Authentication
|
||||
_options = options;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||
{
|
||||
@ -127,8 +130,10 @@ namespace Kyoo.Authentication
|
||||
"are not supported.");
|
||||
}
|
||||
if (permission == null || kind == null)
|
||||
{
|
||||
throw new ArgumentException("The permission type or kind is still missing after two partial " +
|
||||
"permission attributes, this is unsupported.");
|
||||
}
|
||||
}
|
||||
|
||||
string permStr = $"{permission.ToLower()}.{kind.ToString()!.ToLower()}";
|
@ -1,3 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models.Permissions;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@ -9,7 +11,8 @@ namespace Kyoo.Core.Controllers
|
||||
/// </summary>
|
||||
public class PassthroughPermissionValidator : IPermissionValidator
|
||||
{
|
||||
// ReSharper disable once SuggestBaseTypeForParameter
|
||||
[SuppressMessage("ReSharper", "SuggestBaseTypeForParameterInConstructor",
|
||||
Justification = "ILogger should include the typeparam for context.")]
|
||||
public PassthroughPermissionValidator(ILogger<PassthroughPermissionValidator> logger)
|
||||
{
|
||||
logger.LogWarning("No permission validator has been enabled, all users will have all permissions");
|
||||
@ -28,8 +31,8 @@ namespace Kyoo.Core.Controllers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An useless filter that does nothing.
|
||||
/// An useless filter that does nothing.
|
||||
/// </summary>
|
||||
private class PassthroughValidator : IFilterMetadata { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,9 +41,9 @@ namespace Kyoo.Core.Api
|
||||
}
|
||||
|
||||
|
||||
// TODO enable the following line, this is disabled since the web app can't use bearers. [Permission("video", Kind.Read)]
|
||||
[HttpGet("{slug}")]
|
||||
[HttpGet("direct/{slug}")]
|
||||
// TODO enable the following line, this is disabled since the web app can't use bearers. [Permission("video", Kind.Read)]
|
||||
public async Task<IActionResult> Direct(string slug)
|
||||
{
|
||||
try
|
||||
@ -114,4 +114,4 @@ namespace Kyoo.Core.Api
|
||||
return PhysicalFile(path, "video/MP2T");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,38 +26,47 @@ namespace Kyoo.Database
|
||||
/// All libraries of Kyoo. See <see cref="Library"/>.
|
||||
/// </summary>
|
||||
public DbSet<Library> Libraries { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All collections of Kyoo. See <see cref="Collection"/>.
|
||||
/// </summary>
|
||||
public DbSet<Collection> Collections { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All shows of Kyoo. See <see cref="Show"/>.
|
||||
/// </summary>
|
||||
public DbSet<Show> Shows { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All seasons of Kyoo. See <see cref="Season"/>.
|
||||
/// </summary>
|
||||
public DbSet<Season> Seasons { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All episodes of Kyoo. See <see cref="Episode"/>.
|
||||
/// </summary>
|
||||
public DbSet<Episode> Episodes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All tracks of Kyoo. See <see cref="Track"/>.
|
||||
/// </summary>
|
||||
public DbSet<Track> Tracks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All genres of Kyoo. See <see cref="Genres"/>.
|
||||
/// </summary>
|
||||
public DbSet<Genre> Genres { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All people of Kyoo. See <see cref="People"/>.
|
||||
/// </summary>
|
||||
public DbSet<People> People { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All studios of Kyoo. See <see cref="Studio"/>.
|
||||
/// </summary>
|
||||
public DbSet<Studio> Studios { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All providers of Kyoo. See <see cref="Provider"/>.
|
||||
/// </summary>
|
||||
@ -74,12 +83,12 @@ namespace Kyoo.Database
|
||||
public DbSet<PeopleRole> PeopleRoles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Episodes with a watch percentage. See <see cref="WatchedEpisode"/>
|
||||
/// Episodes with a watch percentage. See <see cref="WatchedEpisode"/>.
|
||||
/// </summary>
|
||||
public DbSet<WatchedEpisode> WatchedEpisodes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of library items (shows and collections that are part of a library - or the global one)
|
||||
/// The list of library items (shows and collections that are part of a library - or the global one).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This set is ready only, on most database this will be a view.
|
||||
@ -471,7 +480,7 @@ namespace Kyoo.Database
|
||||
/// <exception cref="DuplicatedItemException">A duplicated item has been found.</exception>
|
||||
/// <returns>The number of state entries written to the database.</returns>
|
||||
public async Task<int> SaveChangesAsync(string duplicateMessage,
|
||||
CancellationToken cancellationToken = new())
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -492,7 +501,7 @@ namespace Kyoo.Database
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe while waiting for the task to complete</param>
|
||||
/// <returns>The number of state entries written to the database or -1 if a duplicate exist.</returns>
|
||||
public async Task<int> SaveIfNoDuplicates(CancellationToken cancellationToken = new())
|
||||
public async Task<int> SaveIfNoDuplicates(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -507,7 +516,7 @@ namespace Kyoo.Database
|
||||
/// <summary>
|
||||
/// Return the first resource with the given slug that is currently tracked by this context.
|
||||
/// This allow one to limit redundant calls to <see cref="IRepository{T}.CreateIfNotExists"/> during the
|
||||
/// same transaction and prevent fails from EF when two same entities are being tracked.
|
||||
/// same transaction and prevent fails from EF when two same entities are being tracked.
|
||||
/// </summary>
|
||||
/// <param name="slug">The slug of the resource to check</param>
|
||||
/// <typeparam name="T">The type of entity to check</typeparam>
|
||||
@ -548,4 +557,4 @@ namespace Kyoo.Database
|
||||
/// <returns>An expression representing the like query. It can directly be passed to a where call.</returns>
|
||||
public abstract Expression<Func<T, bool>> Like<T>(Expression<Func<T, string>> query, string format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ namespace Kyoo.TheMovieDb
|
||||
/// The API key used to authenticate with TheMovieDb API.
|
||||
/// </summary>
|
||||
private readonly IOptions<TheMovieDbOptions> _apiKey;
|
||||
|
||||
/// <summary>
|
||||
/// The logger to use in ase of issue.
|
||||
/// </summary>
|
||||
@ -43,7 +44,7 @@ namespace Kyoo.TheMovieDb
|
||||
/// <summary>
|
||||
/// Create a new <see cref="TheMovieDbProvider"/> using the given api key.
|
||||
/// </summary>
|
||||
/// <param name="apiKey">The api key</param>
|
||||
/// <param name="apiKey">The api key.</param>
|
||||
/// <param name="logger">The logger to use in case of issue.</param>
|
||||
public TheMovieDbProvider(IOptions<TheMovieDbOptions> apiKey, ILogger<TheMovieDbProvider> logger)
|
||||
{
|
||||
@ -51,7 +52,6 @@ namespace Kyoo.TheMovieDb
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<T> Get<T>(T item)
|
||||
where T : class, IResource
|
||||
@ -71,8 +71,8 @@ namespace Kyoo.TheMovieDb
|
||||
/// <summary>
|
||||
/// Get a collection using it's id, if the id is not present in the collection, fallback to a name search.
|
||||
/// </summary>
|
||||
/// <param name="collection">The collection to search for</param>
|
||||
/// <returns>A collection containing metadata from TheMovieDb</returns>
|
||||
/// <param name="collection">The collection to search for.</param>
|
||||
/// <returns>A collection containing metadata from TheMovieDb.</returns>
|
||||
private async Task<Collection> _GetCollection(Collection collection)
|
||||
{
|
||||
if (!collection.TryGetID(Provider.Slug, out int id))
|
||||
@ -89,8 +89,8 @@ namespace Kyoo.TheMovieDb
|
||||
/// <summary>
|
||||
/// Get a show using it's id, if the id is not present in the show, fallback to a title search.
|
||||
/// </summary>
|
||||
/// <param name="show">The show to search for</param>
|
||||
/// <returns>A show containing metadata from TheMovieDb</returns>
|
||||
/// <param name="show">The show to search for.</param>
|
||||
/// <returns>A show containing metadata from TheMovieDb.</returns>
|
||||
private async Task<Show> _GetShow(Show show)
|
||||
{
|
||||
if (!show.TryGetID(Provider.Slug, out int id))
|
||||
@ -119,7 +119,7 @@ namespace Kyoo.TheMovieDb
|
||||
/// Get a season using it's show and it's season number.
|
||||
/// </summary>
|
||||
/// <param name="season">The season to retrieve metadata for.</param>
|
||||
/// <returns>A season containing metadata from TheMovieDb</returns>
|
||||
/// <returns>A season containing metadata from TheMovieDb.</returns>
|
||||
private async Task<Season> _GetSeason(Season season)
|
||||
{
|
||||
if (season.Show == null)
|
||||
@ -139,10 +139,10 @@ namespace Kyoo.TheMovieDb
|
||||
|
||||
/// <summary>
|
||||
/// Get an episode using it's show, it's season number and it's episode number.
|
||||
/// Absolute numbering is not supported.
|
||||
/// Absolute numbering is not supported.
|
||||
/// </summary>
|
||||
/// <param name="episode">The episode to retrieve metadata for.</param>
|
||||
/// <returns>An episode containing metadata from TheMovieDb</returns>
|
||||
/// <returns>An episode containing metadata from TheMovieDb.</returns>
|
||||
private async Task<Episode> _GetEpisode(Episode episode)
|
||||
{
|
||||
if (episode.Show == null)
|
||||
@ -163,8 +163,8 @@ namespace Kyoo.TheMovieDb
|
||||
/// <summary>
|
||||
/// Get a person using it's id, if the id is not present in the person, fallback to a name search.
|
||||
/// </summary>
|
||||
/// <param name="person">The person to search for</param>
|
||||
/// <returns>A person containing metadata from TheMovieDb</returns>
|
||||
/// <param name="person">The person to search for.</param>
|
||||
/// <returns>A person containing metadata from TheMovieDb.</returns>
|
||||
private async Task<People> _GetPerson(People person)
|
||||
{
|
||||
if (!person.TryGetID(Provider.Slug, out int id))
|
||||
@ -181,8 +181,8 @@ namespace Kyoo.TheMovieDb
|
||||
/// <summary>
|
||||
/// Get a studio using it's id, if the id is not present in the studio, fallback to a name search.
|
||||
/// </summary>
|
||||
/// <param name="studio">The studio to search for</param>
|
||||
/// <returns>A studio containing metadata from TheMovieDb</returns>
|
||||
/// <param name="studio">The studio to search for.</param>
|
||||
/// <returns>A studio containing metadata from TheMovieDb.</returns>
|
||||
private async Task<Studio> _GetStudio(Studio studio)
|
||||
{
|
||||
if (!studio.TryGetID(Provider.Slug, out int id))
|
||||
@ -277,4 +277,4 @@ namespace Kyoo.TheMovieDb
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
Kyoo.ruleset
12
Kyoo.ruleset
@ -3,6 +3,10 @@
|
||||
<Rule Id="SA1413" Action="None" /> <!-- UseTrailingCommasInMultiLineInitializers -->
|
||||
<Rule Id="SA1414" Action="None" /> <!-- UseTrailingCommasInMultiLineInitializers -->
|
||||
</Rules>
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.OrderingRules">
|
||||
<Rule Id="SA1201" Action="None" /> <!-- ElementsMustAppearInTheCorrectOrder -->
|
||||
<Rule Id="SA1202" Action="None" /> <!-- ElementsMustBeOrderedByAccess -->
|
||||
</Rules>
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.NamingRules">
|
||||
<Rule Id="SA1309" Action="None" /> <!-- FieldNamesMustNotBeginWithUnderscore -->
|
||||
<Rule Id="SX1309" Action="Warning" /> <!-- FieldNamesMustBeginWithUnderscore -->
|
||||
@ -11,13 +15,20 @@
|
||||
<Rule Id="SA1101" Action="None" /> <!-- PrefixLocalCallsWithThis -->
|
||||
<Rule Id="SX1101" Action="Warning" /> <!-- DoNotPrefixLocalMembersWithThis -->
|
||||
<Rule Id="SA1134" Action="None" /> <!-- AttributesMustNotShareLine -->
|
||||
<Rule Id="SA1117" Action="None" /> <!-- ParametersMustBeOnSameLineOrSeparateLines -->
|
||||
<Rule Id="SA1116" Action="None" /> <!-- SplitParametersMustStartOnLineAfterDeclaration -->
|
||||
<Rule Id="SA1111" Action="None" /> <!-- ClosingParenthesisMustBeOnLineOfLastParameter -->
|
||||
<Rule Id="SA1009" Action="None" /> <!-- ClosingParenthesisMustBeSpacedCorrectly (bugged if the parenthesis is on a line by iteself) -->
|
||||
</Rules>
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.SpacingRules">
|
||||
<Rule Id="SA1502" Action="None"/> <!-- DocumentationLinesMustBeginWithSingleSpace -->
|
||||
<Rule Id="SA1027" Action="None"/> <!-- UseTabsCorrectly (smarts tabs are broken). TODO find a way to enable smart tabs -->
|
||||
</Rules>
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.LayoutRules">
|
||||
<Rule Id="SA1503" Action="None"/> <!-- BracesMustNotBeOmitted -->
|
||||
<Rule Id="SA1520" Action="None"/> <!-- UseBracesConsistently -->
|
||||
<Rule Id="SA1515" Action="None"/> <!-- SingleLineCommentMustBePrecededByBlankLine -->
|
||||
<Rule Id="SA1513" Action="None"/> <!-- ClosingBraceMustBeFollowedByBlankLine -->
|
||||
</Rules>
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.CSharp.DocumentationRules">
|
||||
<Rule Id="SA1642" Action="None" /> <!-- ConstructorSummaryDocumentationMustBeginWithStandardText -->
|
||||
@ -27,5 +38,6 @@
|
||||
|
||||
|
||||
<Rule Id="SA1633" Action="None" /> <!-- FileMustHaveHeader TODO remove this, this is only temporary -->
|
||||
<Rule Id="SA1629" Action="None" /> <!-- DocumentationTextMustEndWithAPeriod TODO remove this, this is only temporary -->
|
||||
</Rules>
|
||||
</RuleSet>
|
||||
|
Loading…
x
Reference in New Issue
Block a user