package core import ( "context" "net/http" "net/url" mongodbstore "github.com/2-72/gorilla-sessions-mongodb" "github.com/go-chi/chi" "github.com/gorilla/sessions" "github.com/spf13/viper" "github.com/unrolled/render" spotifyauth "github.com/zmb3/spotify/v2/auth" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "golang.org/x/oauth2" "gopkg.in/mgo.v2" ) type App struct { MongoClient *mongo.Client MgoClient *mgo.Session SpotifyAuth *spotifyauth.Authenticator SpotifyOAuthConfig *oauth2.Config Mux *chi.Mux SessionStore sessions.Store Render *render.Render } func (a App) Run() { http.ListenAndServe(":5001", a.Mux) } func (a App) Shutdown() error { if err := a.MongoClient.Disconnect(context.TODO()); err != nil { return err } return nil } func NewApp() *App { serverAPI := options.ServerAPI(options.ServerAPIVersion1) opts := options.Client().ApplyURI(viper.GetString("mongodb.uri")).SetServerAPIOptions(serverAPI) // Create a new client and connect to the server client, err := mongo.Connect(context.TODO(), opts) if err != nil { panic(err) } store, err := mongodbstore.NewMongoDBStore(client.Database("listy").Collection("sessions"), []byte(viper.GetString("server.sessionkey"))) if err != nil { panic(err) } redirectURL := url.URL{ Scheme: viper.GetString("server.scheme"), Host: viper.GetString("server.host"), Path: "/auth/oidc/spotify/callback", } auth := spotifyauth.New( spotifyauth.WithRedirectURL(redirectURL.String()), spotifyauth.WithClientID(viper.GetString("spotify.clientid")), spotifyauth.WithClientSecret(viper.GetString("spotify.clientsecret")), spotifyauth.WithScopes( spotifyauth.ScopeUserReadPrivate, spotifyauth.ScopePlaylistReadPrivate, spotifyauth.ScopeUserLibraryRead, spotifyauth.ScopePlaylistModifyPrivate, spotifyauth.ScopePlaylistModifyPublic, )) authConfig := &oauth2.Config{ ClientID: viper.GetString("spotify.clientid"), ClientSecret: viper.GetString("spotify.clientsecret"), Endpoint: oauth2.Endpoint{ AuthURL: spotifyauth.AuthURL, TokenURL: spotifyauth.TokenURL, }, } mux := NewMux() r := render.New() app := &App{ MongoClient: client, SpotifyAuth: auth, SpotifyOAuthConfig: authConfig, Mux: mux, SessionStore: store, Render: r, } return app }