Got plex oauth working! !wip

pull/2174/head
Jamie Rees 6 years ago
parent 7bbcb9a626
commit 2fc4ef2613

@ -1,6 +1,8 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using Ombi.Api.Plex.Models;
using Ombi.Api.Plex.Models.Friends;
using Ombi.Api.Plex.Models.OAuth;
using Ombi.Api.Plex.Models.Server;
using Ombi.Api.Plex.Models.Status;
@ -20,5 +22,8 @@ namespace Ombi.Api.Plex
Task<PlexFriends> GetUsers(string authToken);
Task<PlexAccount> GetAccount(string authToken);
Task<PlexMetadata> GetRecentlyAdded(string authToken, string uri, string sectionId);
Task<OAuthPin> CreatePin();
Task<OAuthPin> GetPin(int pinId);
Uri GetOAuthUrl(int pinId, string code, string applicationUrl, bool wizard);
}
}

@ -0,0 +1,27 @@
using System;
namespace Ombi.Api.Plex.Models.OAuth
{
public class OAuthPin
{
public int id { get; set; }
public string code { get; set; }
public bool trusted { get; set; }
public string clientIdentifier { get; set; }
public Location location { get; set; }
public int expiresIn { get; set; }
public DateTime createdAt { get; set; }
public DateTime expiresAt { get; set; }
public string authToken { get; set; }
}
public class Location
{
public string code { get; set; }
public string country { get; set; }
public string city { get; set; }
public string subdivisions { get; set; }
public string coordinates { get; set; }
}
}

