Skip to content
Snippets Groups Projects
Commit 00e56da4 authored by gbe's avatar gbe
Browse files

Add a very stupid authentication mechanism

parent b2db89fc
No related branches found
No related tags found
No related merge requests found
package auth
import (
"context"
"net/http"
)
type contextKey string
type Provider interface {
// Returns true if pass is a valid password for the given user
Valid(user, pass string) bool
}
// Require wraps hdlr so that it requires authentication to use. Requests handled by hdlr will have the user
// name attached to their context. Use the User function to retrieve it.
func Require(hdlr http.HandlerFunc, provider Provider) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
if !ok {
w.Header().Add("WWW-Authenticate", `Basic realm="In Vino Veritas"`)
w.WriteHeader(http.StatusUnauthorized)
return
}
if !provider.Valid(user, pass) {
w.Header().Add("WWW-Authenticate", `Basic realm="In Vino Veritas"`)
w.WriteHeader(http.StatusUnauthorized)
return
}
key := contextKey("user")
ctx := context.WithValue(r.Context(), key, user)
hdlr(w, r.WithContext(ctx))
})
}
// User returns the user from r's context. If r has no user in its context, the empty string will be returned.
func User(r *http.Request) string {
val := r.Context().Value(contextKey("user"))
if val == nil {
return ""
}
return val.(string)
}
...@@ -15,7 +15,7 @@ import ( ...@@ -15,7 +15,7 @@ import (
var detailsTemplate = template.Must(template.ParseFS(templateFS, "templates/base.tpl", "templates/details.tpl")) var detailsTemplate = template.Must(template.ParseFS(templateFS, "templates/base.tpl", "templates/details.tpl"))
func (h Handler) img(w http.ResponseWriter, r *http.Request) { func (h Handler) img(w http.ResponseWriter, r *http.Request) {
log.Println("handling", r.Method, r.URL, "from", r.RemoteAddr) logRequest(r)
if r.Method != "GET" { if r.Method != "GET" {
httpError(w, "bad method", errors.New(r.Method), http.StatusMethodNotAllowed) httpError(w, "bad method", errors.New(r.Method), http.StatusMethodNotAllowed)
......
...@@ -17,7 +17,7 @@ func (h Handler) index(w http.ResponseWriter, r *http.Request) { ...@@ -17,7 +17,7 @@ func (h Handler) index(w http.ResponseWriter, r *http.Request) {
return return
} }
log.Println("handling", r.Method, r.URL, "from", r.RemoteAddr) logRequest(r)
if r.Method == "GET" { if r.Method == "GET" {
wines, err := ListWines(r.Context(), h.db) wines, err := ListWines(r.Context(), h.db)
......
...@@ -7,6 +7,8 @@ import ( ...@@ -7,6 +7,8 @@ import (
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
_ "modernc.org/sqlite" // Imported for side effects: registers DB driver _ "modernc.org/sqlite" // Imported for side effects: registers DB driver
"git.c3pb.de/gbe/invinoveritas/auth"
) )
//go:embed templates/*.tpl //go:embed templates/*.tpl
...@@ -29,6 +31,20 @@ func httpError(w http.ResponseWriter, msg string, err error, status int) { ...@@ -29,6 +31,20 @@ func httpError(w http.ResponseWriter, msg string, err error, status int) {
http.Error(w, msg, status) http.Error(w, msg, status)
} }
type authProvider struct{}
func (a authProvider) Valid(user, pass string) bool {
if user == "wine" && pass == "potatoe" {
return true
}
return false
}
func logRequest(r *http.Request) {
log.Println("handling", r.Method, r.URL, "from", r.RemoteAddr, "by", auth.User(r))
}
func main() { func main() {
db, err := sqlx.Open("sqlite", "vino.sqlite") db, err := sqlx.Open("sqlite", "vino.sqlite")
if err != nil { if err != nil {
...@@ -41,15 +57,19 @@ func main() { ...@@ -41,15 +57,19 @@ func main() {
log.Fatalln("can't initialize DB:", err) log.Fatalln("can't initialize DB:", err)
} }
http.HandleFunc("/favicon.ico", http.NotFound)
http.Handle("/static/", http.FileServer(http.FS(staticFS))) http.Handle("/static/", http.FileServer(http.FS(staticFS)))
handler := Handler{ handler := Handler{
db: db, db: db,
} }
http.HandleFunc("/details/img", handler.img) ap := authProvider{}
http.HandleFunc("/details/", handler.details)
http.HandleFunc("/", handler.index) http.HandleFunc("/details/img", auth.Require(http.HandlerFunc(handler.img), ap))
http.HandleFunc("/details/", auth.Require(http.HandlerFunc(handler.details), ap))
http.HandleFunc("/", auth.Require(http.HandlerFunc(handler.index), ap))
const listenAddr = ":7878" const listenAddr = ":7878"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment