Read Only Account Changes + Fixes from last PR (#3453)
This commit is contained in:
parent
41c346d5e6
commit
a8144a1d3e
28 changed files with 193 additions and 38 deletions
|
|
@ -457,6 +457,7 @@ public class AccountController : BaseApiController
|
|||
{
|
||||
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());
|
||||
if (user == null) return Unauthorized(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
var isAdmin = await _unitOfWork.UserRepository.IsUserAdminAsync(user);
|
||||
if (!await _accountService.CanChangeAgeRestriction(user)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
|
@ -494,6 +495,7 @@ public class AccountController : BaseApiController
|
|||
var adminUser = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());
|
||||
if (adminUser == null) return Unauthorized();
|
||||
if (!await _unitOfWork.UserRepository.IsUserAdminAsync(adminUser)) return Unauthorized(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(dto.UserId, AppUserIncludes.SideNavStreams);
|
||||
if (user == null) return BadRequest(await _localizationService.Translate(User.GetUserId(), "no-user"));
|
||||
|
|
@ -911,7 +913,6 @@ public class AccountController : BaseApiController
|
|||
[EnableRateLimiting("Authentication")]
|
||||
public async Task<ActionResult<string>> ForgotPassword([FromQuery] string email)
|
||||
{
|
||||
|
||||
var settings = await _unitOfWork.SettingsRepository.GetSettingsDtoAsync();
|
||||
var user = await _unitOfWork.UserRepository.GetUserByEmailAsync(email);
|
||||
if (user == null)
|
||||
|
|
@ -1012,6 +1013,8 @@ public class AccountController : BaseApiController
|
|||
await _localizationService.Translate(user.Id, "user-migration-needed"));
|
||||
if (user.EmailConfirmed) return BadRequest(await _localizationService.Translate(user.Id, "user-already-confirmed"));
|
||||
|
||||
// TODO: If the target user is read only, we might want to just forgo this
|
||||
|
||||
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||
user.ConfirmationToken = token;
|
||||
_unitOfWork.UserRepository.Update(user);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using API.Constants;
|
||||
using API.DTOs.ReadingLists.CBL;
|
||||
using API.Extensions;
|
||||
using API.Services;
|
||||
|
|
@ -20,11 +21,13 @@ public class CblController : BaseApiController
|
|||
{
|
||||
private readonly IReadingListService _readingListService;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
|
||||
public CblController(IReadingListService readingListService, IDirectoryService directoryService)
|
||||
public CblController(IReadingListService readingListService, IDirectoryService directoryService, ILocalizationService localizationService)
|
||||
{
|
||||
_readingListService = readingListService;
|
||||
_directoryService = directoryService;
|
||||
_localizationService = localizationService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -91,6 +94,8 @@ public class CblController : BaseApiController
|
|||
[SwaggerIgnore]
|
||||
public async Task<ActionResult<CblImportSummaryDto>> ImportCbl(IFormFile cbl, [FromQuery] bool dryRun = false, [FromQuery] bool useComicVineMatching = false)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
try
|
||||
{
|
||||
var userId = User.GetUserId();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.Constants;
|
||||
using API.Data;
|
||||
using API.Data.Repositories;
|
||||
using API.DTOs;
|
||||
|
|
@ -58,6 +59,8 @@ public class ChapterController : BaseApiController
|
|||
[HttpDelete]
|
||||
public async Task<ActionResult<bool>> DeleteChapter(int chapterId)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
var chapter = await _unitOfWork.ChapterRepository.GetChapterAsync(chapterId);
|
||||
if (chapter == null)
|
||||
return BadRequest(_localizationService.Translate(User.GetUserId(), "chapter-doesnt-exist"));
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ public class CollectionController : BaseApiController
|
|||
[HttpPost("update")]
|
||||
public async Task<ActionResult> UpdateTag(AppUserCollectionDto updatedTag)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
try
|
||||
{
|
||||
if (await _collectionService.UpdateTag(updatedTag, User.GetUserId()))
|
||||
|
|
@ -130,6 +132,8 @@ public class CollectionController : BaseApiController
|
|||
[HttpPost("promote-multiple")]
|
||||
public async Task<ActionResult> PromoteMultipleCollections(PromoteCollectionsDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
// This needs to take into account owner as I can select other users cards
|
||||
var collections = await _unitOfWork.CollectionTagRepository.GetCollectionsByIds(dto.CollectionIds);
|
||||
var userId = User.GetUserId();
|
||||
|
|
@ -161,6 +165,8 @@ public class CollectionController : BaseApiController
|
|||
[HttpPost("delete-multiple")]
|
||||
public async Task<ActionResult> DeleteMultipleCollections(DeleteCollectionsDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
// This needs to take into account owner as I can select other users cards
|
||||
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Collections);
|
||||
if (user == null) return Unauthorized();
|
||||
|
|
@ -182,6 +188,8 @@ public class CollectionController : BaseApiController
|
|||
[HttpPost("update-for-series")]
|
||||
public async Task<ActionResult> AddToMultipleSeries(CollectionTagBulkAddDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
// Create a new tag and save
|
||||
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Collections);
|
||||
if (user == null) return Unauthorized();
|
||||
|
|
@ -223,6 +231,8 @@ public class CollectionController : BaseApiController
|
|||
[HttpPost("update-series")]
|
||||
public async Task<ActionResult> RemoveTagFromMultipleSeries(UpdateSeriesForTagDto updateSeriesForTagDto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
try
|
||||
{
|
||||
var tag = await _unitOfWork.CollectionTagRepository.GetCollectionAsync(updateSeriesForTagDto.Tag.Id, CollectionIncludes.Series);
|
||||
|
|
@ -247,6 +257,8 @@ public class CollectionController : BaseApiController
|
|||
[HttpDelete]
|
||||
public async Task<ActionResult> DeleteTag(int tagId)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
try
|
||||
{
|
||||
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Collections);
|
||||
|
|
@ -276,6 +288,8 @@ public class CollectionController : BaseApiController
|
|||
[HttpGet("mal-stacks")]
|
||||
public async Task<ActionResult<IList<MalStackDto>>> GetMalStacksForUser()
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
return Ok(await _externalMetadataService.GetStacksForUser(User.GetUserId()));
|
||||
}
|
||||
|
||||
|
|
@ -289,6 +303,8 @@ public class CollectionController : BaseApiController
|
|||
{
|
||||
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Collections);
|
||||
if (user == null) return Unauthorized();
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
|
||||
// Validation check to ensure stack doesn't exist already
|
||||
if (await _unitOfWork.CollectionTagRepository.CollectionExists(dto.Title, user.Id))
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.Constants;
|
||||
using API.Data;
|
||||
using API.Data.Repositories;
|
||||
using API.DTOs.Dashboard;
|
||||
|
|
@ -9,6 +10,7 @@ using API.DTOs.Filtering.v2;
|
|||
using API.Entities;
|
||||
using API.Extensions;
|
||||
using API.Helpers;
|
||||
using API.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace API.Controllers;
|
||||
|
|
@ -21,10 +23,12 @@ namespace API.Controllers;
|
|||
public class FilterController : BaseApiController
|
||||
{
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
|
||||
public FilterController(IUnitOfWork unitOfWork)
|
||||
public FilterController(IUnitOfWork unitOfWork, ILocalizationService localizationService)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_localizationService = localizationService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -37,6 +41,7 @@ public class FilterController : BaseApiController
|
|||
{
|
||||
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.SmartFilters);
|
||||
if (user == null) return Unauthorized();
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(dto.Name)) return BadRequest("Name must be set");
|
||||
if (Seed.DefaultStreams.Any(s => s.Name.Equals(dto.Name, StringComparison.InvariantCultureIgnoreCase)))
|
||||
|
|
@ -78,6 +83,8 @@ public class FilterController : BaseApiController
|
|||
[HttpDelete]
|
||||
public async Task<ActionResult> DeleteFilter(int filterId)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
var filter = await _unitOfWork.AppUserSmartFilterRepository.GetById(filterId);
|
||||
if (filter == null) return Ok();
|
||||
// This needs to delete any dashboard filters that have it too
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using API.Services;
|
|||
using API.Services.Tasks.Metadata;
|
||||
using API.SignalR;
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nager.ArticleNumber;
|
||||
|
||||
|
|
@ -72,6 +73,7 @@ public class PersonController : BaseApiController
|
|||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize("AdminRequired")]
|
||||
[HttpPost("update")]
|
||||
public async Task<ActionResult<PersonDto>> UpdatePerson(UpdatePersonDto dto)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("update-position")]
|
||||
public async Task<ActionResult> UpdateListItemPosition(UpdateReadingListPosition dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
// Make sure UI buffers events
|
||||
var user = await _readingListService.UserHasReadingListAccess(dto.ReadingListId, User.GetUsername());
|
||||
if (user == null)
|
||||
|
|
@ -129,6 +130,7 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("delete-item")]
|
||||
public async Task<ActionResult> DeleteListItem(UpdateReadingListPosition dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
var user = await _readingListService.UserHasReadingListAccess(dto.ReadingListId, User.GetUsername());
|
||||
if (user == null)
|
||||
{
|
||||
|
|
@ -151,6 +153,8 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("remove-read")]
|
||||
public async Task<ActionResult> DeleteReadFromList([FromQuery] int readingListId)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
var user = await _readingListService.UserHasReadingListAccess(readingListId, User.GetUsername());
|
||||
if (user == null)
|
||||
{
|
||||
|
|
@ -173,6 +177,7 @@ public class ReadingListController : BaseApiController
|
|||
[HttpDelete]
|
||||
public async Task<ActionResult> DeleteList([FromQuery] int readingListId)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
var user = await _readingListService.UserHasReadingListAccess(readingListId, User.GetUsername());
|
||||
if (user == null)
|
||||
{
|
||||
|
|
@ -193,6 +198,7 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("create")]
|
||||
public async Task<ActionResult<ReadingListDto>> CreateList(CreateReadingListDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername(), AppUserIncludes.ReadingLists);
|
||||
if (user == null) return Unauthorized();
|
||||
|
||||
|
|
@ -216,6 +222,7 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("update")]
|
||||
public async Task<ActionResult> UpdateList(UpdateReadingListDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
var readingList = await _unitOfWork.ReadingListRepository.GetReadingListByIdAsync(dto.ReadingListId);
|
||||
if (readingList == null) return BadRequest(await _localizationService.Translate(User.GetUserId(), "reading-list-doesnt-exist"));
|
||||
|
||||
|
|
@ -245,6 +252,7 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("update-by-series")]
|
||||
public async Task<ActionResult> UpdateListBySeries(UpdateReadingListBySeriesDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
var user = await _readingListService.UserHasReadingListAccess(dto.ReadingListId, User.GetUsername());
|
||||
if (user == null)
|
||||
{
|
||||
|
|
@ -287,6 +295,7 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("update-by-multiple")]
|
||||
public async Task<ActionResult> UpdateListByMultiple(UpdateReadingListByMultipleDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
var user = await _readingListService.UserHasReadingListAccess(dto.ReadingListId, User.GetUsername());
|
||||
if (user == null)
|
||||
{
|
||||
|
|
@ -331,6 +340,7 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("update-by-multiple-series")]
|
||||
public async Task<ActionResult> UpdateListByMultipleSeries(UpdateReadingListByMultipleSeriesDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
var user = await _readingListService.UserHasReadingListAccess(dto.ReadingListId, User.GetUsername());
|
||||
if (user == null)
|
||||
{
|
||||
|
|
@ -369,6 +379,7 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("update-by-volume")]
|
||||
public async Task<ActionResult> UpdateListByVolume(UpdateReadingListByVolumeDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
var user = await _readingListService.UserHasReadingListAccess(dto.ReadingListId, User.GetUsername());
|
||||
if (user == null)
|
||||
{
|
||||
|
|
@ -405,6 +416,7 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("update-by-chapter")]
|
||||
public async Task<ActionResult> UpdateListByChapter(UpdateReadingListByChapterDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
var user = await _readingListService.UserHasReadingListAccess(dto.ReadingListId, User.GetUsername());
|
||||
if (user == null)
|
||||
{
|
||||
|
|
@ -514,6 +526,8 @@ public class ReadingListController : BaseApiController
|
|||
[HttpPost("promote-multiple")]
|
||||
public async Task<ActionResult> PromoteMultipleReadingLists(PromoteReadingListsDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
// This needs to take into account owner as I can select other users cards
|
||||
var userId = User.GetUserId();
|
||||
if (!User.IsInRole(PolicyConstants.PromoteRole) && !User.IsInRole(PolicyConstants.AdminRole))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using API.Constants;
|
||||
using API.Data;
|
||||
using API.DTOs.Dashboard;
|
||||
using API.DTOs.SideNav;
|
||||
|
|
@ -19,11 +20,13 @@ public class StreamController : BaseApiController
|
|||
{
|
||||
private readonly IStreamService _streamService;
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
|
||||
public StreamController(IStreamService streamService, IUnitOfWork unitOfWork)
|
||||
public StreamController(IStreamService streamService, IUnitOfWork unitOfWork, ILocalizationService localizationService)
|
||||
{
|
||||
_streamService = streamService;
|
||||
_unitOfWork = unitOfWork;
|
||||
_localizationService = localizationService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -74,6 +77,7 @@ public class StreamController : BaseApiController
|
|||
[HttpPost("update-external-source")]
|
||||
public async Task<ActionResult<ExternalSourceDto>> UpdateExternalSource(ExternalSourceDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
// Check if a host and api key exists for the current user
|
||||
return Ok(await _streamService.UpdateExternalSource(User.GetUserId(), dto));
|
||||
}
|
||||
|
|
@ -86,7 +90,8 @@ public class StreamController : BaseApiController
|
|||
[HttpGet("external-source-exists")]
|
||||
public async Task<ActionResult<bool>> ExternalSourceExists(string host, string name, string apiKey)
|
||||
{
|
||||
return Ok(await _unitOfWork.AppUserExternalSourceRepository.ExternalSourceExists(User.GetUserId(), host, name, apiKey));
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
return Ok(await _unitOfWork.AppUserExternalSourceRepository.ExternalSourceExists(User.GetUserId(), name, host, apiKey));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -97,6 +102,7 @@ public class StreamController : BaseApiController
|
|||
[HttpDelete("delete-external-source")]
|
||||
public async Task<ActionResult> ExternalSourceExists(int externalSourceId)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
await _streamService.DeleteExternalSource(User.GetUserId(), externalSourceId);
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -110,6 +116,7 @@ public class StreamController : BaseApiController
|
|||
[HttpPost("add-dashboard-stream")]
|
||||
public async Task<ActionResult<DashboardStreamDto>> AddDashboard([FromQuery] int smartFilterId)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
return Ok(await _streamService.CreateDashboardStreamFromSmartFilter(User.GetUserId(), smartFilterId));
|
||||
}
|
||||
|
||||
|
|
@ -121,6 +128,7 @@ public class StreamController : BaseApiController
|
|||
[HttpPost("update-dashboard-stream")]
|
||||
public async Task<ActionResult> UpdateDashboardStream(DashboardStreamDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
await _streamService.UpdateDashboardStream(User.GetUserId(), dto);
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -133,6 +141,7 @@ public class StreamController : BaseApiController
|
|||
[HttpPost("update-dashboard-position")]
|
||||
public async Task<ActionResult> UpdateDashboardStreamPosition(UpdateStreamPositionDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
await _streamService.UpdateDashboardStreamPosition(User.GetUserId(), dto);
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -146,6 +155,7 @@ public class StreamController : BaseApiController
|
|||
[HttpPost("add-sidenav-stream")]
|
||||
public async Task<ActionResult<SideNavStreamDto>> AddSideNav([FromQuery] int smartFilterId)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
return Ok(await _streamService.CreateSideNavStreamFromSmartFilter(User.GetUserId(), smartFilterId));
|
||||
}
|
||||
|
||||
|
|
@ -157,6 +167,7 @@ public class StreamController : BaseApiController
|
|||
[HttpPost("add-sidenav-stream-from-external-source")]
|
||||
public async Task<ActionResult<SideNavStreamDto>> AddSideNavFromExternalSource([FromQuery] int externalSourceId)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
return Ok(await _streamService.CreateSideNavStreamFromExternalSource(User.GetUserId(), externalSourceId));
|
||||
}
|
||||
|
||||
|
|
@ -168,6 +179,7 @@ public class StreamController : BaseApiController
|
|||
[HttpPost("update-sidenav-stream")]
|
||||
public async Task<ActionResult> UpdateSideNavStream(SideNavStreamDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
await _streamService.UpdateSideNavStream(User.GetUserId(), dto);
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -180,6 +192,7 @@ public class StreamController : BaseApiController
|
|||
[HttpPost("update-sidenav-position")]
|
||||
public async Task<ActionResult> UpdateSideNavStreamPosition(UpdateStreamPositionDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
await _streamService.UpdateSideNavStreamPosition(User.GetUserId(), dto);
|
||||
return Ok();
|
||||
}
|
||||
|
|
@ -187,6 +200,7 @@ public class StreamController : BaseApiController
|
|||
[HttpPost("bulk-sidenav-stream-visibility")]
|
||||
public async Task<ActionResult> BulkUpdateSideNavStream(BulkUpdateSideNavStreamVisibilityDto dto)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
await _streamService.UpdateSideNavStreamBulk(User.GetUserId(), dto);
|
||||
return Ok();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public class ThemeController : BaseApiController
|
|||
[HttpDelete]
|
||||
public async Task<ActionResult<IEnumerable<DownloadableSiteThemeDto>>> DeleteTheme(int themeId)
|
||||
{
|
||||
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
await _themeService.DeleteTheme(themeId);
|
||||
|
||||
return Ok();
|
||||
|
|
@ -128,6 +128,8 @@ public class ThemeController : BaseApiController
|
|||
[HttpPost("upload-theme")]
|
||||
public async Task<ActionResult<SiteThemeDto>> DownloadTheme(IFormFile formFile)
|
||||
{
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
if (!formFile.FileName.EndsWith(".css")) return BadRequest("Invalid file");
|
||||
if (formFile.FileName.Contains("..")) return BadRequest("Invalid file");
|
||||
var tempFile = await UploadToTemp(formFile);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.Constants;
|
||||
using API.Data;
|
||||
using API.Data.Repositories;
|
||||
using API.DTOs;
|
||||
|
|
@ -82,12 +83,20 @@ public class UsersController : BaseApiController
|
|||
return Ok(libs.Any(x => x.Id == libraryId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the user preferences
|
||||
/// </summary>
|
||||
/// <remarks>If the user has ReadOnly role, they will not be able to perform this action</remarks>
|
||||
/// <param name="preferencesDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("update-preferences")]
|
||||
public async Task<ActionResult<UserPreferencesDto>> UpdatePreferences(UserPreferencesDto preferencesDto)
|
||||
{
|
||||
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername(),
|
||||
AppUserIncludes.UserPreferences);
|
||||
if (user == null) return Unauthorized();
|
||||
if (User.IsInRole(PolicyConstants.ReadOnlyRole)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
|
||||
|
||||
var existingPreferences = user!.UserPreferences;
|
||||
|
||||
existingPreferences.ReadingDirection = preferencesDto.ReadingDirection;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,9 @@ public class StatisticService : IStatisticService
|
|||
|
||||
var lastActive = await _context.AppUserProgresses
|
||||
.Where(p => p.AppUserId == userId)
|
||||
.MaxAsync(p => p.LastModified);
|
||||
.Select(p => p.LastModified)
|
||||
.DefaultIfEmpty()
|
||||
.MaxAsync();
|
||||
|
||||
|
||||
// First get the total pages per library
|
||||
|
|
@ -127,12 +129,23 @@ public class StatisticService : IStatisticService
|
|||
|
||||
var earliestReadDate = await _context.AppUserProgresses
|
||||
.Where(p => p.AppUserId == userId)
|
||||
.MinAsync(p => p.Created);
|
||||
.Select(p => p.Created)
|
||||
.DefaultIfEmpty()
|
||||
.MinAsync();
|
||||
|
||||
if (earliestReadDate == DateTime.MinValue)
|
||||
{
|
||||
averageReadingTimePerWeek = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var timeDifference = DateTime.Now - earliestReadDate;
|
||||
var deltaWeeks = (int)Math.Ceiling(timeDifference.TotalDays / 7);
|
||||
|
||||
averageReadingTimePerWeek /= deltaWeeks;
|
||||
}
|
||||
|
||||
var timeDifference = DateTime.Now - earliestReadDate;
|
||||
var deltaWeeks = (int)Math.Ceiling(timeDifference.TotalDays / 7);
|
||||
|
||||
averageReadingTimePerWeek /= deltaWeeks;
|
||||
|
||||
|
||||
return new UserReadStatistics()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue