2016-07-19 20:15:22 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using SpotifyAPI.Web.Enums;
|
|
|
|
|
using SpotifyAPI.Web.Models;
|
|
|
|
|
|
|
|
|
|
namespace SpotifyAPI.Web.Auth
|
|
|
|
|
{
|
2016-07-29 23:19:57 +01:00
|
|
|
|
public class WebAPIFactory
|
2016-07-19 20:15:22 +01:00
|
|
|
|
{
|
2016-07-29 23:19:57 +01:00
|
|
|
|
private readonly string _redirectUrl;
|
|
|
|
|
private readonly int _listeningPort;
|
|
|
|
|
private readonly string _clientId;
|
|
|
|
|
private readonly TimeSpan _timeout;
|
|
|
|
|
private readonly Scope _scope;
|
2018-03-25 18:39:19 +01:00
|
|
|
|
private readonly ProxyConfig _proxyConfig;
|
2016-07-31 15:13:08 +01:00
|
|
|
|
private readonly string _xss;
|
2016-07-19 20:15:22 +01:00
|
|
|
|
|
2016-07-31 15:13:08 +01:00
|
|
|
|
public WebAPIFactory(string redirectUrl, int listeningPort, string clientId, Scope scope)
|
2018-03-25 18:39:19 +01:00
|
|
|
|
: this(redirectUrl, listeningPort, clientId, scope, null)
|
2016-07-31 15:13:08 +01:00
|
|
|
|
{
|
2018-03-25 18:39:19 +01:00
|
|
|
|
}
|
2016-07-31 15:13:08 +01:00
|
|
|
|
|
2018-03-25 18:39:19 +01:00
|
|
|
|
public WebAPIFactory(string redirectUrl, int listeningPort, string clientId, Scope scope, ProxyConfig proxyConfig)
|
|
|
|
|
: this(redirectUrl, listeningPort, clientId, scope, TimeSpan.FromSeconds(20), proxyConfig)
|
|
|
|
|
{
|
2016-07-31 15:13:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public WebAPIFactory(string redirectUrl, int listeningPort, string clientId, Scope scope, TimeSpan timeout, string xss = "XSS")
|
2018-03-25 18:39:19 +01:00
|
|
|
|
: this(redirectUrl, listeningPort, clientId, scope, timeout, null, xss)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public WebAPIFactory(string redirectUrl, int listeningPort, string clientId, Scope scope, TimeSpan timeout, ProxyConfig proxyConfig, string xss = "XSS")
|
2016-07-19 20:15:22 +01:00
|
|
|
|
{
|
2016-07-29 23:19:57 +01:00
|
|
|
|
_redirectUrl = redirectUrl;
|
|
|
|
|
_listeningPort = listeningPort;
|
|
|
|
|
_clientId = clientId;
|
|
|
|
|
_scope = scope;
|
|
|
|
|
_timeout = timeout;
|
2018-03-25 18:39:19 +01:00
|
|
|
|
_proxyConfig = proxyConfig;
|
2016-07-31 15:13:08 +01:00
|
|
|
|
_xss = xss;
|
2016-07-19 20:15:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-24 16:19:06 +01:00
|
|
|
|
public Task<SpotifyWebAPI> GetWebApi(bool showDialog = false)
|
2016-07-19 20:15:22 +01:00
|
|
|
|
{
|
|
|
|
|
var authentication = new ImplicitGrantAuth
|
|
|
|
|
{
|
2017-06-10 20:50:16 +01:00
|
|
|
|
RedirectUri = new UriBuilder(_redirectUrl) { Port = _listeningPort }.Uri.OriginalString.TrimEnd('/'),
|
2016-07-29 23:19:57 +01:00
|
|
|
|
ClientId = _clientId,
|
|
|
|
|
Scope = _scope,
|
2018-04-24 16:19:06 +01:00
|
|
|
|
ShowDialog = showDialog,
|
2016-07-31 15:13:08 +01:00
|
|
|
|
State = _xss
|
2016-07-19 20:15:22 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
AutoResetEvent authenticationWaitFlag = new AutoResetEvent(false);
|
|
|
|
|
SpotifyWebAPI spotifyWebApi = null;
|
|
|
|
|
authentication.OnResponseReceivedEvent += (token, state) =>
|
|
|
|
|
{
|
|
|
|
|
spotifyWebApi = HandleSpotifyResponse(state, token);
|
|
|
|
|
authenticationWaitFlag.Set();
|
|
|
|
|
};
|
|
|
|
|
|
2016-07-20 08:56:05 +01:00
|
|
|
|
try
|
|
|
|
|
{
|
2016-07-29 23:19:57 +01:00
|
|
|
|
authentication.StartHttpServer(_listeningPort);
|
2016-07-19 20:15:22 +01:00
|
|
|
|
|
2016-07-20 08:56:05 +01:00
|
|
|
|
authentication.DoAuth();
|
2016-07-19 20:15:22 +01:00
|
|
|
|
|
2016-07-29 23:19:57 +01:00
|
|
|
|
authenticationWaitFlag.WaitOne(_timeout);
|
2016-07-20 08:56:05 +01:00
|
|
|
|
if (spotifyWebApi == null)
|
2016-07-29 23:19:57 +01:00
|
|
|
|
throw new TimeoutException($"No valid response received for the last {_timeout.TotalSeconds} seconds");
|
2016-07-20 08:56:05 +01:00
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
authentication.StopHttpServer();
|
|
|
|
|
}
|
2016-07-19 20:15:22 +01:00
|
|
|
|
|
|
|
|
|
return Task.FromResult(spotifyWebApi);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-31 15:13:08 +01:00
|
|
|
|
private SpotifyWebAPI HandleSpotifyResponse(string state, Token token)
|
2016-07-19 20:15:22 +01:00
|
|
|
|
{
|
2016-07-31 15:13:08 +01:00
|
|
|
|
if (state != _xss)
|
2016-07-19 20:15:22 +01:00
|
|
|
|
throw new SpotifyWebApiException($"Wrong state '{state}' received.");
|
|
|
|
|
|
|
|
|
|
if (token.Error != null)
|
|
|
|
|
throw new SpotifyWebApiException($"Error: {token.Error}");
|
|
|
|
|
|
2018-03-25 18:39:19 +01:00
|
|
|
|
var spotifyWebApi = new SpotifyWebAPI(_proxyConfig)
|
2016-07-19 20:15:22 +01:00
|
|
|
|
{
|
|
|
|
|
UseAuth = true,
|
|
|
|
|
AccessToken = token.AccessToken,
|
|
|
|
|
TokenType = token.TokenType
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return spotifyWebApi;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
public class SpotifyWebApiException : Exception
|
|
|
|
|
{
|
|
|
|
|
public SpotifyWebApiException(string message) : base(message)
|
|
|
|
|
{ }
|
|
|
|
|
}
|
|
|
|
|
}
|