@ -1,20 +1,49 @@
using System.Net.Http;
using System;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using Ombi.Api.Plex.Models;
using Ombi.Api.Plex.Models.Friends;
using Ombi.Api.Plex.Models.OAuth;
using Ombi.Api.Plex.Models.Server;
using Ombi.Api.Plex.Models.Status;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
namespace Ombi.Api.Plex
{
public class PlexApi : IPlexApi
{
public PlexApi(IApi api)
public PlexApi(IApi api, ISettingsService<PlexSettings> settings)
{
Api = api;
_plex = settings;
}
private IApi Api { get; }
private readonly ISettingsService<PlexSettings> _plex;
private string _clientId;
private string ClientIdSecret
{
get
{
if (string.IsNullOrEmpty(_clientId))
{
var settings = _plex.GetSettings();
if (settings.UniqueInstallCode.IsNullOrEmpty())
{
settings.UniqueInstallCode = Guid.NewGuid().ToString("N");
_plex.SaveSettings(settings);
}
_clientId = settings.UniqueInstallCode;
}
return _clientId;
}
}
private const string SignInUri = "https://plex.tv/users/sign_in.json";
private const string FriendsUri = "https://plex.tv/pms/friends/all";
@ -156,6 +185,50 @@ namespace Ombi.Api.Plex
return await Api.Request<PlexMetadata>(request);
}
public async Task<OAuthPin> CreatePin()
{
var request = new Request($"api/v2/pins", "https://plex.tv/", HttpMethod.Post);
request.AddQueryString("strong", "true");
AddHeaders(request);
return await Api.Request<OAuthPin>(request);
}
public async Task<OAuthPin> GetPin(int pinId)
{
var request = new Request($"api/v2/pins/{pinId}", "https://plex.tv/", HttpMethod.Get);
AddHeaders(request);
return await Api.Request<OAuthPin>(request);
}
public Uri GetOAuthUrl(int pinId, string code, string applicationUrl, bool wizard)
{
var request = new Request("auth#", "https://app.plex.tv", HttpMethod.Get);
AddHeaders(request);
var forwardUrl = wizard
? new Request($"Wizard/OAuth/{pinId}", applicationUrl, HttpMethod.Get)
: new Request($"api/v1/PlexOAuth/{pinId}", applicationUrl, HttpMethod.Get);
request.AddQueryString("forwardUrl", forwardUrl.FullUri.ToString());
request.AddQueryString("pinID", pinId.ToString());
request.AddQueryString("code", code);
request.AddQueryString("context[device][product]", "Ombi");
request.AddQueryString("context[device][environment]", "bundled");
request.AddQueryString("clientID", $"OmbiV3{ClientIdSecret}");
if (request.FullUri.Fragment.Equals("#"))
{
var uri = request.FullUri.ToString();
var withoutEnd = uri.Remove(uri.Length - 1, 1);
var startOfQueryLocation = withoutEnd.IndexOf('?');
var better = withoutEnd.Insert(startOfQueryLocation, "#");
request.FullUri = new Uri(better);
}
return request.FullUri;
}
/// <summary>
/// Adds the required headers and also the authorization header
/// </summary>
@ -173,7 +246,7 @@ namespace Ombi.Api.Plex
/// <param name="request"></param>
private void AddHeaders(Request request)
{
request.AddHeader("X-Plex-Client-Identifier", $"OmbiV3");
request.AddHeader("X-Plex-Client-Identifier", $"OmbiV3{ClientIdSecret}");
request.AddHeader("X-Plex-Product", "Ombi");
request.AddHeader("X-Plex-Version", "3");
request.AddContentHeader("Content-Type", request.ContentType == ContentType.Json ? "application/json" : "application/xml");

@ -10,7 +10,7 @@ namespace Ombi.Api
{
public Request()
{
}
public Request(string endpoint, string baseUrl, HttpMethod http, ContentType contentType = ContentType.Json)
@ -105,10 +105,10 @@ namespace Ombi.Api
hasQuery = true;
startingTag = builder.Query.Contains("?") ? "&" : "?";
}
builder.Query = hasQuery
? $"{builder.Query}{startingTag}{key}={value}"
: $"{startingTag}{key}={value}";
_modified = builder.Uri;
}

@ -0,0 +1,76 @@
using System;
using System.Threading.Tasks;
using Ombi.Api.Plex;
using Ombi.Api.Plex.Models;
using Ombi.Api.Plex.Models.OAuth;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Settings.Settings.Models;
namespace Ombi.Core.Authentication
{
public class PlexOAuthManager : IPlexOAuthManager
{
public PlexOAuthManager(IPlexApi api, ISettingsService<CustomizationSettings> settings)
{
_api = api;
_customizationSettingsService = settings;
}
private readonly IPlexApi _api;
private readonly ISettingsService<CustomizationSettings> _customizationSettingsService;
public async Task<OAuthPin> RequestPin()
{
var pin = await _api.CreatePin();
return pin;
}
public async Task<string> GetAccessTokenFromPin(int pinId)
{
var pin = await _api.GetPin(pinId);
if (pin.expiresAt < DateTime.UtcNow)
{
return string.Empty;
}
if (pin.authToken.IsNullOrEmpty())
{
// Looks like we do not have a pin yet, we should retry a few times.
var retryCount = 0;
var retryMax = 5;
var retryWaitMs = 1000;
while (pin.authToken.IsNullOrEmpty() && retryCount < retryMax)
{
retryCount++;
await Task.Delay(retryWaitMs);
pin = await _api.GetPin(pinId);
}
}
return pin.authToken;
}
public async Task<PlexAccount> GetAccount(string accessToken)
{
return await _api.GetAccount(accessToken);
}
public async Task<Uri> GetOAuthUrl(int pinId, string code)
{
var settings = await _customizationSettingsService.GetSettingsAsync();
if (settings.ApplicationUrl.IsNullOrEmpty())
{
return null;
}
var url = _api.GetOAuthUrl(pinId, code, settings.ApplicationUrl, false);
return url;
}
public Uri GetWizardOAuthUrl(int pinId, string code, string websiteAddress)
{
var url = _api.GetOAuthUrl(pinId, code, websiteAddress, true);
return url;
}
}
}

@ -0,0 +1,16 @@
using System;
using System.Threading.Tasks;
using Ombi.Api.Plex.Models;
using Ombi.Api.Plex.Models.OAuth;
namespace Ombi.Core.Authentication
{
public interface IPlexOAuthManager
{
Task<string> GetAccessTokenFromPin(int pinId);
Task<OAuthPin> RequestPin();
Task<Uri> GetOAuthUrl(int pinId, string code);
Uri GetWizardOAuthUrl(int pinId, string code, string websiteAddress);
Task<PlexAccount> GetAccount(string accessToken);
}
}

@ -51,6 +51,7 @@ using Ombi.Store.Repository.Requests;
using Ombi.Updater;
using PlexContentCacher = Ombi.Schedule.Jobs.Plex;
using Ombi.Api.Telegram;
using Ombi.Core.Authentication;
using Ombi.Core.Processor;
using Ombi.Schedule.Jobs.Plex.Interfaces;
using Ombi.Schedule.Jobs.SickRage;
@ -82,6 +83,7 @@ namespace Ombi.DependencyInjection
services.AddTransient<IRecentlyAddedEngine, RecentlyAddedEngine>();
services.AddTransient<ITvSender, TvSender>();
services.AddTransient<IMassEmailSender, MassEmailSender>();
services.AddTransient<IPlexOAuthManager, PlexOAuthManager>();
}
public static void RegisterHttp(this IServiceCollection services)
{

@ -6,8 +6,8 @@ namespace Ombi.Core.Settings.Models.External
public sealed class PlexSettings : Ombi.Settings.Settings.Models.Settings
{
public bool Enable { get; set; }
public string UniqueInstallCode { get; set; }
public List<PlexServers> Servers { get; set; }
}
public class PlexServers : ExternalSettings

@ -18,6 +18,10 @@ export class AuthService extends ServiceHelpers {
return this.http.post(`${this.url}/`, JSON.stringify(login), {headers: this.headers});
}
public oAuth(pin: number): Observable<any> {
return this.http.get<any>(`${this.url}/${pin}`, {headers: this.headers});
}
public requiresPassword(login: IUserLogin): Observable<boolean> {
return this.http.post<boolean>(`${this.url}/requirePassword`, JSON.stringify(login), {headers: this.headers});
}

@ -2,6 +2,10 @@
user: IPlexUser;
}
export interface IPlexOAuthAccessToken {
accessToken: string;
}
export interface IPlexUser {
email: string;
uuid: string;

@ -4,3 +4,4 @@ export * from "./plex.service";
export * from "./radarr.service";
export * from "./sonarr.service";
export * from "./tester.service";
export * from "./plexoauth.service";

@ -29,4 +29,8 @@ export class PlexService extends ServiceHelpers {
public getFriends(): Observable<IUsersModel[]> {
return this.http.get<IUsersModel[]>(`${this.url}Friends`, {headers: this.headers});
}
public oAuth(wizard: boolean): Observable<any> {
return this.http.get<any>(`${this.url}oauth/${wizard}`, {headers: this.headers});
}
}

@ -0,0 +1,20 @@
import { PlatformLocation } from "@angular/common";
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Rx";
import { ServiceHelpers } from "../service.helpers";
import { IPlexOAuthAccessToken } from "../../interfaces";
@Injectable()
export class PlexOAuthService extends ServiceHelpers {
constructor(http: HttpClient, public platformLocation: PlatformLocation) {
super(http, "/api/v1/PlexOAuth/", platformLocation);
}
public oAuth(pin: number): Observable<IPlexOAuthAccessToken> {
return this.http.get<IPlexOAuthAccessToken>(`${this.url}${pin}`, {headers: this.headers});
}
}

@ -20,6 +20,13 @@
<button (click)="requestAuthToken()" class="btn btn-primary-outline">Request Token <i class="fa fa-key"></i></button>
</div>
</div>
<div class="form-group">
<div style="text-align: center; margin-top: 20px">
<button (click)="oauth()" class="btn btn-sucess">Sign In With Plex <i class="fa fa-key"></i></button>
</div>
</div>
</div>
</div>
</div>

@ -70,4 +70,12 @@ export class PlexComponent {
});
});
}
public oauth() {
this.plexService.oAuth(true).subscribe(x => {
if(x.url) {
window.location.href = x.url;
}
});
}
}

