2019-04-25 04:52:08 +07:00
|
|
|
package session
|
|
|
|
|
|
|
|
import (
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
"crypto/x509"
|
2019-04-25 04:52:08 +07:00
|
|
|
"encoding/json"
|
|
|
|
"time"
|
|
|
|
|
2021-03-13 12:06:19 +07:00
|
|
|
fasthttpsession "github.com/fasthttp/session/v2"
|
|
|
|
"github.com/fasthttp/session/v2/providers/memory"
|
|
|
|
"github.com/fasthttp/session/v2/providers/redis"
|
2019-04-25 04:52:08 +07:00
|
|
|
"github.com/valyala/fasthttp"
|
2020-04-05 19:37:21 +07:00
|
|
|
|
|
|
|
"github.com/authelia/authelia/internal/configuration/schema"
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
"github.com/authelia/authelia/internal/logging"
|
2020-04-05 19:37:21 +07:00
|
|
|
"github.com/authelia/authelia/internal/utils"
|
2019-04-25 04:52:08 +07:00
|
|
|
)
|
|
|
|
|
|
|
|
// Provider a session provider.
|
|
|
|
type Provider struct {
|
|
|
|
sessionHolder *fasthttpsession.Session
|
2020-04-04 06:11:33 +07:00
|
|
|
RememberMe time.Duration
|
2020-04-05 19:37:21 +07:00
|
|
|
Inactivity time.Duration
|
2019-04-25 04:52:08 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewProvider instantiate a session provider given a configuration.
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
func NewProvider(configuration schema.SessionConfiguration, certPool *x509.CertPool) *Provider {
|
|
|
|
providerConfig := NewProviderConfig(configuration, certPool)
|
2019-04-25 04:52:08 +07:00
|
|
|
|
|
|
|
provider := new(Provider)
|
|
|
|
provider.sessionHolder = fasthttpsession.New(providerConfig.config)
|
2020-04-05 19:37:21 +07:00
|
|
|
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
logger := logging.Logger()
|
|
|
|
|
2020-04-04 06:11:33 +07:00
|
|
|
duration, err := utils.ParseDurationString(configuration.RememberMeDuration)
|
|
|
|
if err != nil {
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
logger.Fatal(err)
|
2020-04-04 06:11:33 +07:00
|
|
|
}
|
2020-05-06 02:35:32 +07:00
|
|
|
|
2020-04-04 06:11:33 +07:00
|
|
|
provider.RememberMe = duration
|
2020-04-05 19:37:21 +07:00
|
|
|
|
|
|
|
duration, err = utils.ParseDurationString(configuration.Inactivity)
|
|
|
|
if err != nil {
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
logger.Fatal(err)
|
2020-04-05 19:37:21 +07:00
|
|
|
}
|
2020-05-06 02:35:32 +07:00
|
|
|
|
2020-04-05 19:37:21 +07:00
|
|
|
provider.Inactivity = duration
|
|
|
|
|
2020-05-18 09:45:47 +07:00
|
|
|
var providerImpl fasthttpsession.Provider
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
|
|
|
|
switch {
|
|
|
|
case providerConfig.redisConfig != nil:
|
2020-05-18 09:45:47 +07:00
|
|
|
providerImpl, err = redis.New(*providerConfig.redisConfig)
|
|
|
|
if err != nil {
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
logger.Fatal(err)
|
|
|
|
}
|
|
|
|
case providerConfig.redisSentinelConfig != nil:
|
|
|
|
providerImpl, err = redis.NewFailoverCluster(*providerConfig.redisSentinelConfig)
|
|
|
|
if err != nil {
|
|
|
|
logger.Fatal(err)
|
2020-05-18 09:45:47 +07:00
|
|
|
}
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
default:
|
2020-05-18 09:45:47 +07:00
|
|
|
providerImpl, err = memory.New(memory.Config{})
|
|
|
|
if err != nil {
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
logger.Fatal(err)
|
2020-05-18 09:45:47 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err = provider.sessionHolder.SetProvider(providerImpl)
|
2019-04-25 04:52:08 +07:00
|
|
|
if err != nil {
|
feat(session): add redis sentinel provider (#1768)
* feat(session): add redis sentinel provider
* refactor(session): use int for ports as per go standards
* refactor(configuration): adjust tests and validation
* refactor(configuration): add err format consts
* refactor(configuration): explicitly map redis structs
* refactor(session): merge redis/redis sentinel providers
* refactor(session): add additional checks to redis providers
* feat(session): add redis cluster provider
* fix: update config for new values
* fix: provide nil certpool to affected tests/mocks
* test: add additional tests to cover uncovered code
* docs: expand explanation of host and nodes relation for redis
* ci: add redis-sentinel to suite highavailability, add redis-sentinel quorum
* fix(session): sentinel password
* test: use redis alpine library image for redis sentinel, use expose instead of ports, use redis ip, adjust redis ip range, adjust redis config
* test: make entrypoint.sh executable, fix entrypoint.sh if/elif
* test: add redis failover tests
* test: defer docker start, adjust sleep, attempt logout before login, attempt visit before login and tune timeouts, add additional logging
* test: add sentinel integration test
* test: add secondary node failure to tests, fix password usage, bump test timeout, add sleep
* feat: use sentinel failover cluster
* fix: renamed addrs to sentineladdrs upstream
* test(session): sentinel failover
* test: add redis standard back into testing
* test: move redis standalone test to traefik2
* fix/docs: apply suggestions from code review
2021-03-10 06:03:05 +07:00
|
|
|
logger.Fatal(err)
|
2019-04-25 04:52:08 +07:00
|
|
|
}
|
2020-05-06 02:35:32 +07:00
|
|
|
|
2019-04-25 04:52:08 +07:00
|
|
|
return provider
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// GetSession return the user session from a request.
|
2019-04-25 04:52:08 +07:00
|
|
|
func (p *Provider) GetSession(ctx *fasthttp.RequestCtx) (UserSession, error) {
|
|
|
|
store, err := p.sessionHolder.Get(ctx)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return NewDefaultUserSession(), err
|
|
|
|
}
|
|
|
|
|
|
|
|
userSessionJSON, ok := store.Get(userSessionStorerKey).([]byte)
|
|
|
|
|
|
|
|
// If userSession is not yet defined we create the new session with default values
|
|
|
|
// and save it in the store.
|
|
|
|
if !ok {
|
|
|
|
userSession := NewDefaultUserSession()
|
|
|
|
store.Set(userSessionStorerKey, userSession)
|
2020-05-06 02:35:32 +07:00
|
|
|
|
2019-04-25 04:52:08 +07:00
|
|
|
return userSession, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var userSession UserSession
|
|
|
|
err = json.Unmarshal(userSessionJSON, &userSession)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return NewDefaultUserSession(), err
|
|
|
|
}
|
|
|
|
|
|
|
|
return userSession, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// SaveSession save the user session.
|
|
|
|
func (p *Provider) SaveSession(ctx *fasthttp.RequestCtx, userSession UserSession) error {
|
|
|
|
store, err := p.sessionHolder.Get(ctx)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
userSessionJSON, err := json.Marshal(userSession)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
store.Set(userSessionStorerKey, userSessionJSON)
|
2020-05-18 09:45:47 +07:00
|
|
|
|
2020-05-19 04:50:50 +07:00
|
|
|
err = p.sessionHolder.Save(ctx, store)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-05-06 02:35:32 +07:00
|
|
|
|
2019-04-25 04:52:08 +07:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// RegenerateSession regenerate a session ID.
|
|
|
|
func (p *Provider) RegenerateSession(ctx *fasthttp.RequestCtx) error {
|
2020-05-18 09:45:47 +07:00
|
|
|
err := p.sessionHolder.Regenerate(ctx)
|
2019-04-25 04:52:08 +07:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// DestroySession destroy a session ID and delete the cookie.
|
|
|
|
func (p *Provider) DestroySession(ctx *fasthttp.RequestCtx) error {
|
|
|
|
return p.sessionHolder.Destroy(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateExpiration update the expiration of the cookie and session.
|
|
|
|
func (p *Provider) UpdateExpiration(ctx *fasthttp.RequestCtx, expiration time.Duration) error {
|
|
|
|
store, err := p.sessionHolder.Get(ctx)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = store.SetExpiration(expiration)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-05-18 09:45:47 +07:00
|
|
|
return p.sessionHolder.Save(ctx, store)
|
2019-04-25 04:52:08 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetExpiration get the expiration of the current session.
|
|
|
|
func (p *Provider) GetExpiration(ctx *fasthttp.RequestCtx) (time.Duration, error) {
|
|
|
|
store, err := p.sessionHolder.Get(ctx)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return time.Duration(0), err
|
|
|
|
}
|
|
|
|
|
|
|
|
return store.GetExpiration(), nil
|
|
|
|
}
|