2018-09-04 13:39:07 +01:00
|
|
|
using System;
|
2018-08-24 13:10:13 +01:00
|
|
|
using System.Collections.Generic;
|
2018-09-21 13:45:14 +01:00
|
|
|
using System.Net.Http;
|
2018-08-24 13:10:13 +01:00
|
|
|
using System.Text;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
using SpotifyAPI.Web.Enums;
|
|
|
|
using SpotifyAPI.Web.Models;
|
|
|
|
using Unosquare.Labs.EmbedIO;
|
|
|
|
using Unosquare.Labs.EmbedIO.Constants;
|
|
|
|
using Unosquare.Labs.EmbedIO.Modules;
|
|
|
|
|
|
|
|
namespace SpotifyAPI.Web.Auth
|
|
|
|
{
|
|
|
|
public class AuthorizationCodeAuth : SpotifyAuthServer<AuthorizationCode>
|
|
|
|
{
|
|
|
|
public string SecretId { get; set; }
|
2019-07-17 16:39:51 +01:00
|
|
|
|
|
|
|
public ProxyConfig ProxyConfig { get; set; }
|
2018-08-24 13:10:13 +01:00
|
|
|
|
|
|
|
public AuthorizationCodeAuth(string redirectUri, string serverUri, Scope scope = Scope.None, string state = "")
|
|
|
|
: base("code", "AuthorizationCodeAuth", redirectUri, serverUri, scope, state)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public AuthorizationCodeAuth(string clientId, string secretId, string redirectUri, string serverUri, Scope scope = Scope.None, string state = "")
|
|
|
|
: this(redirectUri, serverUri, scope, state)
|
|
|
|
{
|
|
|
|
ClientId = clientId;
|
|
|
|
SecretId = secretId;
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool ShouldRegisterNewApp()
|
|
|
|
{
|
|
|
|
return string.IsNullOrEmpty(SecretId) || string.IsNullOrEmpty(ClientId);
|
|
|
|
}
|
|
|
|
|
|
|
|
public override string GetUri()
|
|
|
|
{
|
|
|
|
return ShouldRegisterNewApp() ? $"{RedirectUri}/start.html#{State}" : base.GetUri();
|
|
|
|
}
|
|
|
|
|
2018-12-22 20:12:57 +00:00
|
|
|
protected override void AdaptWebServer(WebServer webServer)
|
2018-09-21 13:45:14 +01:00
|
|
|
{
|
2018-12-22 20:12:57 +00:00
|
|
|
webServer.Module<WebApiModule>().RegisterController<AuthorizationCodeAuthController>();
|
2018-09-21 13:45:14 +01:00
|
|
|
}
|
2018-08-24 13:10:13 +01:00
|
|
|
|
2018-09-21 13:45:14 +01:00
|
|
|
private string GetAuthHeader() => $"Basic {Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientId + ":" + SecretId))}";
|
|
|
|
|
|
|
|
public async Task<Token> RefreshToken(string refreshToken)
|
2018-08-24 13:10:13 +01:00
|
|
|
{
|
2019-03-18 20:24:09 +00:00
|
|
|
List<KeyValuePair<string, string>> args = new List<KeyValuePair<string, string>>
|
2018-09-21 13:45:14 +01:00
|
|
|
{
|
|
|
|
new KeyValuePair<string, string>("grant_type", "refresh_token"),
|
|
|
|
new KeyValuePair<string, string>("refresh_token", refreshToken)
|
|
|
|
};
|
2018-08-24 13:10:13 +01:00
|
|
|
|
2019-07-30 17:54:02 +01:00
|
|
|
return await GetToken(args);
|
2018-09-21 13:45:14 +01:00
|
|
|
}
|
2019-07-30 17:54:02 +01:00
|
|
|
|
2018-09-21 13:45:14 +01:00
|
|
|
public async Task<Token> ExchangeCode(string code)
|
|
|
|
{
|
2019-03-18 20:24:09 +00:00
|
|
|
List<KeyValuePair<string, string>> args = new List<KeyValuePair<string, string>>
|
2018-08-24 13:10:13 +01:00
|
|
|
{
|
|
|
|
new KeyValuePair<string, string>("grant_type", "authorization_code"),
|
|
|
|
new KeyValuePair<string, string>("code", code),
|
|
|
|
new KeyValuePair<string, string>("redirect_uri", RedirectUri)
|
|
|
|
};
|
|
|
|
|
2019-07-30 17:54:02 +01:00
|
|
|
return await GetToken(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
private async Task<Token> GetToken(IEnumerable<KeyValuePair<string, string>> args)
|
|
|
|
{
|
|
|
|
HttpClientHandler handler = ProxyConfig.CreateClientHandler(ProxyConfig);
|
|
|
|
HttpClient client = new HttpClient(handler);
|
2018-09-21 13:45:14 +01:00
|
|
|
client.DefaultRequestHeaders.Add("Authorization", GetAuthHeader());
|
2018-08-24 13:10:13 +01:00
|
|
|
HttpContent content = new FormUrlEncodedContent(args);
|
|
|
|
|
|
|
|
HttpResponseMessage resp = await client.PostAsync("https://accounts.spotify.com/api/token", content);
|
|
|
|
string msg = await resp.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
return JsonConvert.DeserializeObject<Token>(msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class AuthorizationCode
|
|
|
|
{
|
|
|
|
public string Code { get; set; }
|
|
|
|
|
|
|
|
public string Error { get; set; }
|
|
|
|
}
|
|
|
|
|
|
|
|
internal class AuthorizationCodeAuthController : WebApiController
|
|
|
|
{
|
|
|
|
[WebApiHandler(HttpVerbs.Get, "/")]
|
2018-12-22 20:12:57 +00:00
|
|
|
public Task<bool> GetEmpty()
|
2018-08-24 13:10:13 +01:00
|
|
|
{
|
2018-12-22 20:12:57 +00:00
|
|
|
string state = Request.QueryString["state"];
|
2018-08-24 13:10:13 +01:00
|
|
|
AuthorizationCodeAuth.Instances.TryGetValue(state, out SpotifyAuthServer<AuthorizationCode> auth);
|
|
|
|
|
|
|
|
string code = null;
|
2018-12-22 20:12:57 +00:00
|
|
|
string error = Request.QueryString["error"];
|
2018-08-24 13:10:13 +01:00
|
|
|
if (error == null)
|
2018-12-22 20:12:57 +00:00
|
|
|
code = Request.QueryString["code"];
|
2018-08-24 13:10:13 +01:00
|
|
|
|
|
|
|
Task.Factory.StartNew(() => auth?.TriggerAuth(new AuthorizationCode
|
|
|
|
{
|
|
|
|
Code = code,
|
|
|
|
Error = error
|
|
|
|
}));
|
2018-12-22 20:12:57 +00:00
|
|
|
|
2019-06-03 14:18:10 +01:00
|
|
|
return HttpContext.HtmlResponseAsync("<html><script type=\"text/javascript\">window.close();</script>OK - This window can be closed now</html>");
|
2018-08-24 13:10:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
[WebApiHandler(HttpVerbs.Post, "/")]
|
2019-02-19 21:18:24 +00:00
|
|
|
public async Task<bool> PostValues()
|
2018-08-24 13:10:13 +01:00
|
|
|
{
|
2019-06-03 14:18:10 +01:00
|
|
|
Dictionary<string, object> formParams = await HttpContext.RequestFormDataDictionaryAsync();
|
2018-08-24 13:10:13 +01:00
|
|
|
|
|
|
|
string state = (string) formParams["state"];
|
|
|
|
AuthorizationCodeAuth.Instances.TryGetValue(state, out SpotifyAuthServer<AuthorizationCode> authServer);
|
|
|
|
|
|
|
|
AuthorizationCodeAuth auth = (AuthorizationCodeAuth) authServer;
|
|
|
|
auth.ClientId = (string) formParams["clientId"];
|
|
|
|
auth.SecretId = (string) formParams["secretId"];
|
|
|
|
|
|
|
|
string uri = auth.GetUri();
|
2019-06-03 14:18:10 +01:00
|
|
|
return HttpContext.Redirect(uri, false);
|
2018-12-22 20:12:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public AuthorizationCodeAuthController(IHttpContext context) : base(context)
|
|
|
|
{
|
2018-08-24 13:10:13 +01:00
|
|
|
}
|
|
|
|
}
|
2018-09-04 13:39:07 +01:00
|
|
|
}
|