diff --git a/Kyoo/Startup.cs b/Kyoo/Startup.cs index ff26f54e..196cf25d 100644 --- a/Kyoo/Startup.cs +++ b/Kyoo/Startup.cs @@ -1,5 +1,7 @@ using System; +using System.Net; using System.Reflection; +using System.Threading.Tasks; using Kyoo.Api; using Kyoo.Controllers; using Kyoo.Models; @@ -75,7 +77,30 @@ namespace Kyoo .AddInMemoryApiResources(IdentityContext.GetApis()) .AddAspNetIdentity() .AddProfileService() - .AddDeveloperSigningCredential(); + .AddDeveloperSigningCredential(); // TODO remove the developer signin + + services.ConfigureApplicationCookie(options => + { + options.Events.OnRedirectToAccessDenied = context => + { + context.Response.StatusCode = (int)HttpStatusCode.Forbidden; + return Task.CompletedTask; + }; + options.Events.OnRedirectToLogin = context => + { + context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; + return Task.CompletedTask; + }; + }); + + services.AddAuthorization(options => + { + options.AddPolicy("Read", policy => policy.RequireClaim("read")); + options.AddPolicy("Write", policy => policy.RequireClaim("write")); + options.AddPolicy("Play", policy => policy.RequireClaim("play")); + options.AddPolicy("Download", policy => policy.RequireClaim("download")); + options.AddPolicy("Admin", policy => policy.RequireClaim("admin")); + }); services.AddScoped(); services.AddScoped(); diff --git a/Kyoo/Views/API/AccountAPI.cs b/Kyoo/Views/API/AccountAPI.cs index 3dcbb94a..015915de 100644 --- a/Kyoo/Views/API/AccountAPI.cs +++ b/Kyoo/Views/API/AccountAPI.cs @@ -52,6 +52,12 @@ namespace Kyoo.Api private readonly UserManager _userManager; private readonly SignInManager _signInManager; private readonly string _picturePath; + + public Claim[] defaultClaims = + { + new Claim("read", ""), + new Claim("play", "") + }; // TODO should add this field on the server's configuration page. public AccountController(UserManager userManager, SignInManager siginInManager, IConfiguration configuration) { @@ -73,6 +79,7 @@ namespace Kyoo.Api return BadRequest(result.Errors); string otac = account.GenerateOTAC(TimeSpan.FromMinutes(1)); await _userManager.UpdateAsync(account); + await _userManager.AddClaimsAsync(account, defaultClaims); return Ok(otac); } @@ -118,7 +125,7 @@ namespace Kyoo.Api new Claim("username", user.UserName), new Claim("picture", $"api/account/picture/{user.UserName}") }; - + context.IssuedClaims.AddRange(claims); } } diff --git a/Kyoo/Views/API/AdminAPI.cs b/Kyoo/Views/API/AdminAPI.cs index ae8bc6cd..6e2af871 100644 --- a/Kyoo/Views/API/AdminAPI.cs +++ b/Kyoo/Views/API/AdminAPI.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using System.Threading; using Kyoo.Controllers; +using Microsoft.AspNetCore.Authorization; namespace Kyoo.Api { @@ -9,6 +10,7 @@ namespace Kyoo.Api public class AdminController : ControllerBase { [HttpGet("scan")] + [Authorize(Policy="Admin")] public IActionResult ScanLibrary([FromServices] ICrawler crawler) { // The crawler is destroyed before the completion of this task. diff --git a/Kyoo/Views/API/CollectionAPI.cs b/Kyoo/Views/API/CollectionAPI.cs index 7369a43c..f15ff86d 100644 --- a/Kyoo/Views/API/CollectionAPI.cs +++ b/Kyoo/Views/API/CollectionAPI.cs @@ -2,6 +2,7 @@ using Kyoo.Models; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; +using Microsoft.AspNetCore.Authorization; namespace Kyoo.Api { @@ -17,6 +18,7 @@ namespace Kyoo.Api } [HttpGet("{collectionSlug}")] + [Authorize(Policy="Read")] public ActionResult GetShows(string collectionSlug) { Collection collection = _libraryManager.GetCollection(collectionSlug); diff --git a/Kyoo/Views/API/EpisodesAPI.cs b/Kyoo/Views/API/EpisodesAPI.cs index b6801f94..d4fe7bd0 100644 --- a/Kyoo/Views/API/EpisodesAPI.cs +++ b/Kyoo/Views/API/EpisodesAPI.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Linq; using Kyoo.Controllers; +using Microsoft.AspNetCore.Authorization; namespace Kyoo.Api { @@ -18,6 +19,7 @@ namespace Kyoo.Api } [HttpGet("{showSlug}/season/{seasonNumber}")] + [Authorize(Policy="Read")] public ActionResult> GetEpisodesForSeason(string showSlug, long seasonNumber) { IEnumerable episodes = _libraryManager.GetEpisodes(showSlug, seasonNumber); @@ -29,6 +31,7 @@ namespace Kyoo.Api } [HttpGet("{showSlug}/season/{seasonNumber}/episode/{episodeNumber}")] + [Authorize(Policy="Read")] [JsonDetailed] public ActionResult GetEpisode(string showSlug, long seasonNumber, long episodeNumber) { diff --git a/Kyoo/Views/API/PeopleAPI.cs b/Kyoo/Views/API/PeopleAPI.cs index 2061d0eb..274bcbfe 100644 --- a/Kyoo/Views/API/PeopleAPI.cs +++ b/Kyoo/Views/API/PeopleAPI.cs @@ -1,5 +1,6 @@ using Kyoo.Controllers; using Kyoo.Models; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Kyoo.Api @@ -16,6 +17,7 @@ namespace Kyoo.Api } [HttpGet("{peopleSlug}")] + [Authorize(Policy="Read")] public ActionResult GetPeople(string peopleSlug) { People people = _libraryManager.GetPeopleBySlug(peopleSlug); diff --git a/Kyoo/Views/API/SearchAPI.cs b/Kyoo/Views/API/SearchAPI.cs index ee7ac5e4..273dd6cd 100644 --- a/Kyoo/Views/API/SearchAPI.cs +++ b/Kyoo/Views/API/SearchAPI.cs @@ -1,5 +1,6 @@ using Kyoo.Controllers; using Kyoo.Models; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Kyoo.Api @@ -16,6 +17,7 @@ namespace Kyoo.Api } [HttpGet("{query}")] + [Authorize(Policy="Read")] public ActionResult Search(string query) { SearchResult result = new SearchResult diff --git a/Kyoo/Views/API/ShowsAPI.cs b/Kyoo/Views/API/ShowsAPI.cs index 2872e473..67913293 100644 --- a/Kyoo/Views/API/ShowsAPI.cs +++ b/Kyoo/Views/API/ShowsAPI.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using Kyoo.Controllers; +using Microsoft.AspNetCore.Authorization; namespace Kyoo.Api { @@ -18,12 +19,14 @@ namespace Kyoo.Api } [HttpGet] + [Authorize(Policy="Read")] public IEnumerable GetShows() { return _libraryManager.GetShows(); } [HttpGet("{slug}")] + [Authorize(Policy="Read")] [JsonDetailed] public ActionResult GetShow(string slug) { diff --git a/Kyoo/Views/API/SubtitleAPI.cs b/Kyoo/Views/API/SubtitleAPI.cs index d16435fa..5b279e5f 100644 --- a/Kyoo/Views/API/SubtitleAPI.cs +++ b/Kyoo/Views/API/SubtitleAPI.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Kyoo.Controllers; +using Microsoft.AspNetCore.Authorization; namespace Kyoo.Api { @@ -22,6 +23,7 @@ namespace Kyoo.Api } [HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}.{identifier}.{extension?}")] + [Authorize(Policy="Play")] public IActionResult GetSubtitle(string showSlug, int seasonNumber, int episodeNumber, string identifier, string extension) { string languageTag = identifier.Length == 3 ? identifier.Substring(0, 3) : null; @@ -57,6 +59,7 @@ namespace Kyoo.Api } [HttpGet("extract/{showSlug}-s{seasonNumber}e{episodeNumber}")] + [Authorize(Policy="Admin")] public async Task ExtractSubtitle(string showSlug, long seasonNumber, long episodeNumber) { Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber); @@ -73,6 +76,7 @@ namespace Kyoo.Api } [HttpGet("extract/{showSlug}")] + [Authorize(Policy="Admin")] public async Task ExtractSubtitle(string showSlug) { IEnumerable episodes = _libraryManager.GetEpisodes(showSlug); diff --git a/Kyoo/Views/API/ThumbnailAPI.cs b/Kyoo/Views/API/ThumbnailAPI.cs index 8943f9be..5aff643c 100644 --- a/Kyoo/Views/API/ThumbnailAPI.cs +++ b/Kyoo/Views/API/ThumbnailAPI.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.Configuration; using System.IO; using Kyoo.Controllers; +using Microsoft.AspNetCore.Authorization; namespace Kyoo.Api { @@ -18,6 +19,7 @@ namespace Kyoo.Api } [HttpGet("poster/{showSlug}")] + [Authorize(Policy="Read")] public IActionResult GetShowThumb(string showSlug) { string path = _libraryManager.GetShowBySlug(showSlug)?.Path; @@ -27,11 +29,12 @@ namespace Kyoo.Api string thumb = Path.Combine(path, "poster.jpg"); if (System.IO.File.Exists(thumb)) - return new PhysicalFileResult(thumb, "image/jpg"); + return new PhysicalFileResult(Path.GetFullPath(thumb), "image/jpg"); return NotFound(); } [HttpGet("logo/{showSlug}")] + [Authorize(Policy="Read")] public IActionResult GetShowLogo(string showSlug) { string path = _libraryManager.GetShowBySlug(showSlug)?.Path; @@ -41,11 +44,12 @@ namespace Kyoo.Api string thumb = Path.Combine(path, "logo.png"); if (System.IO.File.Exists(thumb)) - return new PhysicalFileResult(thumb, "image/jpg"); + return new PhysicalFileResult(Path.GetFullPath(thumb), "image/jpg"); return NotFound(); } [HttpGet("backdrop/{showSlug}")] + [Authorize(Policy="Read")] public IActionResult GetShowBackdrop(string showSlug) { string path = _libraryManager.GetShowBySlug(showSlug)?.Path; @@ -55,21 +59,23 @@ namespace Kyoo.Api string thumb = Path.Combine(path, "backdrop.jpg"); if (System.IO.File.Exists(thumb)) - return new PhysicalFileResult(thumb, "image/jpg"); + return new PhysicalFileResult(Path.GetFullPath(thumb), "image/jpg"); return NotFound(); } [HttpGet("peopleimg/{peopleSlug}")] + [Authorize(Policy="Read")] public IActionResult GetPeopleIcon(string peopleSlug) { string thumbPath = Path.Combine(_peoplePath, peopleSlug + ".jpg"); if (!System.IO.File.Exists(thumbPath)) return NotFound(); - return new PhysicalFileResult(thumbPath, "image/jpg"); + return new PhysicalFileResult(Path.GetFullPath(thumbPath), "image/jpg"); } [HttpGet("thumb/{showSlug}-s{seasonNumber}e{episodeNumber}")] + [Authorize(Policy="Read")] public IActionResult GetEpisodeThumb(string showSlug, long seasonNumber, long episodeNumber) { string path = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber)?.Path; @@ -79,7 +85,7 @@ namespace Kyoo.Api string thumb = Path.ChangeExtension(path, "jpg"); if (System.IO.File.Exists(thumb)) - return new PhysicalFileResult(thumb, "image/jpg"); + return new PhysicalFileResult(Path.GetFullPath(thumb), "image/jpg"); return NotFound(); } } diff --git a/Kyoo/Views/API/VideoAPI.cs b/Kyoo/Views/API/VideoAPI.cs index 57b833b5..8393095d 100644 --- a/Kyoo/Views/API/VideoAPI.cs +++ b/Kyoo/Views/API/VideoAPI.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using System.IO; using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; namespace Kyoo.Api { @@ -23,6 +24,7 @@ namespace Kyoo.Api } [HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}")] + [Authorize(Policy="Play")] public IActionResult Index(string showSlug, long seasonNumber, long episodeNumber) { WatchItem episode = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); @@ -33,6 +35,7 @@ namespace Kyoo.Api } [HttpGet("transmux/{showSlug}-s{seasonNumber}e{episodeNumber}")] + [Authorize(Policy="Play")] public async Task Transmux(string showSlug, long seasonNumber, long episodeNumber) { WatchItem episode = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); @@ -55,6 +58,7 @@ namespace Kyoo.Api } [HttpGet("transcode/{showSlug}-s{seasonNumber}e{episodeNumber}")] + [Authorize(Policy="Play")] public async Task Transcode(string showSlug, long seasonNumber, long episodeNumber) { WatchItem episode = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); @@ -69,6 +73,7 @@ namespace Kyoo.Api [HttpGet("{movieSlug}")] + [Authorize(Policy="Play")] public IActionResult Index(string movieSlug) { WatchItem episode = _libraryManager.GetMovieWatchItem(movieSlug); @@ -79,6 +84,7 @@ namespace Kyoo.Api } [HttpGet("transmux/{movieSlug}")] + [Authorize(Policy="Play")] public async Task Transmux(string movieSlug) { WatchItem episode = _libraryManager.GetMovieWatchItem(movieSlug); @@ -92,6 +98,7 @@ namespace Kyoo.Api } [HttpGet("transcode/{movieSlug}")] + [Authorize(Policy="Play")] public async Task Transcode(string movieSlug) { WatchItem episode = _libraryManager.GetMovieWatchItem(movieSlug); diff --git a/Kyoo/Views/API/WatchAPI.cs b/Kyoo/Views/API/WatchAPI.cs index b6569c87..6c04d74c 100644 --- a/Kyoo/Views/API/WatchAPI.cs +++ b/Kyoo/Views/API/WatchAPI.cs @@ -1,5 +1,6 @@ using Kyoo.Controllers; using Kyoo.Models; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Kyoo.Api @@ -16,6 +17,7 @@ namespace Kyoo.Api } [HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}")] + [Authorize(Policy="Read")] public ActionResult Index(string showSlug, long seasonNumber, long episodeNumber) { WatchItem item = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); @@ -27,6 +29,7 @@ namespace Kyoo.Api } [HttpGet("{movieSlug}")] + [Authorize(Policy="Read")] public ActionResult Index(string movieSlug) { WatchItem item = _libraryManager.GetMovieWatchItem(movieSlug); diff --git a/Kyoo/Views/WebClient b/Kyoo/Views/WebClient index 5d6a7cf3..04e92944 160000 --- a/Kyoo/Views/WebClient +++ b/Kyoo/Views/WebClient @@ -1 +1 @@ -Subproject commit 5d6a7cf319ce57dc5cf12a10e0195af5705b566f +Subproject commit 04e92944eeb2f5617834253d01ef312fee46e435