|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|