Skip to content

Commit aa71d70

Browse files
committedOct 8, 2024
refactored config into struct and added http basic auth
1 parent efe0d80 commit aa71d70

File tree

5 files changed

+85
-36
lines changed

5 files changed

+85
-36
lines changed
 

‎config.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package main
2+
3+
import (
4+
"time"
5+
6+
"github.com/spf13/viper"
7+
)
8+
9+
type Config struct {
10+
Spotify_client_id string `mapstructure:"spotify_client_id"`
11+
Spotify_client_secret string `mapstructure:"spotify_client_secret"`
12+
Db_path string `mapstructure:"db_path"`
13+
Port string `mapstructure:"port"`
14+
Log_level string `mapstructure:"log_level"`
15+
Redirect_url string `mapstructure:"redirect_url"`
16+
Shutdown_timeout time.Duration `mapstructure:"shutdown_timeout"`
17+
Users map[string]string `mapstructure:"users"`
18+
}
19+
20+
func read_config() (Config, error) {
21+
viper.SetDefault("spotify_client_id", "")
22+
viper.SetDefault("spotify_client_secret", "")
23+
viper.SetDefault("db_path", "ffs.db")
24+
viper.SetDefault("port", "8080")
25+
viper.SetDefault("log_level", "INFO")
26+
viper.SetDefault("redirect_url", "http://localhost:8080/spotifyauthentication")
27+
viper.SetDefault("shutdown_timeout", time.Second*10)
28+
viper.SetDefault("users", map[string]string{})
29+
30+
viper.SetEnvPrefix("ffs")
31+
viper.AutomaticEnv()
32+
33+
viper.AddConfigPath(".")
34+
viper.SetConfigName("ffs_config")
35+
viper.SetConfigType("yaml")
36+
37+
if err := viper.ReadInConfig(); err != nil {
38+
panic(err)
39+
}
40+
41+
var config Config
42+
err := viper.Unmarshal(&config)
43+
return config, err
44+
}

‎main.go

+13-31
Original file line numberDiff line numberDiff line change
@@ -11,41 +11,18 @@ import (
1111
"os/signal"
1212
"strings"
1313
"syscall"
14-
"time"
1514

1615
"github.com/bafto/FindFavouriteSong/db"
1716
"github.com/gorilla/securecookie"
1817
"github.com/gorilla/sessions"
19-
"github.com/spf13/viper"
2018
"github.com/zmb3/spotify/v2"
2119
spotifyauth "github.com/zmb3/spotify/v2/auth"
2220
)
2321

