// Refresh fetches new auth tokens for an existing session that has // expired. func Refresh(globalContext *context.GlobalContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { localContext := context.Get(r) tokens, err := spotify.RefreshAuthTokens( localContext.AuthTokens, globalContext.Spotify.ClientID, globalContext.Spotify.ClientSecret, ) if err != nil { panic(err) } data := map[string]interface{}{ "expires_in": tokens.ExpiresIn, } jsonToken, err := json.Marshal(tokens) if err != nil { panic(err) } token, err := crypto.Encrypt(string(jsonToken)) if err != nil { panic(err) } data["token"] = token w.Header().Set("Content-type", "application/json") err = json.NewEncoder(w).Encode(data) if err != nil { panic(err) } } }
// Login handles login responses from the Spotify API func Login(globalContext *context.GlobalContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { csrfJSON, err := crypto.Decrypt(r.URL.Query().Get("state")) if err != nil { panic(err) } csrf := make(map[string]string) err = json.Unmarshal([]byte(csrfJSON), &csrf) if err != nil { panic(err) } if ip, ok := csrf["IP"]; !ok || ip != util.StripPort(r.RemoteAddr) { panic(errors.New("CSRF mismatch")) } if a, ok := csrf["User-Agent"]; !ok || a != r.Header.Get("User-Agent") { panic(errors.New("CSRF mismatch")) } data := map[string]interface{}{ "error": r.URL.Query().Get("error"), } if r.URL.Query().Get("error") == "" { redirectURI, err := loginURI(globalContext, r.Host) if err != nil { panic(err) } tokens, err := spotify.GetAuthTokens( globalContext.Spotify.ClientID, globalContext.Spotify.ClientSecret, r.URL.Query().Get("code"), redirectURI, ) data["expires_in"] = tokens.ExpiresIn jsonToken, err := json.Marshal(tokens) if err != nil { panic(err) } token, err := crypto.Encrypt(string(jsonToken)) if err != nil { panic(err) } data["token"] = token } err = globalContext.Templates.Login.Execute(w, data) if err != nil { panic(err) } } }
// Index renders the homepage. func Index(globalContext *context.GlobalContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { csrfData := map[string]string{ "User-Agent": r.Header.Get("User-Agent"), "IP": util.StripPort(r.RemoteAddr), } csrfPlaintext, err := json.Marshal(csrfData) if err != nil { panic(err) } csrfToken, err := crypto.Encrypt(string(csrfPlaintext)) loginCompletionURI, err := loginURI(globalContext, r.Host) if err != nil { panic(err) } loginURI, err := spotify.GetLoginURI( globalContext.Spotify.ClientID, csrfToken, loginCompletionURI, ) if err != nil { panic(err) } refreshURI, err := globalContext.Router.Get("refresh").URL() if err != nil { panic(err) } playlistsURI, err := globalContext.Router.Get("playlists").URL() if err != nil { panic(err) } submitURI, err := globalContext.Router.Get("submit").URL() if err != nil { panic(err) } err = globalContext.Templates.Index.Execute( w, map[string]interface{}{ "loginURI": loginURI.String(), "refreshURI": refreshURI.String(), "playlistsURI": playlistsURI.String(), "submitURI": submitURI.String(), }, ) if err != nil { panic(err) } } }