diff --git a/CHANGELOG.md b/CHANGELOG.md index 321098722..a1684273b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,43 @@ ## v3.0.3919 (2018-10-18) +### **New Features** + +- Updated the emby api since we no longer need the extra parameters to send to emby to log in a local user #2546. [Jamie] + +- Added the ability to get the ombi user via a Plex Token #2591. [Jamie] + +### **Fixes** + +- Made the subscribe/unsubscribe button more obvious on the UI #2309. [Jamie] + +- Fixed #2603. [Jamie] + +- Fixed the issue with the user overrides #2646. [Jamie] + +- Fixed the issue where we could sometimes allow the request of a whole series when the user shouldn't be able to. [Jamie] + +- Fixed the issue where we were marking episodes as available with the Emby connection when they have not yet aired #2417 #2623. [TidusJar] + +- Fixed the issue where we were marking the whole season as wanted in Sonarr rather than the individual episode #2629. [TidusJar] + +- Fixed #2623. [Jamie] + +- Fixed #2633. [TidusJar] + +- Fixed #2639. [Jamie] + +- Show the TV show as available when we have all the episodes but future episodes have not aired. #2585. [Jamie] + + +## v3.0.3945 (2018-10-25) + +### **New Features** + +- Update Readme for Lidarr. [Qstick] + +- Update CHANGELOG.md. [Jamie] + ### **Fixes** - New translations en.json (French) [Jamie] diff --git a/appveyor.yml b/appveyor.yml index 99ec1e669..448e1b9c8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,11 @@ configuration: Release os: Visual Studio 2017 environment: nodejs_version: "9.8.0" - typescript_version: "3.0.1" + typescript_version: "3.0.1" + github_auth_token: + secure: H/7uCrjmWHGJxgN3l9fbhhdVjvvWI8VVF4ZzQqeXuJwAf+PgSNBdxv4SS+rMQ+RH + sonarrcloudtoken: + secure: WGkIog4wuMSx1q5vmSOgIBXMtI/leMpLbZhi9MJnJdBBuDfcv12zwXg3LQwY0WbE install: # Get the latest stable version of Node.js or io.js @@ -12,10 +16,14 @@ install: - cmd: set path=%programfiles(x86)%\\Microsoft SDKs\TypeScript\3.0;%path% - cmd: tsc -v build_script: + # - dotnet tool install --global dotnet-sonarscanner + #- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.sonarrcloud_token" /d:sonar.analysis.mode="preview" /d:sonar.github.pullRequest="$env:APPVEYOR_PULL_REQUEST_NUMBER" /d:sonar.github.repository="https://github.com/tidusjar/ombi" /d:sonar.github.oauth="$env.github_auth_token" } + # - ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { dotnet sonarscanner begin /k:"tidusjar_Ombi" /d:sonar.organization="tidusjar-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env.SONARRCLOUDTOKEN" } - ps: ./build.ps1 --settings_skipverification=true + # - dotnet sonarscanner end /d:sonar.login="%sonarrcloudtoken%" test: off - + after_build: - cmd: >- diff --git a/src/Ombi.Api.Emby/EmbyApi.cs b/src/Ombi.Api.Emby/EmbyApi.cs index fcb989094..43a2badb6 100644 --- a/src/Ombi.Api.Emby/EmbyApi.cs +++ b/src/Ombi.Api.Emby/EmbyApi.cs @@ -53,8 +53,6 @@ public async Task LogIn(string username, string password, string apiKe { username, pw = password, - password = password.GetSha1Hash().ToLower(), - passwordMd5 = password.CalcuateMd5Hash() }; request.AddJsonBody(body); @@ -98,7 +96,7 @@ public async Task> GetCollection(string mediaId, st request.AddQueryString("Fields", "ProviderIds,Overview"); - request.AddQueryString("VirtualItem", "False"); + request.AddQueryString("IsVirtualItem", "False"); return await Api.Request>(request); } @@ -149,7 +147,7 @@ private async Task> GetAll(string type, string apiKey, s request.AddQueryString("IncludeItemTypes", type); request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds"); - request.AddQueryString("VirtualItem", "False"); + request.AddQueryString("IsVirtualItem", "False"); AddHeaders(request, apiKey); @@ -167,7 +165,7 @@ private async Task> GetAll(string type, string apiKey, s request.AddQueryString("startIndex", startIndex.ToString()); request.AddQueryString("limit", count.ToString()); - request.AddQueryString("VirtualItem", "False"); + request.AddQueryString("IsVirtualItem", "False"); AddHeaders(request, apiKey); diff --git a/src/Ombi.Core/Authentication/OmbiUserManager.cs b/src/Ombi.Core/Authentication/OmbiUserManager.cs index 185677215..2c78f39bf 100644 --- a/src/Ombi.Core/Authentication/OmbiUserManager.cs +++ b/src/Ombi.Core/Authentication/OmbiUserManager.cs @@ -29,6 +29,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Ombi.Api.Emby; @@ -101,6 +102,22 @@ public async Task RequiresPassword(OmbiUser user) return true; } + public async Task GetOmbiUserFromPlexToken(string plexToken) + { + var plexAccount = await _plexApi.GetAccount(plexToken); + + // Check for a ombi user + if (plexAccount?.user != null) + { + var potentialOmbiUser = await Users.FirstOrDefaultAsync(x => + x.ProviderUserId == plexAccount.user.id); + return potentialOmbiUser; + } + + return null; + } + + /// /// Sign the user into plex and make sure we can get the authentication token. /// We do not check if the user is in the owners "friends" since they must have a local user account to get this far diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index f1a5b9880..290bedd6b 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -116,6 +116,7 @@ public async Task RequestTvShow(TvRequestViewModel tv) } // Remove the ID since this is a new child + // This was a TVDBID for the request rules to run tvBuilder.ChildRequest.Id = 0; if (!tvBuilder.ChildRequest.SeasonRequests.Any()) { diff --git a/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs b/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs index e5277e236..334284484 100644 --- a/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs +++ b/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs @@ -41,7 +41,7 @@ public async Task GetShowInfo(int id) ShowInfo = await TvApi.ShowLookupByTheTvDbId(id); Results = await MovieDbApi.SearchTv(ShowInfo.name); foreach (TvSearchResult result in Results) { - if (result.Name == ShowInfo.name) + if (result.Name.Equals(ShowInfo.name, StringComparison.InvariantCultureIgnoreCase)) { var showIds = await MovieDbApi.GetTvExternals(result.Id); ShowInfo.externals.imdb = showIds.imdb_id; @@ -64,14 +64,15 @@ public TvShowRequestBuilder CreateChild(TvRequestViewModel model, string userId) { ChildRequest = new ChildRequests { - Id = model.TvDbId, + Id = model.TvDbId, // This is set to 0 after the request rules have run, the request rules needs it to identify the request RequestType = RequestType.TvShow, RequestedDate = DateTime.UtcNow, Approved = false, RequestedUserId = userId, SeasonRequests = new List(), Title = ShowInfo.name, - SeriesType = ShowInfo.genres.Any( s => s.Equals("Anime", StringComparison.OrdinalIgnoreCase)) ? SeriesType.Anime : SeriesType.Standard + ReleaseYear = FirstAir, + SeriesType = ShowInfo.genres.Any( s => s.Equals("Anime", StringComparison.InvariantCultureIgnoreCase)) ? SeriesType.Anime : SeriesType.Standard }; return this; diff --git a/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs new file mode 100644 index 000000000..5d7658c83 --- /dev/null +++ b/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Ombi.Core.Rule.Interfaces; +using Ombi.Store.Entities; +using Ombi.Store.Entities.Requests; +using Ombi.Store.Repository; + +namespace Ombi.Core.Rule.Rules.Request +{ + public class ExistingPlexRequestRule : BaseRequestRule, IRules + { + public ExistingPlexRequestRule(IPlexContentRepository rv) + { + _plexContent = rv; + } + + private readonly IPlexContentRepository _plexContent; + + /// + /// We check if the request exists, if it does then we don't want to re-request it. + /// + /// The object. + /// + public async Task Execute(BaseRequest obj) + { + if (obj.RequestType == RequestType.TvShow) + { + var tvRequest = (ChildRequests) obj; + + var tvContent = _plexContent.GetAll().Where(x => x.Type == PlexMediaTypeEntity.Show); + // We need to do a check on the TVDBId + var anyTvDbMatches = await tvContent.Include(x => x.Episodes).FirstOrDefaultAsync(x => x.HasTvDb && x.TvDbId.Equals(tvRequest.Id.ToString())); // the Id on the child is the tvdbid at this point + if (anyTvDbMatches == null) + { + // So we do not have a TVDB Id, that really sucks. + // Let's try and match on the title and year of the show + var titleAndYearMatch = await tvContent.Include(x=> x.Episodes).FirstOrDefaultAsync(x => + x.Title.Equals(tvRequest.Title, StringComparison.InvariantCultureIgnoreCase) + && x.ReleaseYear == tvRequest.ReleaseYear.Year.ToString()); + if (titleAndYearMatch != null) + { + // We have a match! Suprise Motherfucker + return CheckExistingContent(tvRequest, titleAndYearMatch); + } + + // We do not have this + return Success(); + } + // looks like we have a match on the TVDbID + return CheckExistingContent(tvRequest, anyTvDbMatches); + } + return Success(); + } + + + private RuleResult CheckExistingContent(ChildRequests child, PlexServerContent content) + { + foreach (var season in child.SeasonRequests) + { + var currentSeasonRequest = + content.Episodes.Where(x => x.SeasonNumber == season.SeasonNumber).ToList(); + if (!currentSeasonRequest.Any()) + { + continue; + } + foreach (var e in season.Episodes) + { + var hasEpisode = currentSeasonRequest.Any(x => x.EpisodeNumber == e.EpisodeNumber); + if (hasEpisode) + { + return Fail($"We already have episodes requested from series {child.Title}"); + } + } + } + + return Success(); + } + } +} \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs new file mode 100644 index 000000000..9942ece63 --- /dev/null +++ b/src/Ombi.Core/Rule/Rules/Request/ExistingTVRequestRule.cs @@ -0,0 +1,57 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Ombi.Core.Rule.Interfaces; +using Ombi.Store.Entities; +using Ombi.Store.Entities.Requests; +using Ombi.Store.Repository.Requests; + +namespace Ombi.Core.Rule.Rules.Request +{ + public class ExistingTvRequestRule : BaseRequestRule, IRules + { + public ExistingTvRequestRule(ITvRequestRepository rv) + { + Tv = rv; + } + + private ITvRequestRepository Tv { get; } + + /// + /// We check if the request exists, if it does then we don't want to re-request it. + /// + /// The object. + /// + public async Task Execute(BaseRequest obj) + { + if (obj.RequestType == RequestType.TvShow) + { + var tv = (ChildRequests) obj; + var tvRequests = Tv.GetChild(); + var currentRequest = await tvRequests.FirstOrDefaultAsync(x => x.ParentRequest.TvDbId == tv.Id); // the Id on the child is the tvdbid at this point + if (currentRequest == null) + { + return Success(); + } + foreach (var season in tv.SeasonRequests) + { + var currentSeasonRequest = + currentRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == season.SeasonNumber); + if (currentSeasonRequest == null) + { + continue; + } + foreach (var e in season.Episodes) + { + var hasEpisode = currentSeasonRequest.Episodes.Any(x => x.EpisodeNumber == e.EpisodeNumber); + if (hasEpisode) + { + return Fail($"We already have episodes requested from series {tv.Title}"); + } + } + } + } + return Success(); + } + } +} \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs index 016a2817c..e1ddcecd0 100644 --- a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Ombi.Core.Models.Search; @@ -104,6 +105,21 @@ public async Task Execute(SearchViewModel obj) { search.FullyAvailable = true; } + else + { + var airedButNotAvailable = search.SeasonRequests.Any(x => + x.Episodes.Any(c => !c.Available && c.AirDate <= DateTime.Now.Date)); + if (!airedButNotAvailable) + { + var unairedEpisodes = search.SeasonRequests.Any(x => + x.Episodes.Any(c => !c.Available && c.AirDate > DateTime.Now.Date)); + if (unairedEpisodes) + { + search.FullyAvailable = true; + } + } + + } } } } diff --git a/src/Ombi.Core/Senders/MovieSender.cs b/src/Ombi.Core/Senders/MovieSender.cs index 8b89ef7bb..66978f758 100644 --- a/src/Ombi.Core/Senders/MovieSender.cs +++ b/src/Ombi.Core/Senders/MovieSender.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; @@ -101,13 +102,17 @@ private async Task SendToRadarr(MovieRequests model, RadarrSetting var profiles = await _userProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == model.RequestedUserId); if (profiles != null) { - if (profiles.SonarrRootPathAnime > 0) - { - rootFolderPath = await RadarrRootPath(profiles.SonarrRootPathAnime, settings); + if (profiles.RadarrRootPath > 0) + { + var tempPath = await RadarrRootPath(profiles.RadarrRootPath, settings); + if (tempPath.HasValue()) + { + rootFolderPath = tempPath; + } } - if (profiles.SonarrQualityProfileAnime > 0) + if (profiles.RadarrQualityProfile > 0) { - qualityToUse = profiles.SonarrQualityProfileAnime; + qualityToUse = profiles.RadarrQualityProfile; } } @@ -163,7 +168,7 @@ private async Task RadarrRootPath(int overrideId, RadarrSettings setting { var paths = await RadarrApi.GetRootFolders(settings.ApiKey, settings.FullUri); var selectedPath = paths.FirstOrDefault(x => x.id == overrideId); - return selectedPath.path; + return selectedPath?.path ?? String.Empty; } } } \ No newline at end of file diff --git a/src/Ombi.Core/Senders/TvSender.cs b/src/Ombi.Core/Senders/TvSender.cs index e48e54c1a..1b3ed9461 100644 --- a/src/Ombi.Core/Senders/TvSender.cs +++ b/src/Ombi.Core/Senders/TvSender.cs @@ -355,7 +355,7 @@ private static List GetSeasonsToCreate(ChildRequests model) var sea = new Season { seasonNumber = i, - monitored = model.SeasonRequests.Any(x => x.SeasonNumber == index && x.SeasonNumber != 0) + monitored = false }; seasonsToUpdate.Add(sea); } diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs index f66ff89ab..23ad24268 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs @@ -82,6 +82,13 @@ private async Task CacheEpisodes(EmbyServers server) foreach (var ep in allEpisodes.Items) { processed++; + + if (ep.LocationType.Equals("Virtual", StringComparison.InvariantCultureIgnoreCase)) + { + // For some reason Emby is not respecting the `IsVirtualItem` field. + continue; + } + // Let's make sure we have the parent request, stop those pesky forign key errors, // Damn me having data integrity var parent = await _repo.GetByEmbyId(ep.SeriesId); diff --git a/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs b/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs index e645097ef..a34bd89e1 100644 --- a/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs +++ b/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs @@ -174,7 +174,7 @@ private async Task GetGitubRelease(Release release, string releaseTag) var client = new GitHubClient(Octokit.ProductHeaderValue.Parse("OmbiV3")); var releases = await client.Repository.Release.GetAll("tidusjar", "ombi"); - var latest = releases.FirstOrDefault(x => x.TagName == releaseTag); + var latest = releases.FirstOrDefault(x => x.TagName.Equals(releaseTag, StringComparison.InvariantCultureIgnoreCase)); if (latest.Name.Contains("V2", CompareOptions.IgnoreCase)) { latest = null; diff --git a/src/Ombi.Store/Entities/Requests/ChildRequests.cs b/src/Ombi.Store/Entities/Requests/ChildRequests.cs index 3b5156ce5..f212aa3e7 100644 --- a/src/Ombi.Store/Entities/Requests/ChildRequests.cs +++ b/src/Ombi.Store/Entities/Requests/ChildRequests.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using Ombi.Store.Repository.Requests; @@ -22,6 +23,8 @@ public class ChildRequests : BaseRequest [NotMapped] public bool ShowSubscribe { get; set; } + [NotMapped] + public DateTime ReleaseYear { get; set; } // Used in the ExistingPlexRequestRule.cs [ForeignKey(nameof(IssueId))] public List Issues { get; set; } diff --git a/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts b/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts index c88e63009..bf43b7330 100644 --- a/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts +++ b/src/Ombi/ClientApp/app/requests/remainingrequests.component.ts @@ -39,7 +39,9 @@ export class RemainingRequestsComponent implements OnInit { public update(): void { const callback = (remaining => { this.remaining = remaining; - this.calculateTime(); + if(this.remaining) { + this.calculateTime(); + } }); if (this.movie) { diff --git a/src/Ombi/ClientApp/app/requests/request.component.html b/src/Ombi/ClientApp/app/requests/request.component.html index d2df3c97a..db72b9d17 100644 --- a/src/Ombi/ClientApp/app/requests/request.component.html +++ b/src/Ombi/ClientApp/app/requests/request.component.html @@ -9,7 +9,7 @@

{{ 'Requests.TvTab' | translate }} -
  • +
  • {{ 'Requests.MusicTab' | translate }}
  • diff --git a/src/Ombi/ClientApp/app/requests/request.component.ts b/src/Ombi/ClientApp/app/requests/request.component.ts index d0fa9d0b1..b318d619b 100644 --- a/src/Ombi/ClientApp/app/requests/request.component.ts +++ b/src/Ombi/ClientApp/app/requests/request.component.ts @@ -15,6 +15,7 @@ export class RequestComponent implements OnInit { public issueCategories: IIssueCategory[]; public issuesEnabled = false; + public musicEnabled: boolean; constructor(private issuesService: IssuesService, private settingsService: SettingsService) { @@ -23,6 +24,7 @@ export class RequestComponent implements OnInit { public ngOnInit(): void { this.issuesService.getCategories().subscribe(x => this.issueCategories = x); + this.settingsService.lidarrEnabled().subscribe(x => this.musicEnabled = x); this.settingsService.getIssueSettings().subscribe(x => this.issuesEnabled = x.enabled); } diff --git a/src/Ombi/ClientApp/app/search/moviesearch.component.html b/src/Ombi/ClientApp/app/search/moviesearch.component.html index 05dbf15ad..daf77a079 100644 --- a/src/Ombi/ClientApp/app/search/moviesearch.component.html +++ b/src/Ombi/ClientApp/app/search/moviesearch.component.html @@ -2,7 +2,8 @@
    - +

    {{result.title}} ({{result.releaseDate | amLocal | amDateFormat: 'YYYY'}})

    - - {{ 'Search.TheatricalRelease' | translate: {date: result.releaseDate | amLocal | amDateFormat: 'LL'} }} - {{ 'Search.DigitalDate' | translate: {date: result.digitalReleaseDate | amLocal | amDateFormat: 'LL'} }} - - - - - {{result.quality}}p - - - - - - - - - -
    + + {{ + 'Search.TheatricalRelease' | translate: {date: result.releaseDate | amLocal | + amDateFormat: 'LL'} }} + {{ 'Search.DigitalDate' | translate: {date: result.digitalReleaseDate | + amLocal | amDateFormat: 'LL'} }} + + + + + {{result.quality}}p + + + + + + + + + +

    {{result.overview}}

    -
    -
    - - - -
    -
    - +
    -
    - - - - - - -
    - - -
    +
    + + + + + + +
    + + + +
    -
    -
    +
    +
    @@ -117,4 +139,4 @@

    {{result.title}} ({{result.releaseDate | amLocal | amDateFormat: 'YYYY'}}) + [issueCategory]="issueCategorySelected" [id]="issueRequestId" [providerId]="issueProviderId"> \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/search/moviesearch.component.ts b/src/Ombi/ClientApp/app/search/moviesearch.component.ts index f4d19565a..600fc19eb 100644 --- a/src/Ombi/ClientApp/app/search/moviesearch.component.ts +++ b/src/Ombi/ClientApp/app/search/moviesearch.component.ts @@ -172,7 +172,7 @@ export class MovieSearchComponent implements OnInit { r.subscribed = true; this.requestService.subscribeToMovie(r.requestId) .subscribe(x => { - this.notificationService.success("Subscribed To Movie!"); + this.notificationService.success(`Subscribed To Movie ${r.title}!`); }); } diff --git a/src/Ombi/Controllers/TokenController.cs b/src/Ombi/Controllers/TokenController.cs index 87136fd00..75e40639f 100644 --- a/src/Ombi/Controllers/TokenController.cs +++ b/src/Ombi/Controllers/TokenController.cs @@ -10,14 +10,13 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; -using Ombi.Api; using Ombi.Core.Authentication; using Ombi.Helpers; using Ombi.Models; +using Ombi.Models.External; using Ombi.Models.Identity; using Ombi.Store.Entities; using Ombi.Store.Repository; -using StackExchange.Profiling.Helpers; namespace Ombi.Controllers { @@ -80,7 +79,7 @@ await _audit.Record(AuditType.None, AuditArea.Authentication, { // Plex OAuth // Redirect them to Plex - + var websiteAddress = $"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}"; //https://app.plex.tv/auth#?forwardUrl=http://google.com/&clientID=Ombi-Test&context%5Bdevice%5D%5Bproduct%5D=Ombi%20SSO&pinID=798798&code=4lgfd var url = await _plexOAuthManager.GetOAuthUrl(model.PlexTvPin.code, websiteAddress); @@ -97,6 +96,25 @@ await _audit.Record(AuditType.None, AuditArea.Authentication, return new UnauthorizedResult(); } + /// + /// Returns the Token for the Ombi User if we can match the Plex user with a valid Ombi User + /// + [HttpPost("plextoken")] + public async Task GetTokenWithPlexToken([FromBody] PlexTokenAuthentication model) + { + if (!model.PlexToken.HasValue()) + { + return BadRequest("Token was not provided"); + } + var user = await _userManager.GetOmbiUserFromPlexToken(model.PlexToken); + if (user == null) + { + return Unauthorized(); + } + return await CreateToken(true, user); + } + + private async Task CreateToken(bool rememberMe, OmbiUser user) { var roles = await _userManager.GetRolesAsync(user); diff --git a/src/Ombi/Models/External/PlexTokenAuthentication.cs b/src/Ombi/Models/External/PlexTokenAuthentication.cs new file mode 100644 index 000000000..38184ecdb --- /dev/null +++ b/src/Ombi/Models/External/PlexTokenAuthentication.cs @@ -0,0 +1,7 @@ +namespace Ombi.Models.External +{ + public class PlexTokenAuthentication + { + public string PlexToken { get; set; } + } +} \ No newline at end of file