mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 07:16:38 +00:00
Add LocalAuthDisabled option to embedded IdP configuration This adds the ability to disable local (email/password) authentication when using the embedded Dex identity provider. When disabled, users can only authenticate via external identity providers (Google, OIDC, etc.). This simplifies user login when there is only one external IdP configured. The login page will redirect directly to the IdP login page. Key changes: Added LocalAuthDisabled field to EmbeddedIdPConfig Added methods to check and toggle local auth: IsLocalAuthEnabled, HasNonLocalConnectors, DisableLocalAuth, EnableLocalAuth Validation prevents disabling local auth if no external connectors are configured Existing local users are preserved when disabled and can login again when re-enabled Operations are idempotent (disabling already disabled is a no-op)
604 lines
17 KiB
Go
604 lines
17 KiB
Go
package idp
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/netbirdio/netbird/idp/dex"
|
|
)
|
|
|
|
func TestEmbeddedIdPManager_CreateUser_EndToEnd(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
// Create a temporary directory for the test
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create the embedded IDP config
|
|
config := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: filepath.Join(tmpDir, "dex.db"),
|
|
},
|
|
},
|
|
}
|
|
|
|
// Create the embedded IDP manager
|
|
manager, err := NewEmbeddedIdPManager(ctx, config, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager.Stop(ctx) }()
|
|
|
|
// Test data
|
|
email := "newuser@example.com"
|
|
name := "New User"
|
|
accountID := "test-account-id"
|
|
invitedByEmail := "admin@example.com"
|
|
|
|
// Create the user
|
|
userData, err := manager.CreateUser(ctx, email, name, accountID, invitedByEmail)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, userData)
|
|
|
|
t.Logf("Created user: ID=%s, Email=%s, Name=%s, Password=%s",
|
|
userData.ID, userData.Email, userData.Name, userData.Password)
|
|
|
|
// Verify user data
|
|
assert.Equal(t, email, userData.Email)
|
|
assert.Equal(t, name, userData.Name)
|
|
assert.NotEmpty(t, userData.ID)
|
|
assert.NotEmpty(t, userData.Password)
|
|
assert.Equal(t, accountID, userData.AppMetadata.WTAccountID)
|
|
assert.Equal(t, invitedByEmail, userData.AppMetadata.WTInvitedBy)
|
|
|
|
// Verify the user ID is in Dex's encoded format (base64 protobuf)
|
|
rawUserID, connectorID, err := dex.DecodeDexUserID(userData.ID)
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, rawUserID)
|
|
assert.Equal(t, "local", connectorID)
|
|
|
|
t.Logf("Decoded user ID: rawUserID=%s, connectorID=%s", rawUserID, connectorID)
|
|
|
|
// Verify we can look up the user by the encoded ID
|
|
lookedUpUser, err := manager.GetUserDataByID(ctx, userData.ID, AppMetadata{WTAccountID: accountID})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, email, lookedUpUser.Email)
|
|
|
|
// Verify we can look up by email
|
|
users, err := manager.GetUserByEmail(ctx, email)
|
|
require.NoError(t, err)
|
|
require.Len(t, users, 1)
|
|
assert.Equal(t, email, users[0].Email)
|
|
|
|
// Verify creating duplicate user fails
|
|
_, err = manager.CreateUser(ctx, email, name, accountID, invitedByEmail)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "already exists")
|
|
}
|
|
|
|
func TestEmbeddedIdPManager_GetUserDataByID_WithEncodedID(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
config := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: filepath.Join(tmpDir, "dex.db"),
|
|
},
|
|
},
|
|
}
|
|
|
|
manager, err := NewEmbeddedIdPManager(ctx, config, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager.Stop(ctx) }()
|
|
|
|
// Create a user first
|
|
userData, err := manager.CreateUser(ctx, "test@example.com", "Test User", "account1", "admin@example.com")
|
|
require.NoError(t, err)
|
|
|
|
// The returned ID should be encoded
|
|
encodedID := userData.ID
|
|
|
|
// Lookup should work with the encoded ID
|
|
lookedUp, err := manager.GetUserDataByID(ctx, encodedID, AppMetadata{WTAccountID: "account1"})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "test@example.com", lookedUp.Email)
|
|
assert.Equal(t, "Test User", lookedUp.Name)
|
|
}
|
|
|
|
func TestEmbeddedIdPManager_DeleteUser(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
config := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: filepath.Join(tmpDir, "dex.db"),
|
|
},
|
|
},
|
|
}
|
|
|
|
manager, err := NewEmbeddedIdPManager(ctx, config, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager.Stop(ctx) }()
|
|
|
|
// Create a user
|
|
userData, err := manager.CreateUser(ctx, "delete-me@example.com", "Delete Me", "account1", "admin@example.com")
|
|
require.NoError(t, err)
|
|
|
|
// Delete the user using the encoded ID
|
|
err = manager.DeleteUser(ctx, userData.ID)
|
|
require.NoError(t, err)
|
|
|
|
// Verify user no longer exists
|
|
_, err = manager.GetUserDataByID(ctx, userData.ID, AppMetadata{})
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestEmbeddedIdPManager_GetAccount(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
config := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: filepath.Join(tmpDir, "dex.db"),
|
|
},
|
|
},
|
|
}
|
|
|
|
manager, err := NewEmbeddedIdPManager(ctx, config, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager.Stop(ctx) }()
|
|
|
|
// Create multiple users
|
|
_, err = manager.CreateUser(ctx, "user1@example.com", "User 1", "account1", "admin@example.com")
|
|
require.NoError(t, err)
|
|
|
|
_, err = manager.CreateUser(ctx, "user2@example.com", "User 2", "account1", "admin@example.com")
|
|
require.NoError(t, err)
|
|
|
|
// Get all users for the account
|
|
users, err := manager.GetAccount(ctx, "account1")
|
|
require.NoError(t, err)
|
|
assert.Len(t, users, 2)
|
|
|
|
emails := make([]string, len(users))
|
|
for i, u := range users {
|
|
emails[i] = u.Email
|
|
}
|
|
assert.Contains(t, emails, "user1@example.com")
|
|
assert.Contains(t, emails, "user2@example.com")
|
|
}
|
|
|
|
func TestEmbeddedIdPManager_UserIDFormat_MatchesJWT(t *testing.T) {
|
|
// This test verifies that the user ID returned by CreateUser
|
|
// matches the format that Dex uses in JWT tokens (the 'sub' claim)
|
|
ctx := context.Background()
|
|
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
config := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: filepath.Join(tmpDir, "dex.db"),
|
|
},
|
|
},
|
|
}
|
|
|
|
manager, err := NewEmbeddedIdPManager(ctx, config, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager.Stop(ctx) }()
|
|
|
|
// Create a user
|
|
userData, err := manager.CreateUser(ctx, "jwt-test@example.com", "JWT Test", "account1", "admin@example.com")
|
|
require.NoError(t, err)
|
|
|
|
// The ID should be in the format: base64(protobuf{user_id, connector_id})
|
|
// Example: CiQ3YWFkOGMwNS0zMjg3LTQ3M2YtYjQyYS0zNjU1MDRiZjI1ZTcSBWxvY2Fs
|
|
|
|
// Verify it can be decoded
|
|
rawUserID, connectorID, err := dex.DecodeDexUserID(userData.ID)
|
|
require.NoError(t, err)
|
|
|
|
// Raw user ID should be a UUID
|
|
assert.Regexp(t, `^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`, rawUserID)
|
|
|
|
// Connector ID should be "local" for password-based auth
|
|
assert.Equal(t, "local", connectorID)
|
|
|
|
// Re-encoding should produce the same result
|
|
reEncoded := dex.EncodeDexUserID(rawUserID, connectorID)
|
|
assert.Equal(t, userData.ID, reEncoded)
|
|
|
|
t.Logf("User ID format verified:")
|
|
t.Logf(" Encoded ID: %s", userData.ID)
|
|
t.Logf(" Raw UUID: %s", rawUserID)
|
|
t.Logf(" Connector: %s", connectorID)
|
|
}
|
|
|
|
func TestEmbeddedIdPManager_UpdateUserPassword(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
config := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: filepath.Join(tmpDir, "dex.db"),
|
|
},
|
|
},
|
|
}
|
|
|
|
manager, err := NewEmbeddedIdPManager(ctx, config, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager.Stop(ctx) }()
|
|
|
|
// Create a user with a known password
|
|
email := "password-test@example.com"
|
|
name := "Password Test User"
|
|
initialPassword := "InitialPass123!"
|
|
|
|
userData, err := manager.CreateUserWithPassword(ctx, email, initialPassword, name)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, userData)
|
|
|
|
userID := userData.ID
|
|
|
|
t.Run("successful password change", func(t *testing.T) {
|
|
newPassword := "NewSecurePass456!"
|
|
err := manager.UpdateUserPassword(ctx, userID, userID, initialPassword, newPassword)
|
|
require.NoError(t, err)
|
|
|
|
// Verify the new password works by changing it again
|
|
anotherPassword := "AnotherPass789!"
|
|
err = manager.UpdateUserPassword(ctx, userID, userID, newPassword, anotherPassword)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("wrong old password", func(t *testing.T) {
|
|
err := manager.UpdateUserPassword(ctx, userID, userID, "wrongpassword", "NewPass123!")
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "current password is incorrect")
|
|
})
|
|
|
|
t.Run("cannot change other user password", func(t *testing.T) {
|
|
otherUserID := "other-user-id"
|
|
err := manager.UpdateUserPassword(ctx, userID, otherUserID, "oldpass", "newpass")
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "users can only change their own password")
|
|
})
|
|
|
|
t.Run("same password rejected", func(t *testing.T) {
|
|
samePassword := "SamePass123!"
|
|
err := manager.UpdateUserPassword(ctx, userID, userID, samePassword, samePassword)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "new password must be different")
|
|
})
|
|
}
|
|
|
|
func TestEmbeddedIdPManager_GetLocalKeysLocation(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
tests := []struct {
|
|
name string
|
|
localAddress string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "localhost with port",
|
|
localAddress: "localhost:8080",
|
|
expected: "http://localhost:8080/oauth2/keys",
|
|
},
|
|
{
|
|
name: "localhost with https port",
|
|
localAddress: "localhost:443",
|
|
expected: "http://localhost:443/oauth2/keys",
|
|
},
|
|
{
|
|
name: "port only format",
|
|
localAddress: ":8080",
|
|
expected: "http://localhost:8080/oauth2/keys",
|
|
},
|
|
{
|
|
name: "empty address",
|
|
localAddress: "",
|
|
expected: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
config := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
LocalAddress: tt.localAddress,
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: filepath.Join(tmpDir, "dex-"+tt.name+".db"),
|
|
},
|
|
},
|
|
}
|
|
|
|
manager, err := NewEmbeddedIdPManager(ctx, config, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager.Stop(ctx) }()
|
|
|
|
result := manager.GetLocalKeysLocation()
|
|
assert.Equal(t, tt.expected, result)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEmbeddedIdPManager_LocalAuthDisabled(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
t.Run("cannot start with local auth disabled without other connectors", func(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
config := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
LocalAuthDisabled: true,
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: filepath.Join(tmpDir, "dex.db"),
|
|
},
|
|
},
|
|
}
|
|
|
|
_, err = NewEmbeddedIdPManager(ctx, config, nil)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "no other identity providers configured")
|
|
})
|
|
|
|
t.Run("local auth enabled by default", func(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
config := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: filepath.Join(tmpDir, "dex.db"),
|
|
},
|
|
},
|
|
}
|
|
|
|
manager, err := NewEmbeddedIdPManager(ctx, config, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager.Stop(ctx) }()
|
|
|
|
// Verify local auth is enabled by default
|
|
assert.False(t, manager.IsLocalAuthDisabled())
|
|
})
|
|
|
|
t.Run("start with local auth disabled when connector exists", func(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
dbFile := filepath.Join(tmpDir, "dex.db")
|
|
|
|
// First, create a manager with local auth enabled and add a connector
|
|
config1 := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: dbFile,
|
|
},
|
|
},
|
|
}
|
|
|
|
manager1, err := NewEmbeddedIdPManager(ctx, config1, nil)
|
|
require.NoError(t, err)
|
|
|
|
// Create a user
|
|
userData, err := manager1.CreateUser(ctx, "preserved@example.com", "Preserved User", "account1", "admin@example.com")
|
|
require.NoError(t, err)
|
|
userID := userData.ID
|
|
|
|
// Add an external connector (Google doesn't require OIDC discovery)
|
|
_, err = manager1.CreateConnector(ctx, &dex.ConnectorConfig{
|
|
ID: "google-test",
|
|
Name: "Google Test",
|
|
Type: "google",
|
|
ClientID: "test-client-id",
|
|
ClientSecret: "test-client-secret",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Stop the first manager
|
|
err = manager1.Stop(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// Now create a new manager with local auth disabled
|
|
config2 := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
LocalAuthDisabled: true,
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: dbFile,
|
|
},
|
|
},
|
|
}
|
|
|
|
manager2, err := NewEmbeddedIdPManager(ctx, config2, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager2.Stop(ctx) }()
|
|
|
|
// Verify local auth is disabled via config
|
|
assert.True(t, manager2.IsLocalAuthDisabled())
|
|
|
|
// Verify the user still exists in storage (just can't login via local)
|
|
lookedUp, err := manager2.GetUserDataByID(ctx, userID, AppMetadata{})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "preserved@example.com", lookedUp.Email)
|
|
})
|
|
|
|
t.Run("CreateUser fails when local auth is disabled", func(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
dbFile := filepath.Join(tmpDir, "dex.db")
|
|
|
|
// First, create a manager and add an external connector
|
|
config1 := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: dbFile,
|
|
},
|
|
},
|
|
}
|
|
|
|
manager1, err := NewEmbeddedIdPManager(ctx, config1, nil)
|
|
require.NoError(t, err)
|
|
|
|
_, err = manager1.CreateConnector(ctx, &dex.ConnectorConfig{
|
|
ID: "google-test",
|
|
Name: "Google Test",
|
|
Type: "google",
|
|
ClientID: "test-client-id",
|
|
ClientSecret: "test-client-secret",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
err = manager1.Stop(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// Create manager with local auth disabled
|
|
config2 := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
LocalAuthDisabled: true,
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: dbFile,
|
|
},
|
|
},
|
|
}
|
|
|
|
manager2, err := NewEmbeddedIdPManager(ctx, config2, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager2.Stop(ctx) }()
|
|
|
|
// Try to create a user - should fail
|
|
_, err = manager2.CreateUser(ctx, "newuser@example.com", "New User", "account1", "admin@example.com")
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "local user creation is disabled")
|
|
})
|
|
|
|
t.Run("CreateUserWithPassword fails when local auth is disabled", func(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "embedded-idp-test-*")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
dbFile := filepath.Join(tmpDir, "dex.db")
|
|
|
|
// First, create a manager and add an external connector
|
|
config1 := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: dbFile,
|
|
},
|
|
},
|
|
}
|
|
|
|
manager1, err := NewEmbeddedIdPManager(ctx, config1, nil)
|
|
require.NoError(t, err)
|
|
|
|
_, err = manager1.CreateConnector(ctx, &dex.ConnectorConfig{
|
|
ID: "google-test",
|
|
Name: "Google Test",
|
|
Type: "google",
|
|
ClientID: "test-client-id",
|
|
ClientSecret: "test-client-secret",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
err = manager1.Stop(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// Create manager with local auth disabled
|
|
config2 := &EmbeddedIdPConfig{
|
|
Enabled: true,
|
|
Issuer: "http://localhost:5556/dex",
|
|
LocalAuthDisabled: true,
|
|
Storage: EmbeddedStorageConfig{
|
|
Type: "sqlite3",
|
|
Config: EmbeddedStorageTypeConfig{
|
|
File: dbFile,
|
|
},
|
|
},
|
|
}
|
|
|
|
manager2, err := NewEmbeddedIdPManager(ctx, config2, nil)
|
|
require.NoError(t, err)
|
|
defer func() { _ = manager2.Stop(ctx) }()
|
|
|
|
// Try to create a user with password - should fail
|
|
_, err = manager2.CreateUserWithPassword(ctx, "newuser@example.com", "SecurePass123!", "New User")
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "local user creation is disabled")
|
|
})
|
|
}
|