Adding authorization guards on the API

This commit is contained in:
Zoe Roux 2020-03-29 22:03:06 +02:00
parent f54dc6b282
commit 90cc54446a
13 changed files with 74 additions and 8 deletions

View File

@ -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<User>()
.AddProfileService<AccountController>()
.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<ILibraryManager, LibraryManager>();
services.AddScoped<ICrawler, Crawler>();

View File

@ -52,6 +52,12 @@ namespace Kyoo.Api
private readonly UserManager<User> _userManager;
private readonly SignInManager<User> _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<User> userManager, SignInManager<User> 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);
}
}

View File

@ -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.

View File

@ -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<Collection> GetShows(string collectionSlug)
{
Collection collection = _libraryManager.GetCollection(collectionSlug);

View File

@ -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<IEnumerable<Episode>> GetEpisodesForSeason(string showSlug, long seasonNumber)
{
IEnumerable<Episode> episodes = _libraryManager.GetEpisodes(showSlug, seasonNumber);
@ -29,6 +31,7 @@ namespace Kyoo.Api
}
[HttpGet("{showSlug}/season/{seasonNumber}/episode/{episodeNumber}")]
[Authorize(Policy="Read")]
[JsonDetailed]
public ActionResult<Episode> GetEpisode(string showSlug, long seasonNumber, long episodeNumber)
{

View File

@ -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<Collection> GetPeople(string peopleSlug)
{
People people = _libraryManager.GetPeopleBySlug(peopleSlug);

View File

@ -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<SearchResult> Search(string query)
{
SearchResult result = new SearchResult

View File

@ -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<Show> GetShows()
{
return _libraryManager.GetShows();
}
[HttpGet("{slug}")]
[Authorize(Policy="Read")]
[JsonDetailed]
public ActionResult<Show> GetShow(string slug)
{

View File

@ -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<string> 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<string> ExtractSubtitle(string showSlug)
{
IEnumerable<Episode> episodes = _libraryManager.GetEpisodes(showSlug);

View File

@ -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();
}
}

View File

@ -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<IActionResult> 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<IActionResult> 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<IActionResult> Transmux(string movieSlug)
{
WatchItem episode = _libraryManager.GetMovieWatchItem(movieSlug);
@ -92,6 +98,7 @@ namespace Kyoo.Api
}
[HttpGet("transcode/{movieSlug}")]
[Authorize(Policy="Play")]
public async Task<IActionResult> Transcode(string movieSlug)
{
WatchItem episode = _libraryManager.GetMovieWatchItem(movieSlug);

View File

@ -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<WatchItem> 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<WatchItem> Index(string movieSlug)
{
WatchItem item = _libraryManager.GetMovieWatchItem(movieSlug);

@ -1 +1 @@
Subproject commit 5d6a7cf319ce57dc5cf12a10e0195af5705b566f
Subproject commit 04e92944eeb2f5617834253d01ef312fee46e435