package auth import ( "context" "fmt" "net/http" "gitea.ravianand.me/Dan6erbond/listy/core" "gitea.ravianand.me/Dan6erbond/listy/internal" "gitea.ravianand.me/Dan6erbond/listy/users" "github.com/spf13/viper" "github.com/zmb3/spotify/v2" ) func RegisterRoutes(app *core.App) { app.Mux.Get("/auth/oidc/spotify/redirect", Redirect(app)) app.Mux.Get("/auth/oidc/spotify/callback", Callback(app)) } func Redirect(app *core.App) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { state, _ := internal.GenerateRandomString(16) session, _ := app.SessionStore.Get(r, "oidc") session.Values["state"] = state if err := session.Save(r, w); err != nil { fmt.Println(err) http.Error(w, err.Error(), http.StatusInternalServerError) return } url := app.SpotifyAuth.AuthURL(state) http.Redirect(w, r, url, http.StatusSeeOther) } } func Callback(app *core.App) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { ctx := context.Background() session, _ := app.SessionStore.Get(r, "oidc") state, ok := session.Values["state"] if !ok { http.Error(w, "No state found", http.StatusInternalServerError) return } // use the same state string here that you used to generate the URL token, err := app.SpotifyAuth.Token(r.Context(), state.(string), r) if err != nil || token == nil { fmt.Println(err) http.Error(w, "Couldn't get token", http.StatusInternalServerError) return } spotifyClient := spotify.New(app.SpotifyAuth.Client(r.Context(), token)) user, err := spotifyClient.CurrentUser(ctx) if err != nil { fmt.Println(err) http.Error(w, "Couldn't get current user", http.StatusInternalServerError) return } var allowUser bool if allowUserIDs := viper.GetStringSlice("alloweduserids"); len(viper.GetStringSlice("alloweduserids")) != 0 { for _, userID := range allowUserIDs { if user.ID == userID { allowUser = true break } } } else { allowUser = true } if !allowUser { http.Error(w, "You aren't allowed to access this application", http.StatusUnauthorized) return } _, err = users.SaveUserToken(ctx, app, user.ID, token) if err != nil { fmt.Println(err) http.Error(w, "Couldn't save token", http.StatusInternalServerError) return } app.Render.JSON(w, 200, user) } }