+ config: "web_session_ttl" setting
This commit is contained in:
parent
0d4dce5c79
commit
c9a6e4e018
25
home/auth.go
25
home/auth.go
@ -18,7 +18,6 @@ import (
|
||||
)
|
||||
|
||||
const cookieTTL = 365 * 24 // in hours
|
||||
const expireTime = 30 * 24 // in hours
|
||||
|
||||
type session struct {
|
||||
userName string
|
||||
@ -56,10 +55,11 @@ func (s *session) deserialize(data []byte) bool {
|
||||
|
||||
// Auth - global object
|
||||
type Auth struct {
|
||||
db *bbolt.DB
|
||||
sessions map[string]*session // session name -> session data
|
||||
lock sync.Mutex
|
||||
users []User
|
||||
db *bbolt.DB
|
||||
sessions map[string]*session // session name -> session data
|
||||
lock sync.Mutex
|
||||
users []User
|
||||
sessionTTL uint32 // in seconds
|
||||
}
|
||||
|
||||
// User object
|
||||
@ -69,8 +69,9 @@ type User struct {
|
||||
}
|
||||
|
||||
// InitAuth - create a global object
|
||||
func InitAuth(dbFilename string, users []User) *Auth {
|
||||
func InitAuth(dbFilename string, users []User, sessionTTL uint32) *Auth {
|
||||
a := Auth{}
|
||||
a.sessionTTL = sessionTTL
|
||||
a.sessions = make(map[string]*session)
|
||||
rand.Seed(time.Now().UTC().Unix())
|
||||
var err error
|
||||
@ -233,7 +234,7 @@ func (a *Auth) CheckSession(sess string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
newExpire := now + expireTime*60*60
|
||||
newExpire := now + a.sessionTTL
|
||||
if s.expire/(24*60*60) != newExpire/(24*60*60) {
|
||||
// update expiration time once a day
|
||||
update = true
|
||||
@ -270,8 +271,8 @@ func getSession(u *User) []byte {
|
||||
return hash[:]
|
||||
}
|
||||
|
||||
func httpCookie(req loginJSON) string {
|
||||
u := config.auth.UserFind(req.Name, req.Password)
|
||||
func (a *Auth) httpCookie(req loginJSON) string {
|
||||
u := a.UserFind(req.Name, req.Password)
|
||||
if len(u.Name) == 0 {
|
||||
return ""
|
||||
}
|
||||
@ -286,8 +287,8 @@ func httpCookie(req loginJSON) string {
|
||||
|
||||
s := session{}
|
||||
s.userName = u.Name
|
||||
s.expire = uint32(now.Unix()) + expireTime*60*60
|
||||
config.auth.addSession(sess, &s)
|
||||
s.expire = uint32(now.Unix()) + a.sessionTTL
|
||||
a.addSession(sess, &s)
|
||||
|
||||
return fmt.Sprintf("session=%s; Path=/; HttpOnly; Expires=%s", hex.EncodeToString(sess), expstr)
|
||||
}
|
||||
@ -300,7 +301,7 @@ func handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
cookie := httpCookie(req)
|
||||
cookie := config.auth.httpCookie(req)
|
||||
if len(cookie) == 0 {
|
||||
time.Sleep(1 * time.Second)
|
||||
httpError(w, http.StatusBadRequest, "invalid login or password")
|
||||
|
@ -27,7 +27,7 @@ func TestAuth(t *testing.T) {
|
||||
users := []User{
|
||||
User{Name: "name", PasswordHash: "$2y$05$..vyzAECIhJPfaQiOK17IukcQnqEgKJHy0iETyYqxn3YXJl8yZuo2"},
|
||||
}
|
||||
a := InitAuth(fn, nil)
|
||||
a := InitAuth(fn, nil, 60)
|
||||
s := session{}
|
||||
|
||||
user := User{Name: "name"}
|
||||
@ -54,7 +54,7 @@ func TestAuth(t *testing.T) {
|
||||
a.Close()
|
||||
|
||||
// load saved session
|
||||
a = InitAuth(fn, users)
|
||||
a = InitAuth(fn, users, 60)
|
||||
|
||||
// the session is still alive
|
||||
assert.True(t, a.CheckSession(sessStr) == 0)
|
||||
@ -69,7 +69,7 @@ func TestAuth(t *testing.T) {
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
// load and remove expired sessions
|
||||
a = InitAuth(fn, users)
|
||||
a = InitAuth(fn, users, 60)
|
||||
assert.True(t, a.CheckSession(sessStr) == -1)
|
||||
|
||||
a.Close()
|
||||
@ -100,7 +100,7 @@ func TestAuthHTTP(t *testing.T) {
|
||||
users := []User{
|
||||
User{Name: "name", PasswordHash: "$2y$05$..vyzAECIhJPfaQiOK17IukcQnqEgKJHy0iETyYqxn3YXJl8yZuo2"},
|
||||
}
|
||||
config.auth = InitAuth(fn, users)
|
||||
config.auth = InitAuth(fn, users, 60)
|
||||
|
||||
handlerCalled := false
|
||||
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||
@ -129,7 +129,7 @@ func TestAuthHTTP(t *testing.T) {
|
||||
assert.True(t, handlerCalled)
|
||||
|
||||
// perform login
|
||||
cookie := httpCookie(loginJSON{Name: "name", Password: "password"})
|
||||
cookie := config.auth.httpCookie(loginJSON{Name: "name", Password: "password"})
|
||||
assert.True(t, cookie != "")
|
||||
|
||||
// get /
|
||||
|
@ -91,6 +91,10 @@ type configuration struct {
|
||||
Language string `yaml:"language"` // two-letter ISO 639-1 language code
|
||||
RlimitNoFile uint `yaml:"rlimit_nofile"` // Maximum number of opened fd's per process (0: default)
|
||||
|
||||
// TTL for a web session (in hours)
|
||||
// An active session is automatically refreshed once a day.
|
||||
WebSessionTTLHours uint32 `yaml:"web_session_ttl"`
|
||||
|
||||
DNS dnsConfig `yaml:"dns"`
|
||||
TLS tlsConfig `yaml:"tls"`
|
||||
Filters []filter `yaml:"filters"`
|
||||
@ -210,6 +214,8 @@ func initConfig() {
|
||||
Transport: config.transport,
|
||||
}
|
||||
|
||||
config.WebSessionTTLHours = 30 * 24
|
||||
|
||||
if runtime.GOARCH == "mips" || runtime.GOARCH == "mipsle" {
|
||||
// Use plain DNS on MIPS, encryption is too slow
|
||||
defaultDNS = []string{"1.1.1.1", "1.0.0.1"}
|
||||
|
@ -68,7 +68,7 @@ func initDNSServer() {
|
||||
config.dnsServer = dnsforward.NewServer(config.dnsFilter, config.stats, config.queryLog)
|
||||
|
||||
sessFilename := filepath.Join(baseDir, "sessions.db")
|
||||
config.auth = InitAuth(sessFilename, config.Users)
|
||||
config.auth = InitAuth(sessFilename, config.Users, config.WebSessionTTLHours*60*60)
|
||||
config.Users = nil
|
||||
|
||||
config.dnsctx.rdns = InitRDNS(&config.clients)
|
||||
|
Loading…
Reference in New Issue
Block a user