authelia/internal/session/provider_config_test.go
James Elliott 706fbfdb2c
fix(session): ensure default cookie samesite value is lax (#1926)
This implements a change to the default behaviour of the cookies generated by the sessions package. The old behaviour was to set the SameSite=None, this changes it to SameSite=Lax. Additionally this puts the option in the hands of the end-user so they can decide for themselves what the best option is.
2021-04-18 10:02:04 +10:00

289 lines
9.8 KiB
Go

package session
import (
"crypto/sha256"
"crypto/tls"
"testing"
"time"
"github.com/fasthttp/session/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
"github.com/authelia/authelia/internal/configuration/schema"
"github.com/authelia/authelia/internal/utils"
)
func TestShouldCreateInMemorySessionProvider(t *testing.T) {
// The redis configuration is not provided so we create a in-memory provider.
configuration := schema.SessionConfiguration{}
configuration.Domain = testDomain
configuration.Name = testName
configuration.Expiration = testExpiration
providerConfig := NewProviderConfig(configuration, nil)
assert.Equal(t, "my_session", providerConfig.config.CookieName)
assert.Equal(t, testDomain, providerConfig.config.Domain)
assert.Equal(t, true, providerConfig.config.Secure)
assert.Equal(t, time.Duration(40)*time.Second, providerConfig.config.Expiration)
assert.True(t, providerConfig.config.IsSecureFunc(nil))
assert.Equal(t, "memory", providerConfig.providerName)
}
func TestShouldCreateRedisSessionProviderTLS(t *testing.T) {
configuration := schema.SessionConfiguration{}
configuration.Domain = testDomain
configuration.Name = testName
configuration.Expiration = testExpiration
configuration.Redis = &schema.RedisSessionConfiguration{
Host: "redis.example.com",
Port: 6379,
Password: "pass",
TLS: &schema.TLSConfig{
ServerName: "redis.fqdn.example.com",
MinimumVersion: "TLS1.3",
},
}
providerConfig := NewProviderConfig(configuration, nil)
assert.Nil(t, providerConfig.redisSentinelConfig)
assert.Equal(t, "my_session", providerConfig.config.CookieName)
assert.Equal(t, testDomain, providerConfig.config.Domain)
assert.Equal(t, true, providerConfig.config.Secure)
assert.Equal(t, time.Duration(40)*time.Second, providerConfig.config.Expiration)
assert.True(t, providerConfig.config.IsSecureFunc(nil))
assert.Equal(t, "redis", providerConfig.providerName)
pConfig := providerConfig.redisConfig
assert.Equal(t, "redis.example.com:6379", pConfig.Addr)
assert.Equal(t, "pass", pConfig.Password)
// DbNumber is the fasthttp/session property for the Redis DB Index
assert.Equal(t, 0, pConfig.DB)
assert.Equal(t, 0, pConfig.PoolSize)
assert.Equal(t, 0, pConfig.MinIdleConns)
require.NotNil(t, pConfig.TLSConfig)
require.Equal(t, uint16(tls.VersionTLS13), pConfig.TLSConfig.MinVersion)
require.Equal(t, "redis.fqdn.example.com", pConfig.TLSConfig.ServerName)
require.False(t, pConfig.TLSConfig.InsecureSkipVerify)
}
func TestShouldCreateRedisSessionProvider(t *testing.T) {
configuration := schema.SessionConfiguration{}
configuration.Domain = testDomain
configuration.Name = testName
configuration.Expiration = testExpiration
configuration.Redis = &schema.RedisSessionConfiguration{
Host: "redis.example.com",
Port: 6379,
Password: "pass",
}
providerConfig := NewProviderConfig(configuration, nil)
assert.Nil(t, providerConfig.redisSentinelConfig)
assert.Equal(t, "my_session", providerConfig.config.CookieName)
assert.Equal(t, testDomain, providerConfig.config.Domain)
assert.Equal(t, true, providerConfig.config.Secure)
assert.Equal(t, time.Duration(40)*time.Second, providerConfig.config.Expiration)
assert.True(t, providerConfig.config.IsSecureFunc(nil))
assert.Equal(t, "redis", providerConfig.providerName)
pConfig := providerConfig.redisConfig
assert.Equal(t, "redis.example.com:6379", pConfig.Addr)
assert.Equal(t, "pass", pConfig.Password)
// DbNumber is the fasthttp/session property for the Redis DB Index
assert.Equal(t, 0, pConfig.DB)
assert.Equal(t, 0, pConfig.PoolSize)
assert.Equal(t, 0, pConfig.MinIdleConns)
assert.Nil(t, pConfig.TLSConfig)
}
func TestShouldCreateRedisSentinelSessionProviderWithoutDuplicateHosts(t *testing.T) {
configuration := schema.SessionConfiguration{}
configuration.Domain = testDomain
configuration.Name = testName
configuration.Expiration = testExpiration
configuration.Redis = &schema.RedisSessionConfiguration{
Host: "REDIS.example.com",
Port: 26379,
Password: "pass",
MaximumActiveConnections: 8,
MinimumIdleConnections: 2,
HighAvailability: &schema.RedisHighAvailabilityConfiguration{
SentinelName: "mysent",
SentinelPassword: "mypass",
Nodes: []schema.RedisNode{
{
Host: "redis2.example.com",
Port: 26379,
},
{
Host: "redis.example.com",
Port: 26379,
},
},
},
}
providerConfig := NewProviderConfig(configuration, nil)
assert.Len(t, providerConfig.redisSentinelConfig.SentinelAddrs, 2)
assert.Equal(t, providerConfig.redisSentinelConfig.SentinelAddrs[0], "redis.example.com:26379")
assert.Equal(t, providerConfig.redisSentinelConfig.SentinelAddrs[1], "redis2.example.com:26379")
}
func TestShouldCreateRedisSentinelSessionProvider(t *testing.T) {
configuration := schema.SessionConfiguration{}
configuration.Domain = testDomain
configuration.Name = testName
configuration.Expiration = testExpiration
configuration.Redis = &schema.RedisSessionConfiguration{
Host: "redis.example.com",
Port: 26379,
Password: "pass",
MaximumActiveConnections: 8,
MinimumIdleConnections: 2,
HighAvailability: &schema.RedisHighAvailabilityConfiguration{
SentinelName: "mysent",
SentinelPassword: "mypass",
Nodes: []schema.RedisNode{
{
Host: "redis2.example.com",
Port: 26379,
},
},
},
}
providerConfig := NewProviderConfig(configuration, nil)
assert.Nil(t, providerConfig.redisConfig)
assert.Equal(t, "my_session", providerConfig.config.CookieName)
assert.Equal(t, testDomain, providerConfig.config.Domain)
assert.Equal(t, true, providerConfig.config.Secure)
assert.Equal(t, time.Duration(40)*time.Second, providerConfig.config.Expiration)
assert.True(t, providerConfig.config.IsSecureFunc(nil))
assert.Equal(t, "redis-sentinel", providerConfig.providerName)
pConfig := providerConfig.redisSentinelConfig
assert.Equal(t, "redis.example.com:26379", pConfig.SentinelAddrs[0])
assert.Equal(t, "redis2.example.com:26379", pConfig.SentinelAddrs[1])
assert.Equal(t, "pass", pConfig.Password)
assert.Equal(t, "mysent", pConfig.MasterName)
assert.Equal(t, "mypass", pConfig.SentinelPassword)
assert.False(t, pConfig.RouteRandomly)
assert.False(t, pConfig.RouteByLatency)
assert.Equal(t, 8, pConfig.PoolSize)
assert.Equal(t, 2, pConfig.MinIdleConns)
// DbNumber is the fasthttp/session property for the Redis DB Index
assert.Equal(t, 0, pConfig.DB)
assert.Nil(t, pConfig.TLSConfig)
}
func TestShouldSetCookieSameSite(t *testing.T) {
configuration := schema.SessionConfiguration{}
configuration.Domain = testDomain
configuration.Name = testName
configuration.Expiration = testExpiration
configValueExpectedValue := map[string]fasthttp.CookieSameSite{
"": fasthttp.CookieSameSiteLaxMode,
"lax": fasthttp.CookieSameSiteLaxMode,
"strict": fasthttp.CookieSameSiteStrictMode,
"none": fasthttp.CookieSameSiteNoneMode,
"invalid": fasthttp.CookieSameSiteLaxMode,
}
for configValue, expectedValue := range configValueExpectedValue {
configuration.SameSite = configValue
providerConfig := NewProviderConfig(configuration, nil)
assert.Equal(t, expectedValue, providerConfig.config.CookieSameSite)
}
}
func TestShouldCreateRedisSessionProviderWithUnixSocket(t *testing.T) {
configuration := schema.SessionConfiguration{}
configuration.Domain = testDomain
configuration.Name = testName
configuration.Expiration = testExpiration
configuration.Redis = &schema.RedisSessionConfiguration{
Host: "/var/run/redis/redis.sock",
Port: 0,
Password: "pass",
}
providerConfig := NewProviderConfig(configuration, nil)
assert.Nil(t, providerConfig.redisSentinelConfig)
assert.Equal(t, "my_session", providerConfig.config.CookieName)
assert.Equal(t, testDomain, providerConfig.config.Domain)
assert.Equal(t, true, providerConfig.config.Secure)
assert.Equal(t, time.Duration(40)*time.Second, providerConfig.config.Expiration)
assert.True(t, providerConfig.config.IsSecureFunc(nil))
assert.Equal(t, "redis", providerConfig.providerName)
pConfig := providerConfig.redisConfig
assert.Equal(t, "/var/run/redis/redis.sock", pConfig.Addr)
assert.Equal(t, "pass", pConfig.Password)
// DbNumber is the fasthttp/session property for the Redis DB Index
assert.Equal(t, 0, pConfig.DB)
assert.Nil(t, pConfig.TLSConfig)
}
func TestShouldSetDbNumber(t *testing.T) {
configuration := schema.SessionConfiguration{}
configuration.Domain = testDomain
configuration.Name = testName
configuration.Expiration = testExpiration
configuration.Redis = &schema.RedisSessionConfiguration{
Host: "redis.example.com",
Port: 6379,
Password: "pass",
DatabaseIndex: 5,
}
providerConfig := NewProviderConfig(configuration, nil)
assert.Nil(t, providerConfig.redisSentinelConfig)
assert.Equal(t, "redis", providerConfig.providerName)
pConfig := providerConfig.redisConfig
// DbNumber is the fasthttp/session property for the Redis DB Index
assert.Equal(t, 5, pConfig.DB)
}
func TestShouldUseEncryptingSerializerWithRedis(t *testing.T) {
configuration := schema.SessionConfiguration{}
configuration.Secret = "abc"
configuration.Redis = &schema.RedisSessionConfiguration{
Host: "redis.example.com",
Port: 6379,
Password: "pass",
DatabaseIndex: 5,
}
providerConfig := NewProviderConfig(configuration, nil)
payload := session.Dict{}
payload.Set("key", "value")
encoded, err := providerConfig.config.EncodeFunc(payload)
require.NoError(t, err)
// Now we try to decrypt what has been serialized
key := sha256.Sum256([]byte("abc"))
decrypted, err := utils.Decrypt(encoded, &key)
require.NoError(t, err)
decoded := session.Dict{}
_, _ = decoded.UnmarshalMsg(decrypted)
assert.Equal(t, "value", decoded.Get("key"))
}