@ -0,0 +1,14 @@

<img class="landing-header" src="/images/logo.png" width="300" />
<div class="landing-block shadow">
<div class="media">
<div id="contentBody" class="media-body">
<h4 class="media-heading landing-title">Plex Authentication</h4>
<div class="form-group">
<label for="username" class="control-label">Please Wait</label>
</div>
</div>
</div>
</div>
<p-confirmDialog></p-confirmDialog>

@ -0,0 +1,76 @@
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { ConfirmationService } from "primeng/primeng";
import { PlexOAuthService, IdentityService, SettingsService } from "../../services";
import { AuthService } from "./../../auth/auth.service";
@Component({
templateUrl: "./plexoauth.component.html",
})
export class PlexOAuthComponent implements OnInit {
public pinId: number;
constructor(private route: ActivatedRoute,
private plexOauth: PlexOAuthService,
private confirmationService: ConfirmationService,
private identityService: IdentityService,
private settings: SettingsService,
private router: Router,
private auth: AuthService) {
this.route.params
.subscribe((params: any) => {
this.pinId = params.pin;
});
}
ngOnInit(): void {
this.plexOauth.oAuth(this.pinId).subscribe(x => {
x.accessToken;
this.confirmationService.confirm({
message: "Do you want your Plex user to be the main admin account on Ombi?",
header: "Use Plex Account",
icon: "fa fa-check",
accept: () => {
this.identityService.createWizardUser({
username: "",
password: "",
usePlexAdminAccount: true,
}).subscribe(x => {
if (x) {
this.auth.oAuth(this.pinId).subscribe(c => {
localStorage.setItem("id_token", c.access_token);
// Mark that we have done the settings now
this.settings.getOmbi().subscribe(ombi => {
ombi.wizard = true;
this.settings.saveOmbi(ombi).subscribe(x => {
this.settings.getUserManagementSettings().subscribe(usr => {
usr.importPlexAdmin = true;
this.settings.saveUserManagementSettings(usr).subscribe(saved => {
this.router.navigate(["login"]);
});
});
});
});
});
} else {
//this.notificationService.error("Could not get the Plex Admin Information");
return;
}
});
},
reject: () => {
this.router.navigate(["Wizard/CreateAdmin"]);
},
});
});
}
}

