Merge: + auth: add more tests

#1060

* commit '91bb9ccae69afadc06206d413d57c1c3b136e7a7':
  + auth: add more tests
This commit is contained in:
Simon Zolin 2019-10-11 17:03:50 +03:00
commit bfc6c98109
2 changed files with 136 additions and 21 deletions

View File

@ -224,19 +224,10 @@ func getSession(u *User) []byte {
return hash[:] return hash[:]
} }
func handleLogin(w http.ResponseWriter, r *http.Request) { func httpCookie(req loginJSON) string {
req := loginJSON{}
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
httpError(w, http.StatusBadRequest, "json decode: %s", err)
return
}
u := config.auth.UserFind(req.Name, req.Password) u := config.auth.UserFind(req.Name, req.Password)
if len(u.Name) == 0 { if len(u.Name) == 0 {
time.Sleep(1 * time.Second) return ""
httpError(w, http.StatusBadRequest, "invalid login or password")
return
} }
sess := getSession(&u) sess := getSession(&u)
@ -250,8 +241,25 @@ func handleLogin(w http.ResponseWriter, r *http.Request) {
expireSess := uint32(now.Unix()) + expireTime*60*60 expireSess := uint32(now.Unix()) + expireTime*60*60
config.auth.storeSession(sess, expireSess) config.auth.storeSession(sess, expireSess)
s := fmt.Sprintf("session=%s; Path=/; HttpOnly; Expires=%s", hex.EncodeToString(sess), expstr) return fmt.Sprintf("session=%s; Path=/; HttpOnly; Expires=%s", hex.EncodeToString(sess), expstr)
w.Header().Set("Set-Cookie", s) }
func handleLogin(w http.ResponseWriter, r *http.Request) {
req := loginJSON{}
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
httpError(w, http.StatusBadRequest, "json decode: %s", err)
return
}
cookie := httpCookie(req)
if len(cookie) == 0 {
time.Sleep(1 * time.Second)
httpError(w, http.StatusBadRequest, "invalid login or password")
return
}
w.Header().Set("Set-Cookie", cookie)
w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate") w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate")
w.Header().Set("Pragma", "no-cache") w.Header().Set("Pragma", "no-cache")
@ -324,7 +332,6 @@ func optionalAuth(handler func(http.ResponseWriter, *http.Request)) func(http.Re
if err == nil { if err == nil {
r := config.auth.CheckSession(cookie.Value) r := config.auth.CheckSession(cookie.Value)
if r == 0 { if r == 0 {
ok = true ok = true
} else if r < 0 { } else if r < 0 {
log.Debug("Auth: invalid cookie value: %s", cookie) log.Debug("Auth: invalid cookie value: %s", cookie)

View File

@ -2,6 +2,8 @@ package home
import ( import (
"encoding/hex" "encoding/hex"
"net/http"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@ -10,19 +12,25 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestAuth(t *testing.T) { func prepareTestDir() string {
config.ourWorkingDir = "." const dir = "./agh-test"
fn := filepath.Join(config.getDataDir(), "sessions.db") _ = os.RemoveAll(dir)
_ = os.MkdirAll(dir, 0755)
return dir
}
_ = os.RemoveAll(config.getDataDir()) func TestAuth(t *testing.T) {
defer func() { _ = os.RemoveAll(config.getDataDir()) }() dir := prepareTestDir()
defer func() { _ = os.RemoveAll(dir) }()
fn := filepath.Join(dir, "sessions.db")
users := []User{ users := []User{
User{Name: "name", PasswordHash: "$2y$05$..vyzAECIhJPfaQiOK17IukcQnqEgKJHy0iETyYqxn3YXJl8yZuo2"}, User{Name: "name", PasswordHash: "$2y$05$..vyzAECIhJPfaQiOK17IukcQnqEgKJHy0iETyYqxn3YXJl8yZuo2"},
} }
a := InitAuth(fn, nil)
os.MkdirAll(config.getDataDir(), 0755) user := User{Name: "name"}
a := InitAuth(fn, users) a.UserAdd(&user, "password")
assert.True(t, a.CheckSession("notfound") == -1) assert.True(t, a.CheckSession("notfound") == -1)
a.RemoveSession("notfound") a.RemoveSession("notfound")
@ -59,3 +67,103 @@ func TestAuth(t *testing.T) {
a.Close() a.Close()
os.Remove(fn) os.Remove(fn)
} }
// implements http.ResponseWriter
type testResponseWriter struct {
hdr http.Header
statusCode int
}
func (w *testResponseWriter) Header() http.Header {
return w.hdr
}
func (w *testResponseWriter) Write([]byte) (int, error) {
return 0, nil
}
func (w *testResponseWriter) WriteHeader(statusCode int) {
w.statusCode = statusCode
}
func TestAuthHTTP(t *testing.T) {
dir := prepareTestDir()
defer func() { _ = os.RemoveAll(dir) }()
fn := filepath.Join(dir, "sessions.db")
users := []User{
User{Name: "name", PasswordHash: "$2y$05$..vyzAECIhJPfaQiOK17IukcQnqEgKJHy0iETyYqxn3YXJl8yZuo2"},
}
config.auth = InitAuth(fn, users)
handlerCalled := false
handler := func(w http.ResponseWriter, r *http.Request) {
handlerCalled = true
}
handler2 := optionalAuth(handler)
w := testResponseWriter{}
w.hdr = make(http.Header)
r := http.Request{}
r.Header = make(http.Header)
r.Method = "GET"
// get / - we're redirected to login page
r.URL = &url.URL{Path: "/"}
handlerCalled = false
handler2(&w, &r)
assert.True(t, w.statusCode == http.StatusFound)
assert.True(t, w.hdr.Get("Location") != "")
assert.True(t, !handlerCalled)
// go to login page
loginURL := w.hdr.Get("Location")
r.URL = &url.URL{Path: loginURL}
handlerCalled = false
handler2(&w, &r)
assert.True(t, handlerCalled)
// perform login
cookie := httpCookie(loginJSON{Name: "name", Password: "password"})
assert.True(t, cookie != "")
// get /
handler2 = optionalAuth(handler)
w.hdr = make(http.Header)
r.Header.Set("Cookie", cookie)
r.URL = &url.URL{Path: "/"}
handlerCalled = false
handler2(&w, &r)
assert.True(t, handlerCalled)
r.Header.Del("Cookie")
// get / with basic auth
handler2 = optionalAuth(handler)
w.hdr = make(http.Header)
r.URL = &url.URL{Path: "/"}
r.SetBasicAuth("name", "password")
handlerCalled = false
handler2(&w, &r)
assert.True(t, handlerCalled)
r.Header.Del("Authorization")
// get login page with a valid cookie - we're redirected to /
handler2 = optionalAuth(handler)
w.hdr = make(http.Header)
r.Header.Set("Cookie", cookie)
r.URL = &url.URL{Path: loginURL}
handlerCalled = false
handler2(&w, &r)
assert.True(t, w.hdr.Get("Location") != "")
assert.True(t, !handlerCalled)
r.Header.Del("Cookie")
// get login page with an invalid cookie
handler2 = optionalAuth(handler)
w.hdr = make(http.Header)
r.Header.Set("Cookie", "bad")
r.URL = &url.URL{Path: loginURL}
handlerCalled = false
handler2(&w, &r)
assert.True(t, handlerCalled)
r.Header.Del("Cookie")
config.auth.Close()
}