yellowcab/spotify/auth.go

74 lines
1.9 KiB
Go

package spotify
import (
"crypto/rand"
"encoding/hex"
"fmt"
"log"
"net/http"
"os"
"git.gay/besties/yellowcab/db"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/adaptor"
spotifysdk "github.com/zmb3/spotify/v2"
spotifyauth "github.com/zmb3/spotify/v2/auth"
)
var (
redirectURI = os.Getenv("BASE_URL") + "/spotifyauth/callback"
auth = spotifyauth.New(spotifyauth.WithRedirectURL(redirectURI), spotifyauth.WithScopes(spotifyauth.ScopeUserReadCurrentlyPlaying+" "+spotifyauth.ScopeUserReadPlaybackState+" "+spotifyauth.ScopeUserReadRecentlyPlayed))
)
func SpotifyAuthHandler(c *fiber.Ctx) error {
stateBytes := make([]byte, 60)
_, err := rand.Read(stateBytes)
if err != nil {
return err
}
state := hex.EncodeToString(stateBytes)
c.Cookie(&fiber.Cookie{
Name: "state",
Value: state,
})
return c.Redirect(auth.AuthURL(state))
}
func CompleteSpotifyAuth(c *fiber.Ctx) error {
fmt.Println("Doing spotify auth, got request")
state := c.Cookies("state")
httpReq, err := adaptor.ConvertRequest(c, false)
if err != nil {
return err
}
tok, err := auth.Token(c.Context(), state, httpReq)
if err != nil {
c.Status(http.StatusForbidden)
return fmt.Errorf("Couldn't get token: %w\n", err)
}
if st := c.FormValue("state"); st != state {
c.Status(http.StatusBadRequest)
return fmt.Errorf("State mismatch: %s != %s\n", st, state)
}
fmt.Println("Got user's token")
// use the token to get an authenticated client
client := spotifysdk.New(auth.Client(c.Context(), tok))
fmt.Println("Login Completed!")
user, usererr := client.CurrentUser(c.Context())
if usererr != nil {
log.Fatalf("Error getting user: %s", usererr)
}
err = db.SetRefreshToken(user.ID, tok.RefreshToken)
if err != nil {
log.Fatal("Error inserting user token into database")
}
fmt.Println("Inserted refresh token into database!")
// redirect back to main page
c.Redirect(os.Getenv("BASE_URL"), http.StatusFound)
return nil
}