mirror of
https://github.com/pocketbase/pocketbase.git
synced 2024-11-24 17:07:00 +02:00
619 lines
15 KiB
Go
619 lines
15 KiB
Go
package core_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/pocketbase/pocketbase/core"
|
|
"github.com/pocketbase/pocketbase/tools/auth"
|
|
)
|
|
|
|
func TestSettingsValidate(t *testing.T) {
|
|
s := core.NewSettings()
|
|
|
|
// set invalid settings data
|
|
s.Meta.AppName = ""
|
|
s.Logs.MaxDays = -10
|
|
s.Smtp.Enabled = true
|
|
s.Smtp.Host = ""
|
|
s.S3.Enabled = true
|
|
s.S3.Endpoint = "invalid"
|
|
s.AdminAuthToken.Duration = -10
|
|
s.AdminPasswordResetToken.Duration = -10
|
|
s.UserAuthToken.Duration = -10
|
|
s.UserPasswordResetToken.Duration = -10
|
|
s.UserEmailChangeToken.Duration = -10
|
|
s.UserVerificationToken.Duration = -10
|
|
s.EmailAuth.Enabled = true
|
|
s.EmailAuth.MinPasswordLength = -10
|
|
s.GoogleAuth.Enabled = true
|
|
s.GoogleAuth.ClientId = ""
|
|
s.FacebookAuth.Enabled = true
|
|
s.FacebookAuth.ClientId = ""
|
|
s.GithubAuth.Enabled = true
|
|
s.GithubAuth.ClientId = ""
|
|
s.GitlabAuth.Enabled = true
|
|
s.GitlabAuth.ClientId = ""
|
|
|
|
// check if Validate() is triggering the members validate methods.
|
|
err := s.Validate()
|
|
if err == nil {
|
|
t.Fatalf("Expected error, got nil")
|
|
}
|
|
|
|
expectations := []string{
|
|
`"meta":{`,
|
|
`"logs":{`,
|
|
`"smtp":{`,
|
|
`"s3":{`,
|
|
`"adminAuthToken":{`,
|
|
`"adminPasswordResetToken":{`,
|
|
`"userAuthToken":{`,
|
|
`"userPasswordResetToken":{`,
|
|
`"userEmailChangeToken":{`,
|
|
`"userVerificationToken":{`,
|
|
`"emailAuth":{`,
|
|
`"googleAuth":{`,
|
|
`"facebookAuth":{`,
|
|
`"githubAuth":{`,
|
|
`"gitlabAuth":{`,
|
|
}
|
|
|
|
errBytes, _ := json.Marshal(err)
|
|
jsonErr := string(errBytes)
|
|
for _, expected := range expectations {
|
|
if !strings.Contains(jsonErr, expected) {
|
|
t.Errorf("Expected error key %s in %v", expected, jsonErr)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSettingsMerge(t *testing.T) {
|
|
s1 := core.NewSettings()
|
|
s1.Meta.AppUrl = "old_app_url"
|
|
|
|
s2 := core.NewSettings()
|
|
s2.Meta.AppName = "test"
|
|
s2.Logs.MaxDays = 123
|
|
s2.Smtp.Host = "test"
|
|
s2.Smtp.Enabled = true
|
|
s2.S3.Enabled = true
|
|
s2.S3.Endpoint = "test"
|
|
s2.AdminAuthToken.Duration = 1
|
|
s2.AdminPasswordResetToken.Duration = 2
|
|
s2.UserAuthToken.Duration = 3
|
|
s2.UserPasswordResetToken.Duration = 4
|
|
s2.UserEmailChangeToken.Duration = 5
|
|
s2.UserVerificationToken.Duration = 6
|
|
s2.EmailAuth.Enabled = false
|
|
s2.EmailAuth.MinPasswordLength = 30
|
|
s2.GoogleAuth.Enabled = true
|
|
s2.GoogleAuth.ClientId = "google_test"
|
|
s2.FacebookAuth.Enabled = true
|
|
s2.FacebookAuth.ClientId = "facebook_test"
|
|
s2.GithubAuth.Enabled = true
|
|
s2.GithubAuth.ClientId = "github_test"
|
|
s2.GitlabAuth.Enabled = true
|
|
s2.GitlabAuth.ClientId = "gitlab_test"
|
|
|
|
if err := s1.Merge(s2); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
s1Encoded, err := json.Marshal(s1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
s2Encoded, err := json.Marshal(s2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if string(s1Encoded) != string(s2Encoded) {
|
|
t.Fatalf("Expected the same serialization, got %v VS %v", string(s1Encoded), string(s2Encoded))
|
|
}
|
|
}
|
|
|
|
func TestSettingsClone(t *testing.T) {
|
|
s1 := core.NewSettings()
|
|
|
|
s2, err := s1.Clone()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
s1Bytes, err := json.Marshal(s1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
s2Bytes, err := json.Marshal(s2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if string(s1Bytes) != string(s2Bytes) {
|
|
t.Fatalf("Expected equivalent serialization, got %v VS %v", string(s1Bytes), string(s2Bytes))
|
|
}
|
|
|
|
// verify that it is a deep copy
|
|
s1.Meta.AppName = "new"
|
|
if s1.Meta.AppName == s2.Meta.AppName {
|
|
t.Fatalf("Expected s1 and s2 to have different Meta.AppName, got %s", s1.Meta.AppName)
|
|
}
|
|
}
|
|
|
|
func TestSettingsRedactClone(t *testing.T) {
|
|
s1 := core.NewSettings()
|
|
s1.Meta.AppName = "test123" // control field
|
|
s1.Smtp.Password = "test123"
|
|
s1.Smtp.Tls = true
|
|
s1.S3.Secret = "test123"
|
|
s1.AdminAuthToken.Secret = "test123"
|
|
s1.AdminPasswordResetToken.Secret = "test123"
|
|
s1.UserAuthToken.Secret = "test123"
|
|
s1.UserPasswordResetToken.Secret = "test123"
|
|
s1.UserEmailChangeToken.Secret = "test123"
|
|
s1.UserVerificationToken.Secret = "test123"
|
|
s1.GoogleAuth.ClientSecret = "test123"
|
|
s1.FacebookAuth.ClientSecret = "test123"
|
|
s1.GithubAuth.ClientSecret = "test123"
|
|
s1.GitlabAuth.ClientSecret = "test123"
|
|
|
|
s2, err := s1.RedactClone()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
encoded, err := json.Marshal(s2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `{"meta":{"appName":"test123","appUrl":"http://localhost:8090","senderName":"Support","senderAddress":"support@example.com","userVerificationUrl":"%APP_URL%/_/#/users/confirm-verification/%TOKEN%","userResetPasswordUrl":"%APP_URL%/_/#/users/confirm-password-reset/%TOKEN%","userConfirmEmailChangeUrl":"%APP_URL%/_/#/users/confirm-email-change/%TOKEN%"},"logs":{"maxDays":7},"smtp":{"enabled":false,"host":"smtp.example.com","port":587,"username":"","password":"******","tls":true},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","secret":"******"},"adminAuthToken":{"secret":"******","duration":1209600},"adminPasswordResetToken":{"secret":"******","duration":1800},"userAuthToken":{"secret":"******","duration":1209600},"userPasswordResetToken":{"secret":"******","duration":1800},"userEmailChangeToken":{"secret":"******","duration":1800},"userVerificationToken":{"secret":"******","duration":604800},"emailAuth":{"enabled":true,"exceptDomains":null,"onlyDomains":null,"minPasswordLength":8},"googleAuth":{"enabled":false,"allowRegistrations":true,"clientSecret":"******"},"facebookAuth":{"enabled":false,"allowRegistrations":true,"clientSecret":"******"},"githubAuth":{"enabled":false,"allowRegistrations":true,"clientSecret":"******"},"gitlabAuth":{"enabled":false,"allowRegistrations":true,"clientSecret":"******"}}`
|
|
|
|
if encodedStr := string(encoded); encodedStr != expected {
|
|
t.Fatalf("Expected %v, got \n%v", expected, encodedStr)
|
|
}
|
|
}
|
|
|
|
func TestNamedAuthProviderConfigs(t *testing.T) {
|
|
s := core.NewSettings()
|
|
|
|
s.GoogleAuth.ClientId = "google_test"
|
|
s.FacebookAuth.ClientId = "facebook_test"
|
|
s.GithubAuth.ClientId = "github_test"
|
|
s.GitlabAuth.ClientId = "gitlab_test"
|
|
s.GitlabAuth.Enabled = true
|
|
|
|
result := s.NamedAuthProviderConfigs()
|
|
|
|
encoded, err := json.Marshal(result)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `{"facebook":{"enabled":false,"allowRegistrations":true,"clientId":"facebook_test"},"github":{"enabled":false,"allowRegistrations":true,"clientId":"github_test"},"gitlab":{"enabled":true,"allowRegistrations":true,"clientId":"gitlab_test"},"google":{"enabled":false,"allowRegistrations":true,"clientId":"google_test"}}`
|
|
|
|
if encodedStr := string(encoded); encodedStr != expected {
|
|
t.Fatalf("Expected the same serialization, got %v", encodedStr)
|
|
}
|
|
}
|
|
|
|
func TestTokenConfigValidate(t *testing.T) {
|
|
scenarios := []struct {
|
|
config core.TokenConfig
|
|
expectError bool
|
|
}{
|
|
// zero values
|
|
{
|
|
core.TokenConfig{},
|
|
true,
|
|
},
|
|
// invalid data
|
|
{
|
|
core.TokenConfig{
|
|
Secret: "test",
|
|
Duration: 4,
|
|
},
|
|
true,
|
|
},
|
|
// valid data
|
|
{
|
|
core.TokenConfig{
|
|
Secret: "testtesttesttesttesttesttestte",
|
|
Duration: 100,
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for i, scenario := range scenarios {
|
|
result := scenario.config.Validate()
|
|
|
|
if result != nil && !scenario.expectError {
|
|
t.Errorf("(%d) Didn't expect error, got %v", i, result)
|
|
}
|
|
|
|
if result == nil && scenario.expectError {
|
|
t.Errorf("(%d) Expected error, got nil", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSmtpConfigValidate(t *testing.T) {
|
|
scenarios := []struct {
|
|
config core.SmtpConfig
|
|
expectError bool
|
|
}{
|
|
// zero values (disabled)
|
|
{
|
|
core.SmtpConfig{},
|
|
false,
|
|
},
|
|
// zero values (enabled)
|
|
{
|
|
core.SmtpConfig{Enabled: true},
|
|
true,
|
|
},
|
|
// invalid data
|
|
{
|
|
core.SmtpConfig{
|
|
Enabled: true,
|
|
Host: "test:test:test",
|
|
Port: -10,
|
|
},
|
|
true,
|
|
},
|
|
// valid data
|
|
{
|
|
core.SmtpConfig{
|
|
Enabled: true,
|
|
Host: "example.com",
|
|
Port: 100,
|
|
Tls: true,
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for i, scenario := range scenarios {
|
|
result := scenario.config.Validate()
|
|
|
|
if result != nil && !scenario.expectError {
|
|
t.Errorf("(%d) Didn't expect error, got %v", i, result)
|
|
}
|
|
|
|
if result == nil && scenario.expectError {
|
|
t.Errorf("(%d) Expected error, got nil", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestS3ConfigValidate(t *testing.T) {
|
|
scenarios := []struct {
|
|
config core.S3Config
|
|
expectError bool
|
|
}{
|
|
// zero values (disabled)
|
|
{
|
|
core.S3Config{},
|
|
false,
|
|
},
|
|
// zero values (enabled)
|
|
{
|
|
core.S3Config{Enabled: true},
|
|
true,
|
|
},
|
|
// invalid data
|
|
{
|
|
core.S3Config{
|
|
Enabled: true,
|
|
Endpoint: "test:test:test",
|
|
},
|
|
true,
|
|
},
|
|
// valid data (url endpoint)
|
|
{
|
|
core.S3Config{
|
|
Enabled: true,
|
|
Endpoint: "https://localhost:8090",
|
|
Bucket: "test",
|
|
Region: "test",
|
|
AccessKey: "test",
|
|
Secret: "test",
|
|
},
|
|
false,
|
|
},
|
|
// valid data (hostname endpoint)
|
|
{
|
|
core.S3Config{
|
|
Enabled: true,
|
|
Endpoint: "example.com",
|
|
Bucket: "test",
|
|
Region: "test",
|
|
AccessKey: "test",
|
|
Secret: "test",
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for i, scenario := range scenarios {
|
|
result := scenario.config.Validate()
|
|
|
|
if result != nil && !scenario.expectError {
|
|
t.Errorf("(%d) Didn't expect error, got %v", i, result)
|
|
}
|
|
|
|
if result == nil && scenario.expectError {
|
|
t.Errorf("(%d) Expected error, got nil", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMetaConfigValidate(t *testing.T) {
|
|
scenarios := []struct {
|
|
config core.MetaConfig
|
|
expectError bool
|
|
}{
|
|
// zero values
|
|
{
|
|
core.MetaConfig{},
|
|
true,
|
|
},
|
|
// invalid data
|
|
{
|
|
core.MetaConfig{
|
|
AppName: strings.Repeat("a", 300),
|
|
AppUrl: "test",
|
|
SenderName: strings.Repeat("a", 300),
|
|
SenderAddress: "invalid_email",
|
|
UserVerificationUrl: "test",
|
|
UserResetPasswordUrl: "test",
|
|
UserConfirmEmailChangeUrl: "test",
|
|
},
|
|
true,
|
|
},
|
|
// invalid data (missing required placeholders)
|
|
{
|
|
core.MetaConfig{
|
|
AppName: "test",
|
|
AppUrl: "https://example.com",
|
|
SenderName: "test",
|
|
SenderAddress: "test@example.com",
|
|
UserVerificationUrl: "https://example.com",
|
|
UserResetPasswordUrl: "https://example.com",
|
|
UserConfirmEmailChangeUrl: "https://example.com",
|
|
},
|
|
true,
|
|
},
|
|
// valid data
|
|
{
|
|
core.MetaConfig{
|
|
AppName: "test",
|
|
AppUrl: "https://example.com",
|
|
SenderName: "test",
|
|
SenderAddress: "test@example.com",
|
|
UserVerificationUrl: "https://example.com/" + core.EmailPlaceholderToken,
|
|
UserResetPasswordUrl: "https://example.com/" + core.EmailPlaceholderToken,
|
|
UserConfirmEmailChangeUrl: "https://example.com/" + core.EmailPlaceholderToken,
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for i, scenario := range scenarios {
|
|
result := scenario.config.Validate()
|
|
|
|
if result != nil && !scenario.expectError {
|
|
t.Errorf("(%d) Didn't expect error, got %v", i, result)
|
|
}
|
|
|
|
if result == nil && scenario.expectError {
|
|
t.Errorf("(%d) Expected error, got nil", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLogsConfigValidate(t *testing.T) {
|
|
scenarios := []struct {
|
|
config core.LogsConfig
|
|
expectError bool
|
|
}{
|
|
// zero values
|
|
{
|
|
core.LogsConfig{},
|
|
false,
|
|
},
|
|
// invalid data
|
|
{
|
|
core.LogsConfig{MaxDays: -10},
|
|
true,
|
|
},
|
|
// valid data
|
|
{
|
|
core.LogsConfig{MaxDays: 1},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for i, scenario := range scenarios {
|
|
result := scenario.config.Validate()
|
|
|
|
if result != nil && !scenario.expectError {
|
|
t.Errorf("(%d) Didn't expect error, got %v", i, result)
|
|
}
|
|
|
|
if result == nil && scenario.expectError {
|
|
t.Errorf("(%d) Expected error, got nil", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAuthProviderConfigValidate(t *testing.T) {
|
|
scenarios := []struct {
|
|
config core.AuthProviderConfig
|
|
expectError bool
|
|
}{
|
|
// zero values (disabled)
|
|
{
|
|
core.AuthProviderConfig{},
|
|
false,
|
|
},
|
|
// zero values (enabled)
|
|
{
|
|
core.AuthProviderConfig{Enabled: true},
|
|
true,
|
|
},
|
|
// invalid data
|
|
{
|
|
core.AuthProviderConfig{
|
|
Enabled: true,
|
|
ClientId: "",
|
|
ClientSecret: "",
|
|
AuthUrl: "test",
|
|
TokenUrl: "test",
|
|
UserApiUrl: "test",
|
|
},
|
|
true,
|
|
},
|
|
// valid data (only the required)
|
|
{
|
|
core.AuthProviderConfig{
|
|
Enabled: true,
|
|
ClientId: "test",
|
|
ClientSecret: "test",
|
|
},
|
|
false,
|
|
},
|
|
// valid data (fill all fields)
|
|
{
|
|
core.AuthProviderConfig{
|
|
Enabled: true,
|
|
ClientId: "test",
|
|
ClientSecret: "test",
|
|
AuthUrl: "https://example.com",
|
|
TokenUrl: "https://example.com",
|
|
UserApiUrl: "https://example.com",
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for i, scenario := range scenarios {
|
|
result := scenario.config.Validate()
|
|
|
|
if result != nil && !scenario.expectError {
|
|
t.Errorf("(%d) Didn't expect error, got %v", i, result)
|
|
}
|
|
|
|
if result == nil && scenario.expectError {
|
|
t.Errorf("(%d) Expected error, got nil", i)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAuthProviderConfigSetupProvider(t *testing.T) {
|
|
provider := auth.NewGithubProvider()
|
|
|
|
// disabled config
|
|
c1 := core.AuthProviderConfig{Enabled: false}
|
|
if err := c1.SetupProvider(provider); err == nil {
|
|
t.Errorf("Expected error, got nil")
|
|
}
|
|
|
|
c2 := core.AuthProviderConfig{
|
|
Enabled: true,
|
|
ClientId: "test_ClientId",
|
|
ClientSecret: "test_ClientSecret",
|
|
AuthUrl: "test_AuthUrl",
|
|
UserApiUrl: "test_UserApiUrl",
|
|
TokenUrl: "test_TokenUrl",
|
|
}
|
|
if err := c2.SetupProvider(provider); err != nil {
|
|
t.Error(err)
|
|
}
|
|
encoded, _ := json.Marshal(c2)
|
|
expected := `{"enabled":true,"allowRegistrations":false,"clientId":"test_ClientId","clientSecret":"test_ClientSecret","authUrl":"test_AuthUrl","tokenUrl":"test_TokenUrl","userApiUrl":"test_UserApiUrl"}`
|
|
if string(encoded) != expected {
|
|
t.Errorf("Expected %s, got %s", expected, string(encoded))
|
|
}
|
|
}
|
|
|
|
func TestEmailAuthConfigValidate(t *testing.T) {
|
|
scenarios := []struct {
|
|
config core.EmailAuthConfig
|
|
expectError bool
|
|
}{
|
|
// zero values (disabled)
|
|
{
|
|
core.EmailAuthConfig{},
|
|
false,
|
|
},
|
|
// zero values (enabled)
|
|
{
|
|
core.EmailAuthConfig{Enabled: true},
|
|
true,
|
|
},
|
|
// invalid data (only the required)
|
|
{
|
|
core.EmailAuthConfig{
|
|
Enabled: true,
|
|
MinPasswordLength: 4,
|
|
},
|
|
true,
|
|
},
|
|
// valid data (only the required)
|
|
{
|
|
core.EmailAuthConfig{
|
|
Enabled: true,
|
|
MinPasswordLength: 5,
|
|
},
|
|
false,
|
|
},
|
|
// invalid data (both OnlyDomains and ExceptDomains set)
|
|
{
|
|
core.EmailAuthConfig{
|
|
Enabled: true,
|
|
MinPasswordLength: 5,
|
|
OnlyDomains: []string{"example.com", "test.com"},
|
|
ExceptDomains: []string{"example.com", "test.com"},
|
|
},
|
|
true,
|
|
},
|
|
// valid data (only onlyDomains set)
|
|
{
|
|
core.EmailAuthConfig{
|
|
Enabled: true,
|
|
MinPasswordLength: 5,
|
|
OnlyDomains: []string{"example.com", "test.com"},
|
|
},
|
|
false,
|
|
},
|
|
// valid data (only exceptDomains set)
|
|
{
|
|
core.EmailAuthConfig{
|
|
Enabled: true,
|
|
MinPasswordLength: 5,
|
|
ExceptDomains: []string{"example.com", "test.com"},
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for i, scenario := range scenarios {
|
|
result := scenario.config.Validate()
|
|
|
|
if result != nil && !scenario.expectError {
|
|
t.Errorf("(%d) Didn't expect error, got %v", i, result)
|
|
}
|
|
|
|
if result == nil && scenario.expectError {
|
|
t.Errorf("(%d) Expected error, got nil", i)
|
|
}
|
|
}
|
|
}
|