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