auth/auth.go
This commit is contained in:
parent
b3f019793a
commit
813df834ab
|
@ -14,12 +14,12 @@ func handlerAuthenticated(c *snap.Context) {
|
|||
}
|
||||
|
||||
|
||||
func mustRunServer(auth auth.AuthManager) {
|
||||
func mustRunServer(auth auth.Authenticator) {
|
||||
srv := snap.New("127.0.0.1:9000", "./", nil)
|
||||
srv.SetDebug(true)
|
||||
|
||||
srv.HandleFunc("/", handler)
|
||||
srv.HandleFuncCustomAuth(auth,"/auth", handlerAuthenticated)
|
||||
srv.HandleFuncCustomAuth(auth,"/auth", "", handlerAuthenticated)
|
||||
|
||||
srv.Serve()
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -5,4 +5,5 @@ go 1.15
|
|||
require (
|
||||
git.thirdmartini.com/pub/fancylog v0.0.0-20180118031448-3f3ebedd6016
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
)
|
||||
|
|
12
go.sum
12
go.sum
|
@ -1,3 +1,15 @@
|
|||
git.thirdmartini.com/pub/fancylog v0.0.0-20180118031448-3f3ebedd6016 h1:egW0VTyAgD7FjG6iZKHBcHc7siCGjoxm1T71GecYUE4=
|
||||
git.thirdmartini.com/pub/fancylog v0.0.0-20180118031448-3f3ebedd6016/go.mod h1:nxr8UYB5P+7cpJPpqcbhMjfqm+GH3VDZQs2dFWibA68=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
49
server.go
49
server.go
|
@ -7,6 +7,7 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -23,7 +24,7 @@ type Server struct {
|
|||
path string
|
||||
theme string
|
||||
debug bool
|
||||
auth auth.AuthManager
|
||||
auth auth.Authenticator
|
||||
router *mux.Router
|
||||
templates string
|
||||
cachedTmpl *template.Template
|
||||
|
@ -45,14 +46,17 @@ func (s *Server) makeContext(auth *auth.AuthData, w http.ResponseWriter, r *http
|
|||
return c
|
||||
}
|
||||
|
||||
func (s *Server) authenticated(auth auth.AuthManager, handle func(c *Context)) http.HandlerFunc {
|
||||
func (s *Server) authenticated(auth auth.Authenticator, redirect string, handle func(c *Context)) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("authenticated request: ", r.RequestURI)
|
||||
|
||||
rec, ok := auth.DoAuth(w, r)
|
||||
|
||||
if !ok {
|
||||
http.Error(w, "Not authorized", 401)
|
||||
if redirect != "" {
|
||||
http.Redirect(w, r, redirect, http.StatusSeeOther)
|
||||
} else {
|
||||
http.Error(w, "Not authorized", http.StatusForbidden)
|
||||
}
|
||||
} else {
|
||||
c := s.makeContext(rec, w, r)
|
||||
handle(c)
|
||||
|
@ -125,12 +129,6 @@ func (s *Server) loadTemplates() *template.Template {
|
|||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
/*
|
||||
_, err = tmpl.ParseFiles(path)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
*/
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
@ -169,20 +167,20 @@ func (s *Server) renderError(w http.ResponseWriter, code int, msg string) {
|
|||
w.Write([]byte(msg))
|
||||
}
|
||||
|
||||
func (s *Server) HandleFuncAuthenticated(path string, f func(c *Context)) *mux.Route {
|
||||
func (s *Server) HandleFuncAuthenticated(path,redirect string, f func(c *Context)) *mux.Route {
|
||||
if s.auth == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.router.HandleFunc(path, s.authenticated(s.auth, f))
|
||||
return s.router.HandleFunc(path, s.authenticated(s.auth,redirect, f))
|
||||
}
|
||||
|
||||
func (s *Server) HandleFuncCustomAuth(auth auth.AuthManager, path string, f func(c *Context)) *mux.Route {
|
||||
func (s *Server) HandleFuncCustomAuth(auth auth.Authenticator, path, redirect string, f func(c *Context)) *mux.Route {
|
||||
if auth == nil {
|
||||
log.Warn("Nil auth on", path)
|
||||
return nil
|
||||
}
|
||||
return s.router.HandleFunc(path, s.authenticated(auth, f))
|
||||
return s.router.HandleFunc(path, s.authenticated(auth,redirect, f))
|
||||
}
|
||||
|
||||
func (s *Server) HandleFunc(path string, f func(c *Context)) *mux.Route {
|
||||
|
@ -196,12 +194,12 @@ func (s *Server) SetDebug(enable bool) {
|
|||
func (s *Server) EnableStatus(path string) {
|
||||
}
|
||||
|
||||
func (s *Server) SetTheme(theme string) {
|
||||
s.theme = theme
|
||||
func (s *Server) SetTheme(themePath string) {
|
||||
s.theme = path.Clean(themePath)
|
||||
}
|
||||
|
||||
func (s *Server) SetTemplatePath(path string) {
|
||||
s.templates = path
|
||||
func (s *Server) SetTemplatePath(tmplPath string) {
|
||||
s.templates = path.Clean(tmplPath)
|
||||
}
|
||||
|
||||
func (s *Server) Router() *mux.Router {
|
||||
|
@ -239,17 +237,24 @@ func (s *Server) WithStaticFiles(prefix string, path string) *Server {
|
|||
}
|
||||
|
||||
func (s *Server) WithTheme(themeURL string) *Server {
|
||||
s.theme = themeURL
|
||||
s.theme = path.Clean(themeURL)
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Server) WithDebug(debugURL string) *Server {
|
||||
sub := s.router.PathPrefix("/sovereign/debug").Subrouter()
|
||||
sub := s.router.PathPrefix(debugURL).Subrouter()
|
||||
setupDebugHandler(sub)
|
||||
return s
|
||||
}
|
||||
|
||||
func New(address string, path string, auth auth.AuthManager) *Server {
|
||||
func (s *Server) Dump() {
|
||||
fmt.Printf( " Path: %s\n", s.path)
|
||||
fmt.Printf( " Theme: %s\n", s.theme)
|
||||
fmt.Printf( " Templates: %s\n", s.templates)
|
||||
|
||||
}
|
||||
|
||||
func New(address string, path string, auth auth.Authenticator) *Server {
|
||||
s := Server{
|
||||
router: mux.NewRouter(),
|
||||
auth: auth,
|
||||
|
@ -258,7 +263,5 @@ func New(address string, path string, auth auth.AuthManager) *Server {
|
|||
templates: "templates",
|
||||
theme: "/static/css/default.css",
|
||||
}
|
||||
|
||||
//s.router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(s.path+"static/"))))
|
||||
return &s
|
||||
}
|
||||
|
|
144
server_test.go
144
server_test.go
|
@ -1,10 +1,152 @@
|
|||
package snap
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"git.thirdmartini.com/pub/snap/auth"
|
||||
)
|
||||
|
||||
func TestServer(t *testing.T) {
|
||||
|
||||
var rootExpected = []byte(`
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="/static/skin/css/normalize.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Test of things
|
||||
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
|
||||
var testExpected = []byte(`
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="/static/skin/css/normalize.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
User: admin
|
||||
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
|
||||
|
||||
func handlerRoot(c *Context) {
|
||||
c.RenderEx("index.html", nil)
|
||||
}
|
||||
|
||||
func handlerLogin(c *Context) {
|
||||
c.RenderEx("index.html", nil)
|
||||
}
|
||||
|
||||
func handlerTest(c *Context) {
|
||||
c.RenderEx("test.html", nil)
|
||||
}
|
||||
|
||||
func doTestRequest(t *testing.T, req *http.Request) ([]byte, int, error){
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, resp)
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
assert.Nil(t, err)
|
||||
|
||||
return data, resp.StatusCode, err
|
||||
}
|
||||
|
||||
func TestServer_BasicAuth(t *testing.T) {
|
||||
auth := auth.NewBasicAuth()
|
||||
auth.AddUser("admin", "admin", "test")
|
||||
|
||||
s := New("", "/test", auth)
|
||||
s.SetDebug(true)
|
||||
s.SetTemplatePath("test/templates")
|
||||
s.WithStaticFiles("/static", "test/static" )
|
||||
s.WithTheme("skin/")
|
||||
s.HandleFunc("/", handlerRoot)
|
||||
s.HandleFuncAuthenticated("/login", "", handlerLogin)
|
||||
s.HandleFuncAuthenticated("/test", "", handlerTest)
|
||||
s.Dump()
|
||||
|
||||
ts := httptest.NewServer(s.router)
|
||||
defer ts.Close()
|
||||
|
||||
// Simple Get:/
|
||||
req, err := http.NewRequest(http.MethodGet, ts.URL, nil)
|
||||
assert.Nil(t, err)
|
||||
data, code, err := doTestRequest(t, req)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
assert.Equal(t, rootExpected, data)
|
||||
|
||||
// Check GOOD password
|
||||
req, err = http.NewRequest(http.MethodGet, ts.URL +"/login", nil)
|
||||
assert.Nil(t, err)
|
||||
req.SetBasicAuth("admin","test")
|
||||
data, code, err = doTestRequest(t, req)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
assert.Equal(t, rootExpected, data)
|
||||
|
||||
// Check BAD password
|
||||
req, err = http.NewRequest(http.MethodGet, ts.URL +"/login", nil)
|
||||
assert.Nil(t, err)
|
||||
req.SetBasicAuth("admin","badpass")
|
||||
data, code, err = doTestRequest(t, req)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, http.StatusForbidden, code)
|
||||
|
||||
// Check GOOD password and context in templates
|
||||
req, err = http.NewRequest(http.MethodGet, ts.URL +"/test", nil)
|
||||
assert.Nil(t, err)
|
||||
req.SetBasicAuth("admin","test")
|
||||
data, code, err = doTestRequest(t, req)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
assert.Equal(t, testExpected, data)
|
||||
|
||||
// Test Static Content
|
||||
// Check GOOD password and context in templates
|
||||
req, err = http.NewRequest(http.MethodGet, ts.URL +"/static/skin/skin.html", nil)
|
||||
assert.Nil(t, err)
|
||||
data, code, err = doTestRequest(t, req)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
assert.Equal(t, []byte(`skin-file`), data)
|
||||
}
|
||||
|
||||
func TestServer_TokenAuth(t *testing.T) {
|
||||
auth := auth.NewTokenAuth()
|
||||
auth.AddUser("admin", "admin", "1234567890")
|
||||
|
||||
s := New("", "/test", auth)
|
||||
s.SetDebug(true)
|
||||
s.SetTemplatePath("test/templates")
|
||||
s.WithStaticFiles("/static", "test/static")
|
||||
s.WithTheme("skin/")
|
||||
s.HandleFunc("/", handlerRoot)
|
||||
s.HandleFuncAuthenticated("/login", "", handlerLogin)
|
||||
s.HandleFuncAuthenticated("/test", "", handlerTest)
|
||||
s.Dump()
|
||||
|
||||
ts := httptest.NewServer(s.router)
|
||||
defer ts.Close()
|
||||
|
||||
// Check GOOD password
|
||||
req, err := http.NewRequest(http.MethodGet, ts.URL+"/login", nil)
|
||||
assert.Nil(t, err)
|
||||
req.Header.Add("token", "1234567890")
|
||||
data, code, err := doTestRequest(t, req)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
assert.Equal(t, rootExpected, data)
|
||||
}
|
Loading…
Reference in New Issue