@ -14,6 +14,8 @@ import { WelcomeComponent } from "./welcome/welcome.component";
import { EmbyService } from "../services";
import { PlexService } from "../services";
import { IdentityService } from "../services";
import { PlexOAuthService } from "../services";
import { PlexOAuthComponent } from "./plex/plexoauth.component";
const routes: Routes = [
{ path: "", component: WelcomeComponent},
@ -21,6 +23,7 @@ const routes: Routes = [
{ path: "Plex", component: PlexComponent},
{ path: "Emby", component: EmbyComponent},
{ path: "CreateAdmin", component: CreateAdminComponent},
{ path: "OAuth/:pin", component: PlexOAuthComponent},
];
@NgModule({
imports: [
@ -33,6 +36,7 @@ const routes: Routes = [
WelcomeComponent,
MediaServerComponent,
PlexComponent,
PlexOAuthComponent,
CreateAdminComponent,
EmbyComponent,
],
@ -44,6 +48,7 @@ const routes: Routes = [
IdentityService,
EmbyService,
ConfirmationService,
PlexOAuthService,
],
})

@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging;
using Ombi.Api.Plex;
using Ombi.Api.Plex.Models;
using Ombi.Attributes;
using Ombi.Core.Authentication;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
@ -21,16 +22,18 @@ namespace Ombi.Controllers.External
public class PlexController : Controller
{
public PlexController(IPlexApi plexApi, ISettingsService<PlexSettings> plexSettings,
ILogger<PlexController> logger)
ILogger<PlexController> logger, IPlexOAuthManager manager)
{
PlexApi = plexApi;
PlexSettings = plexSettings;
_log = logger;
_plexOAuthManager = manager;
}
private IPlexApi PlexApi { get; }
private ISettingsService<PlexSettings> PlexSettings { get; }
private readonly ILogger<PlexController> _log;
private readonly IPlexOAuthManager _plexOAuthManager;
/// <summary>
/// Signs into the Plex API.
@ -66,6 +69,7 @@ namespace Ombi.Controllers.External
_log.LogDebug("Adding first server");
settings.Enable = true;
settings.UniqueInstallCode = Guid.NewGuid().ToString("N");
settings.Servers = new List<PlexServers> {
new PlexServers
{
@ -173,5 +177,37 @@ namespace Ombi.Controllers.External
// Filter out any dupes
return vm.DistinctBy(x => x.Id);
}
[HttpGet("oauth/{wizard:bool}")]
[AllowAnonymous]
public async Task<IActionResult> OAuth(bool wizard)
{
//https://app.plex.tv/auth#?forwardUrl=http://google.com/&clientID=Ombi-Test&context%5Bdevice%5D%5Bproduct%5D=Ombi%20SSO&pinID=798798&code=4lgfd
// Plex OAuth
// Redirect them to Plex
// We need a PIN first
var pin = await _plexOAuthManager.RequestPin();
Uri url;
if (!wizard)
{
url = await _plexOAuthManager.GetOAuthUrl(pin.id, pin.code);
}
else
{
var websiteAddress =$"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}";
url = _plexOAuthManager.GetWizardOAuthUrl(pin.id, pin.code, websiteAddress);
}
if (url == null)
{
return new JsonResult(new
{
error = "Application URL has not been set"
});
}
return new JsonResult(new {url = url.ToString()});
}
}
}

@ -1,9 +1,19 @@
using System.Net;
using System;
using System.Collections.Generic;
using System.Net;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http.Internal;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Ombi.Api.Plex;
using Ombi.Core.Authentication;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
namespace Ombi.Controllers
{
@ -12,29 +22,57 @@ namespace Ombi.Controllers
[AllowAnonymous]
public class PlexOAuthController : Controller
{
[HttpGet]
public IActionResult OAuthCallBack()
public PlexOAuthController(IPlexOAuthManager manager, IPlexApi plexApi, ISettingsService<PlexSettings> plexSettings,
ILogger<PlexOAuthController> log)
{
var bodyStr = "";
var req = Request;
_manager = manager;
_plexApi = plexApi;
_plexSettings = plexSettings;
_log = log;
}
// Allows using several time the stream in ASP.Net Core
req.EnableRewind();
private readonly IPlexOAuthManager _manager;
private readonly IPlexApi _plexApi;
private readonly ISettingsService<PlexSettings> _plexSettings;
private readonly ILogger _log;
// Arguments: Stream, Encoding, detect encoding, buffer size
// AND, the most important: keep stream opened
using (StreamReader reader
= new StreamReader(req.Body, Encoding.UTF8, true, 1024, true))
[HttpGet("{pinId:int}")]
public async Task<IActionResult> OAuthWizardCallBack([FromRoute] int pinId)
{
var accessToken = await _manager.GetAccessTokenFromPin(pinId);
if (accessToken.IsNullOrEmpty())
{
return Json(new
{
success = false,
error = "Authentication did not work. Please try again"
});
}
var settings = await _plexSettings.GetSettingsAsync();
var server = await _plexApi.GetServer(accessToken);
var servers = server.Server.FirstOrDefault();
if (servers == null)
{
bodyStr = reader.ReadToEnd();
_log.LogWarning("Looks like we can't find any Plex Servers");
}
_log.LogDebug("Adding first server");
// Rewind, so the core is not lost when it looks the body for the request
req.Body.Position = 0;
settings.Enable = true;
settings.Servers = new List<PlexServers> {
new PlexServers
{
PlexAuthToken = accessToken,
Id = new Random().Next(),
Ip = servers?.LocalAddresses?.Split(new []{','}, StringSplitOptions.RemoveEmptyEntries)?.FirstOrDefault() ?? string.Empty,
MachineIdentifier = servers?.MachineIdentifier ?? string.Empty,
Port = int.Parse(servers?.Port ?? "0"),
Ssl = (servers?.Scheme ?? "http") != "http",
Name = "Server 1",
}
};
// Do your work with bodyStr
return Ok();
await _plexSettings.SaveSettingsAsync(settings);
return Json(new { accessToken });
}
}
}

@ -142,7 +142,13 @@ namespace Ombi.Controllers
[HttpGet("plex")]
public async Task<PlexSettings> PlexSettings()
{
return await Get<PlexSettings>();
var s = await Get<PlexSettings>();
if (s.UniqueInstallCode.IsNullOrEmpty())
{
s.UniqueInstallCode = Guid.NewGuid().ToString("N");
}
return s;
}
/// <summary>

@ -25,18 +25,21 @@ namespace Ombi.Controllers
[Produces("application/json")]
public class TokenController
{
public TokenController(OmbiUserManager um, IOptions<TokenAuthentication> ta, IAuditRepository audit, ITokenRepository token)
public TokenController(OmbiUserManager um, IOptions<TokenAuthentication> ta, IAuditRepository audit, ITokenRepository token,
IPlexOAuthManager oAuthManager)
{
_userManager = um;
_tokenAuthenticationOptions = ta.Value;
_audit = audit;
_token = token;
_plexOAuthManager = oAuthManager;
}
private readonly TokenAuthentication _tokenAuthenticationOptions;
private readonly IAuditRepository _audit;
private readonly ITokenRepository _token;
private readonly OmbiUserManager _userManager;
private readonly IPlexOAuthManager _plexOAuthManager;
/// <summary>
/// Gets the token.
@ -69,63 +72,99 @@ namespace Ombi.Controllers
// Verify Password
if (await _userManager.CheckPasswordAsync(user, model.Password))
{
var roles = await _userManager.GetRolesAsync(user);
if (roles.Contains(OmbiRoles.Disabled))
{
return new UnauthorizedResult();
}
user.LastLoggedIn = DateTime.UtcNow;
await _userManager.UpdateAsync(user);
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(ClaimTypes.NameIdentifier, user.Id),
new Claim(ClaimTypes.Name, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
claims.AddRange(roles.Select(role => new Claim("role", role)));
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_tokenAuthenticationOptions.SecretKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
claims: claims,
expires: model.RememberMe ? DateTime.UtcNow.AddDays(7) : DateTime.UtcNow.AddHours(5),
signingCredentials: creds,
audience: "Ombi", issuer: "Ombi"
);
var accessToken = new JwtSecurityTokenHandler().WriteToken(token);
if (model.RememberMe)
{
// Save the token so we can refresh it later
//await _token.CreateToken(new Tokens() {Token = accessToken, User = user});
}
return await CreateToken(model.RememberMe, user);
}
}
else
{
// Plex OAuth
// Redirect them to Plex
// We need a PIN first
var pin = await _plexOAuthManager.RequestPin();
//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(pin.id, pin.code);
if (url == null)
{
return new JsonResult(new
{
access_token = accessToken,
expiration = token.ValidTo
error = "Application URL has not been set"
});
}
return new RedirectResult(url.ToString());
}
else
return new UnauthorizedResult();
}
private async Task<IActionResult> CreateToken(bool rememberMe, OmbiUser user)
{
var roles = await _userManager.GetRolesAsync(user);
if (roles.Contains(OmbiRoles.Disabled))
{
// Plex OAuth
// Redirect them to Plex
return new UnauthorizedResult();
}
var request = new Request("auth", "https://app.plex.tv", HttpMethod.Get);
request.AddQueryString("clientID", "OMBIv3");
request.AddQueryString("forwardUrl", "http://localhost:5000");
request.AddQueryString("context-device-product", "http://localhost:5000");
return new RedirectResult("https://app.plex.tv/auth#?forwardUrl=http://localhost:5000/api/v1/plexoauth&clientID=OMBIv3&context%5Bdevice%5D%5Bproduct%5D=Ombi%20SSO");
user.LastLoggedIn = DateTime.UtcNow;
await _userManager.UpdateAsync(user);
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(ClaimTypes.NameIdentifier, user.Id),
new Claim(ClaimTypes.Name, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
claims.AddRange(roles.Select(role => new Claim("role", role)));
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_tokenAuthenticationOptions.SecretKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
claims: claims,
expires: rememberMe ? DateTime.UtcNow.AddDays(7) : DateTime.UtcNow.AddHours(5),
signingCredentials: creds,
audience: "Ombi", issuer: "Ombi"
);
var accessToken = new JwtSecurityTokenHandler().WriteToken(token);
if (rememberMe)
{
// Save the token so we can refresh it later
//await _token.CreateToken(new Tokens() {Token = accessToken, User = user});
}
return new UnauthorizedResult();
return new JsonResult(new
{
access_token = accessToken,
expiration = token.ValidTo
});
}
[HttpGet("{pinId:int}")]
public async Task<IActionResult> OAuth(int pinId)
{
var accessToken = await _plexOAuthManager.GetAccessTokenFromPin(pinId);
// Let's look for the users account
var account = await _plexOAuthManager.GetAccount(accessToken);
// Get the ombi user
var user = await _userManager.FindByNameAsync(account.user.username);
if (user == null)
{
// Could this be an email login?
user = await _userManager.FindByEmailAsync(account.user.email);
if (user == null)
{
return new UnauthorizedResult();
}
}
return await CreateToken(true, user);
}
/// <summary>

Loading…
Cancel
Save