24-
func read_config() {
25-
viper.SetDefault("spotify_client_id", "")
26-
viper.SetDefault("spotify_client_secret", "")
27-
viper.SetDefault("db_path", "ffs.db")
28-
viper.SetDefault("port", "8080")
29-
viper.SetDefault("log_level", "INFO")
30-
viper.SetDefault("redirect_url", "http://localhost:8080/spotifyauthentication")
31-
viper.SetDefault("shutdown_timeout", time.Second*10)
32-
33-
viper.SetEnvPrefix("ffs")
34-
viper.AutomaticEnv()
35-
36-
viper.AddConfigPath(".")
37-
viper.SetConfigName("ffs_config")
38-
viper.SetConfigType("yaml")
39-
40-
if err := viper.ReadInConfig(); err != nil {
41-
panic(err)
42-
}
43-
}
44-
4522
func configure_slog() {
4623
var level slog.Level
4724
if err := level.UnmarshalText(
48-
[]byte(viper.GetString("log_level")),
25+
[]byte(config.Log_level),
4926
); err != nil {
5027
panic(err)
5128
}
@@ -72,6 +49,8 @@ type ActiveUser struct {
7249
}
7350

7451
var (
52+
config Config
53+
7554
selectSongsHtml = template.Must(template.ParseFiles("select_songs.html"))
7655
selectPlaylistHtml = template.Must(template.ParseFiles("select_playlist.html"))
7756
winnerHtml = template.Must(template.ParseFiles("winner.html"))
@@ -92,17 +71,20 @@ var (
9271
)
9372

9473
func main() {
95-
read_config()
74+
var err error
75+
config, err = read_config()
76+
if err != nil {
77+
panic(err)
78+
}
9679
configure_slog()
9780

9881
spotifyAuth = spotifyauth.New(
99-
spotifyauth.WithRedirectURL(viper.GetString("redirect_url")),
82+
spotifyauth.WithRedirectURL(config.Redirect_url),
10083
spotifyauth.WithScopes(spotifyauth.ScopePlaylistReadPrivate, spotifyauth.ScopeUserReadPrivate),
101-
spotifyauth.WithClientSecret(viper.GetString("SPOTIFY_CLIENT_SECRET")),
102-
spotifyauth.WithClientID(viper.GetString("SPOTIFY_CLIENT_ID")),
84+
spotifyauth.WithClientSecret(config.Spotify_client_secret),
85+
spotifyauth.WithClientID(config.Spotify_client_id),
10386
)
10487

105-
var err error
10688
db_conn, err = create_db(ctx, "ffs.db")
10789
if err != nil {
10890
slog.Error("Error opening DB connection", "err", err)
@@ -127,7 +109,7 @@ func main() {
127109
mux.HandleFunc("/winner", withMiddleware(winnerHandler))
128110
mux.HandleFunc("/stats", withMiddleware(statsPageHandler))
129111

130-
server := &http.Server{Addr: ":" + viper.GetString("port"), Handler: mux}
112+
server := &http.Server{Addr: ":" + config.Port, Handler: mux}
131113

132114
go func() {
133115
if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
@@ -143,7 +125,7 @@ func main() {
143125
sig := <-sigChan
144126
slog.Warn("received signal, shutting down server", "signal", sig.String())
145127

146-
shutdownCtx, cancelShutdown := context.WithTimeout(ctx, viper.GetDuration("shutdown_timeout"))
128+
shutdownCtx, cancelShutdown := context.WithTimeout(ctx, config.Shutdown_timeout)
147129
defer cancelShutdown()
148130

149131
if err := server.Shutdown(shutdownCtx); err != nil {

‎middleware.go

+27-4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,27 @@ func withLoggingMiddleware(nextHandler http.HandlerFunc) http.HandlerFunc {
4646
}
4747
}
4848

49+
func withAuthMiddleware(nextHandler http.HandlerFunc) http.HandlerFunc {
50+
return func(w http.ResponseWriter, r *http.Request) {
51+
logger := getLogger(r)
52+
53+
user, passwd, ok := r.BasicAuth()
54+
if !ok {
55+
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
56+
logAndErr(w, logger, "no BasicAuth header given", http.StatusUnauthorized)
57+
return
58+
}
59+
60+
if expectedPassword, ok := config.Users[user]; !ok || expectedPassword != passwd {
61+
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
62+
logAndErr(w, logger, "invalid password for user", http.StatusUnauthorized, "user", user)
63+
return
64+
}
65+
66+
nextHandler(w, r)
67+
}
68+
}
69+
4970
type SessionHandlerFunc func(http.ResponseWriter, *http.Request, *sessions.Session)
5071

5172
func withSessionMiddleware(nextHandler SessionHandlerFunc) http.HandlerFunc {
@@ -79,10 +100,12 @@ func withTimerMiddleware(nextHandler SessionHandlerFunc) SessionHandlerFunc {
79100
func withMiddleware(nextHandler SessionHandlerFunc) http.HandlerFunc {
80101
return withPanicMiddleware(
81102
withLoggingMiddleware(
82-
withSessionMiddleware(
83-
withAuthMiddleware(
84-
withTimerMiddleware(
85-
nextHandler,
103+
withAuthMiddleware(
104+
withSessionMiddleware(
105+
withSpotifyAuthMiddleware(
106+
withTimerMiddleware(
107+
nextHandler,
108+
),
86109
),
87110
),
88111
),

‎rmdb.sh

100644100755
File mode changed.

‎auth.go ‎spotify_auth.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"github.com/zmb3/spotify/v2"
1212
)
1313

14-
func withAuthMiddleware(nextHandler SessionHandlerFunc) SessionHandlerFunc {
14+
func withSpotifyAuthMiddleware(nextHandler SessionHandlerFunc) SessionHandlerFunc {
1515
return func(w http.ResponseWriter, r *http.Request, s *sessions.Session) {
1616
if s.IsNew {
1717
state := generateState(state_length)

0 commit comments

Comments
 (0)
Please sign in to comment.