using Newtonsoft.Json; using SpotifyAPI.Web.Enums; using SpotifyAPI.Web.Models; using System; using System.Collections.Specialized; using System.Diagnostics; using System.IO; using System.Net; using System.Text; using System.Threading; namespace SpotifyAPI.Web.Auth { public class AutorizationCodeAuth { public delegate void OnResponseReceived(AutorizationCodeAuthResponse response); private SimpleHttpServer _httpServer; private Thread _httpThread; public String ClientId { get; set; } public String RedirectUri { get; set; } public String State { get; set; } public Scope Scope { get; set; } public Boolean ShowDialog { get; set; } /// /// Will be fired once the user authenticated /// public event OnResponseReceived OnResponseReceivedEvent; /// /// Start the auth process (Make sure the internal HTTP-Server ist started) /// public void DoAuth() { String uri = GetUri(); Process.Start(uri); } /// /// Refreshes auth by providing the clientsecret (Don't use this if you're on a client) /// /// The refresh-token of the earlier gathered token /// Your Client-Secret, don't provide it if this is running on a client! public Token RefreshToken(string refreshToken, string clientSecret) { using (WebClient wc = new WebClient()) { wc.Proxy = null; wc.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientId + ":" + clientSecret))); NameValueCollection col = new NameValueCollection { {"grant_type", "refresh_token"}, {"refresh_token", refreshToken} }; String response; try { byte[] data = wc.UploadValues("https://accounts.spotify.com/api/token", "POST", col); response = Encoding.UTF8.GetString(data); } catch (WebException e) { using (StreamReader reader = new StreamReader(e.Response.GetResponseStream())) { response = reader.ReadToEnd(); } } return JsonConvert.DeserializeObject(response); } } private String GetUri() { StringBuilder builder = new StringBuilder("https://accounts.spotify.com/authorize/?"); builder.Append("client_id=" + ClientId); builder.Append("&response_type=code"); builder.Append("&redirect_uri=" + RedirectUri); builder.Append("&state=" + State); builder.Append("&scope=" + Scope.GetStringAttribute(" ")); builder.Append("&show_dialog=" + ShowDialog); return builder.ToString(); } /// /// Start the internal HTTP-Server /// public void StartHttpServer(int port = 80) { _httpServer = new SimpleHttpServer(port, AuthType.Authorization); _httpServer.OnAuth += HttpServerOnOnAuth; _httpThread = new Thread(_httpServer.Listen); _httpThread.Start(); } private void HttpServerOnOnAuth(AuthEventArgs e) { if (OnResponseReceivedEvent != null) OnResponseReceivedEvent(new AutorizationCodeAuthResponse() { Code = e.Code, State = e.State, Error = e.Error }); } /// /// This will stop the internal HTTP-Server (Should be called after you got the Token) /// public void StopHttpServer() { _httpServer = null; } /// /// Exchange a code for a Token (Don't use this if you're on a client) /// /// The gathered code from the response /// Your Client-Secret, don't provide it if this is running on a client! /// public Token ExchangeAuthCode(String code, String clientSecret) { using (WebClient wc = new WebClient()) { wc.Proxy = null; NameValueCollection col = new NameValueCollection { {"grant_type", "authorization_code"}, {"code", code}, {"redirect_uri", RedirectUri}, {"client_id", ClientId}, {"client_secret", clientSecret} }; String response; try { byte[] data = wc.UploadValues("https://accounts.spotify.com/api/token", "POST", col); response = Encoding.UTF8.GetString(data); } catch (WebException e) { using (StreamReader reader = new StreamReader(e.Response.GetResponseStream())) { response = reader.ReadToEnd(); } } return JsonConvert.DeserializeObject(response); } } } public struct AutorizationCodeAuthResponse { public String Code { get; set; } public String State { get; set; } public String Error { get; set; } } }