mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-13 00:49:07 +02:00
The user half reused nothing: SaveUserLastLogin already exists and is the same call the dashboard and device login paths make, so the parallel RefreshUserLastLogin is gone and the proxy uses the established one. Reaching it no longer widens shared interfaces. The proxy service already receives the store, narrowed to ProxyTokenChecker; that interface now carries the two writes the proxy makes, so users.Manager, peers.Manager and Peer are untouched and the exclusion predicate moved into the proxy package next to its only caller. RefreshPeerLastSeen stays on the store because nothing there fits: SavePeerStatus rewrites the connected flag and session token from a caller snapshot, which would race the sync stream that owns them.
614 lines
22 KiB
Go
614 lines
22 KiB
Go
//go:build integration
|
|
|
|
package grpc
|
|
|
|
import (
|
|
"context"
|
|
"crypto/ed25519"
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/netbirdio/netbird/management/internals/modules/reverseproxy/proxy"
|
|
"github.com/netbirdio/netbird/management/internals/modules/reverseproxy/service"
|
|
"github.com/netbirdio/netbird/management/internals/modules/reverseproxy/sessionkey"
|
|
"github.com/netbirdio/netbird/management/server/store"
|
|
"github.com/netbirdio/netbird/management/server/types"
|
|
"github.com/netbirdio/netbird/proxy/auth"
|
|
"github.com/netbirdio/netbird/shared/management/proto"
|
|
)
|
|
|
|
type validateSessionTestSetup struct {
|
|
proxyService *ProxyServiceServer
|
|
store store.Store
|
|
cleanup func()
|
|
}
|
|
|
|
func setupValidateSessionTest(t *testing.T) *validateSessionTestSetup {
|
|
t.Helper()
|
|
|
|
ctx := context.Background()
|
|
testStore, storeCleanup, err := store.NewTestStoreFromSQL(ctx, "../../../server/testdata/auth_callback.sql", t.TempDir())
|
|
require.NoError(t, err)
|
|
|
|
serviceManager := &testValidateSessionServiceManager{store: testStore}
|
|
usersManager := &testValidateSessionUsersManager{store: testStore}
|
|
proxyManager := &testValidateSessionProxyManager{}
|
|
|
|
tokenStore := NewOneTimeTokenStore(ctx, testCacheStore(t))
|
|
pkceStore := NewPKCEVerifierStore(ctx, testCacheStore(t))
|
|
|
|
proxyService := NewProxyServiceServer(nil, tokenStore, pkceStore, ProxyOIDCConfig{}, nil, usersManager, nil, proxyManager, nil)
|
|
proxyService.SetServiceManager(serviceManager)
|
|
|
|
createTestProxies(t, ctx, testStore)
|
|
createStatusTestUsers(t, ctx, testStore)
|
|
|
|
return &validateSessionTestSetup{
|
|
proxyService: proxyService,
|
|
store: testStore,
|
|
cleanup: storeCleanup,
|
|
}
|
|
}
|
|
|
|
func createTestProxies(t *testing.T, ctx context.Context, testStore store.Store) {
|
|
t.Helper()
|
|
|
|
pubKey, privKey := generateSessionKeyPair(t)
|
|
|
|
testProxy := &service.Service{
|
|
ID: "testProxyId",
|
|
AccountID: "testAccountId",
|
|
Name: "Test Proxy",
|
|
Domain: "test-proxy.example.com",
|
|
Enabled: true,
|
|
SessionPrivateKey: privKey,
|
|
SessionPublicKey: pubKey,
|
|
Auth: service.AuthConfig{
|
|
BearerAuth: &service.BearerAuthConfig{
|
|
Enabled: true,
|
|
},
|
|
},
|
|
}
|
|
require.NoError(t, testStore.CreateService(ctx, testProxy))
|
|
|
|
restrictedProxy := &service.Service{
|
|
ID: "restrictedProxyId",
|
|
AccountID: "testAccountId",
|
|
Name: "Restricted Proxy",
|
|
Domain: "restricted-proxy.example.com",
|
|
Enabled: true,
|
|
SessionPrivateKey: privKey,
|
|
SessionPublicKey: pubKey,
|
|
Auth: service.AuthConfig{
|
|
BearerAuth: &service.BearerAuthConfig{
|
|
Enabled: true,
|
|
DistributionGroups: []string{"allowedGroupId"},
|
|
},
|
|
},
|
|
}
|
|
require.NoError(t, testStore.CreateService(ctx, restrictedProxy))
|
|
|
|
// Distributed to the account's "All" group, the configuration that hands a
|
|
// service to every user in the account.
|
|
allUsersProxy := &service.Service{
|
|
ID: "allUsersProxyId",
|
|
AccountID: "testAccountId",
|
|
Name: "All Users Proxy",
|
|
Domain: "all-users-proxy.example.com",
|
|
Enabled: true,
|
|
SessionPrivateKey: privKey,
|
|
SessionPublicKey: pubKey,
|
|
Auth: service.AuthConfig{
|
|
BearerAuth: &service.BearerAuthConfig{
|
|
Enabled: true,
|
|
DistributionGroups: []string{allUsersGroupID},
|
|
},
|
|
},
|
|
}
|
|
require.NoError(t, testStore.CreateService(ctx, allUsersProxy))
|
|
}
|
|
|
|
const (
|
|
allUsersGroupID = "allUsersGroupId"
|
|
pendingUserID = "pendingUserId"
|
|
blockedUserID = "blockedUserId"
|
|
pendingAllUsersID = "pendingAllUsersUserId"
|
|
)
|
|
|
|
// createStatusTestUsers adds the users whose account status must keep them out
|
|
// of a proxy session. A user awaiting approval is persisted as both blocked and
|
|
// pending approval, the way the approval flow stores one.
|
|
func createStatusTestUsers(t *testing.T, ctx context.Context, testStore store.Store) {
|
|
t.Helper()
|
|
|
|
require.NoError(t, testStore.CreateGroup(ctx, &types.Group{
|
|
ID: allUsersGroupID,
|
|
AccountID: "testAccountId",
|
|
Name: "All",
|
|
Issued: types.GroupIssuedAPI,
|
|
}))
|
|
|
|
users := []*types.User{
|
|
{
|
|
Id: pendingUserID,
|
|
AccountID: "testAccountId",
|
|
Role: types.UserRoleUser,
|
|
AutoGroups: []string{"allowedGroupId"},
|
|
Blocked: true,
|
|
PendingApproval: true,
|
|
Issued: "api",
|
|
CreatedAt: time.Now(),
|
|
},
|
|
{
|
|
Id: pendingAllUsersID,
|
|
AccountID: "testAccountId",
|
|
Role: types.UserRoleUser,
|
|
AutoGroups: []string{allUsersGroupID},
|
|
Blocked: true,
|
|
PendingApproval: true,
|
|
Issued: "api",
|
|
CreatedAt: time.Now(),
|
|
},
|
|
{
|
|
Id: blockedUserID,
|
|
AccountID: "testAccountId",
|
|
Role: types.UserRoleUser,
|
|
AutoGroups: []string{"allowedGroupId"},
|
|
Blocked: true,
|
|
PendingApproval: false,
|
|
Issued: "api",
|
|
CreatedAt: time.Now(),
|
|
},
|
|
}
|
|
for _, user := range users {
|
|
require.NoError(t, testStore.SaveUser(ctx, user))
|
|
}
|
|
}
|
|
|
|
func generateSessionKeyPair(t *testing.T) (string, string) {
|
|
t.Helper()
|
|
pub, priv, err := ed25519.GenerateKey(rand.Reader)
|
|
require.NoError(t, err)
|
|
return base64.StdEncoding.EncodeToString(pub), base64.StdEncoding.EncodeToString(priv)
|
|
}
|
|
|
|
func createSessionToken(t *testing.T, privKeyB64, userID, domain string) string {
|
|
t.Helper()
|
|
token, err := sessionkey.SignToken(privKeyB64, userID, "", domain, auth.MethodOIDC, nil, nil, time.Hour)
|
|
require.NoError(t, err)
|
|
return token
|
|
}
|
|
|
|
func TestValidateSession_UserAllowed(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId")
|
|
require.NoError(t, err)
|
|
|
|
token := createSessionToken(t, proxy.SessionPrivateKey, "allowedUserId", "test-proxy.example.com")
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
Domain: "test-proxy.example.com",
|
|
SessionToken: token,
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.True(t, resp.Valid, "User should be allowed access")
|
|
assert.Equal(t, "allowedUserId", resp.UserId)
|
|
assert.Empty(t, resp.DeniedReason)
|
|
assert.Equal(t, []string{"allowedGroupId"}, resp.GetPeerGroupIds(), "PeerGroupIds must mirror the resolved user's group memberships")
|
|
}
|
|
|
|
func TestValidateSession_UserNotInAllowedGroup(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "restrictedProxyId")
|
|
require.NoError(t, err)
|
|
|
|
token := createSessionToken(t, proxy.SessionPrivateKey, "nonGroupUserId", "restricted-proxy.example.com")
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
Domain: "restricted-proxy.example.com",
|
|
SessionToken: token,
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.Valid, "User not in group should be denied")
|
|
assert.Equal(t, "not_in_group", resp.DeniedReason)
|
|
assert.Equal(t, "nonGroupUserId", resp.UserId)
|
|
assert.Empty(t, resp.GetPeerGroupIds(), "PeerGroupIds must mirror the resolved user's actual (empty) memberships on denial")
|
|
}
|
|
|
|
// TestValidateSession_PendingApprovalUserDenied covers a user who is a member of
|
|
// the service's distribution group but is still waiting for an administrator to
|
|
// approve the account. Group membership alone must not open the service.
|
|
func TestValidateSession_PendingApprovalUserDenied(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "restrictedProxyId")
|
|
require.NoError(t, err)
|
|
|
|
token := createSessionToken(t, proxy.SessionPrivateKey, pendingUserID, "restricted-proxy.example.com")
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
Domain: "restricted-proxy.example.com",
|
|
SessionToken: token,
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.Valid, "User pending approval should be denied")
|
|
assert.Equal(t, deniedReasonPendingApproval, resp.DeniedReason, "Denied reason should name the pending approval state")
|
|
assert.Equal(t, pendingUserID, resp.UserId, "Denial should identify the user it applies to")
|
|
assert.Equal(t, []string{"allowedGroupId"}, resp.GetPeerGroupIds(), "PeerGroupIds must mirror the resolved user's group memberships on denial")
|
|
assert.Equal(t, []string{"Allowed Group"}, resp.GetPeerGroupNames(), "PeerGroupNames must pair with PeerGroupIds on denial")
|
|
}
|
|
|
|
// TestValidateSession_PendingApprovalUserInAllUsersGroupDenied covers the same
|
|
// user against a service distributed to the account's "All" group, where every
|
|
// user of the account is a member by default.
|
|
func TestValidateSession_PendingApprovalUserInAllUsersGroupDenied(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "allUsersProxyId")
|
|
require.NoError(t, err)
|
|
|
|
token := createSessionToken(t, proxy.SessionPrivateKey, pendingAllUsersID, "all-users-proxy.example.com")
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
Domain: "all-users-proxy.example.com",
|
|
SessionToken: token,
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.Valid, "User pending approval should be denied even in the All Users group")
|
|
assert.Equal(t, deniedReasonPendingApproval, resp.DeniedReason, "Denied reason should name the pending approval state")
|
|
assert.Equal(t, pendingAllUsersID, resp.UserId, "Denial should identify the user it applies to")
|
|
assert.Equal(t, []string{allUsersGroupID}, resp.GetPeerGroupIds(), "PeerGroupIds must mirror the resolved user's group memberships on denial")
|
|
}
|
|
|
|
// TestValidateSession_BlockedUserDenied covers a user blocked after having been
|
|
// approved, so PendingApproval is false and only the blocked flag is set.
|
|
func TestValidateSession_BlockedUserDenied(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "restrictedProxyId")
|
|
require.NoError(t, err)
|
|
|
|
token := createSessionToken(t, proxy.SessionPrivateKey, blockedUserID, "restricted-proxy.example.com")
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
Domain: "restricted-proxy.example.com",
|
|
SessionToken: token,
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.Valid, "Blocked user should be denied")
|
|
assert.Equal(t, deniedReasonUserBlocked, resp.DeniedReason, "Denied reason should name the blocked state")
|
|
assert.Equal(t, blockedUserID, resp.UserId, "Denial should identify the user it applies to")
|
|
}
|
|
|
|
// TestValidateSession_UserAllowedAfterApproval walks the same session token
|
|
// through the approval transition: denied while pending, allowed once an
|
|
// administrator clears both flags.
|
|
func TestValidateSession_UserAllowedAfterApproval(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
ctx := context.Background()
|
|
|
|
proxy, err := setup.store.GetServiceByID(ctx, store.LockingStrengthNone, "testAccountId", "restrictedProxyId")
|
|
require.NoError(t, err)
|
|
|
|
token := createSessionToken(t, proxy.SessionPrivateKey, pendingUserID, "restricted-proxy.example.com")
|
|
req := &proto.ValidateSessionRequest{
|
|
Domain: "restricted-proxy.example.com",
|
|
SessionToken: token,
|
|
}
|
|
|
|
resp, err := setup.proxyService.ValidateSession(ctx, req)
|
|
require.NoError(t, err)
|
|
require.False(t, resp.Valid, "User pending approval should be denied before approval")
|
|
assert.Equal(t, deniedReasonPendingApproval, resp.DeniedReason, "Denied reason should name the pending approval state")
|
|
|
|
user, err := setup.store.GetUserByUserID(ctx, store.LockingStrengthNone, pendingUserID)
|
|
require.NoError(t, err)
|
|
user.PendingApproval = false
|
|
user.Blocked = false
|
|
require.NoError(t, setup.store.SaveUser(ctx, user))
|
|
|
|
resp, err = setup.proxyService.ValidateSession(ctx, req)
|
|
require.NoError(t, err)
|
|
assert.True(t, resp.Valid, "Approved user should be allowed access")
|
|
assert.Empty(t, resp.DeniedReason)
|
|
assert.Equal(t, pendingUserID, resp.UserId, "Approved user should be identified in the response")
|
|
assert.Equal(t, []string{"allowedGroupId"}, resp.GetPeerGroupIds(), "PeerGroupIds must mirror the approved user's group memberships")
|
|
}
|
|
|
|
func TestValidateSession_UserInDifferentAccount(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId")
|
|
require.NoError(t, err)
|
|
|
|
token := createSessionToken(t, proxy.SessionPrivateKey, "otherAccountUserId", "test-proxy.example.com")
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
Domain: "test-proxy.example.com",
|
|
SessionToken: token,
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.Valid, "User in different account should be denied")
|
|
assert.Equal(t, "account_mismatch", resp.DeniedReason)
|
|
}
|
|
|
|
func TestValidateSession_UserNotFound(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId")
|
|
require.NoError(t, err)
|
|
|
|
token := createSessionToken(t, proxy.SessionPrivateKey, "nonExistentUserId", "test-proxy.example.com")
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
Domain: "test-proxy.example.com",
|
|
SessionToken: token,
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.Valid, "Non-existent user should be denied")
|
|
assert.Equal(t, "user_not_found", resp.DeniedReason)
|
|
}
|
|
|
|
func TestValidateSession_ProxyNotFound(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
proxy, err := setup.store.GetServiceByID(context.Background(), store.LockingStrengthNone, "testAccountId", "testProxyId")
|
|
require.NoError(t, err)
|
|
|
|
token := createSessionToken(t, proxy.SessionPrivateKey, "allowedUserId", "unknown-proxy.example.com")
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
Domain: "unknown-proxy.example.com",
|
|
SessionToken: token,
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.Valid, "Unknown proxy should be denied")
|
|
assert.Equal(t, "service_not_found", resp.DeniedReason)
|
|
}
|
|
|
|
func TestValidateSession_InvalidToken(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
Domain: "test-proxy.example.com",
|
|
SessionToken: "invalid-token",
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.Valid, "Invalid token should be denied")
|
|
assert.Equal(t, "invalid_token", resp.DeniedReason)
|
|
}
|
|
|
|
func TestValidateSession_MissingDomain(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
SessionToken: "some-token",
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.Valid)
|
|
assert.Contains(t, resp.DeniedReason, "missing")
|
|
}
|
|
|
|
func TestValidateSession_MissingToken(t *testing.T) {
|
|
setup := setupValidateSessionTest(t)
|
|
defer setup.cleanup()
|
|
|
|
resp, err := setup.proxyService.ValidateSession(context.Background(), &proto.ValidateSessionRequest{
|
|
Domain: "test-proxy.example.com",
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
assert.False(t, resp.Valid)
|
|
assert.Contains(t, resp.DeniedReason, "missing")
|
|
}
|
|
|
|
type testValidateSessionServiceManager struct {
|
|
store store.Store
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) GetAllServices(_ context.Context, _, _ string) ([]*service.Service, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) GetService(_ context.Context, _, _, _ string) (*service.Service, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) CreateService(_ context.Context, _, _ string, _ *service.Service) (*service.Service, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) UpdateService(_ context.Context, _, _ string, _ *service.Service) (*service.Service, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) DeleteService(_ context.Context, _, _, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) DeleteAllServices(_ context.Context, _, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) SetCertificateIssuedAt(_ context.Context, _, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) SetStatus(_ context.Context, _, _ string, _ service.Status) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) ReloadAllServicesForAccount(_ context.Context, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) ReloadService(_ context.Context, _, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) GetGlobalServices(ctx context.Context) ([]*service.Service, error) {
|
|
return m.store.GetServices(ctx, store.LockingStrengthNone)
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) GetServiceByID(ctx context.Context, accountID, proxyID string) (*service.Service, error) {
|
|
return m.store.GetServiceByID(ctx, store.LockingStrengthNone, accountID, proxyID)
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) GetAccountServices(ctx context.Context, accountID string) ([]*service.Service, error) {
|
|
return m.store.GetAccountServices(ctx, store.LockingStrengthNone, accountID)
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) GetServiceIDByTargetID(_ context.Context, _, _ string) (string, error) {
|
|
return "", nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) CreateServiceFromPeer(_ context.Context, _, _ string, _ *service.ExposeServiceRequest) (*service.ExposeServiceResponse, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) RenewServiceFromPeer(_ context.Context, _, _, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) StopServiceFromPeer(_ context.Context, _, _, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) StartExposeReaper(_ context.Context) {}
|
|
|
|
func (m *testValidateSessionServiceManager) GetServiceByDomain(ctx context.Context, domain string) (*service.Service, error) {
|
|
return m.store.GetServiceByDomain(ctx, domain)
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) GetClusters(_ context.Context, _, _ string) ([]proxy.Cluster, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionServiceManager) DeleteAccountCluster(_ context.Context, _, _, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
type testValidateSessionProxyManager struct{}
|
|
|
|
func (m *testValidateSessionProxyManager) Connect(_ context.Context, _, _, _, _ string, _ *string, _ *proxy.Capabilities) (*proxy.Proxy, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) Disconnect(_ context.Context, _, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) Heartbeat(_ context.Context, _ *proxy.Proxy) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) DeleteAccountCluster(_ context.Context, _, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) GetActiveClusterAddresses(_ context.Context) ([]string, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) GetActiveClusterAddressesForAccount(_ context.Context, _ string) ([]string, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) GetActiveClusters(_ context.Context) ([]proxy.Cluster, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) CleanupStale(_ context.Context, _ time.Duration) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) GetAccountProxy(_ context.Context, _ string) (*proxy.Proxy, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) CountAccountProxies(_ context.Context, _ string) (int64, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) IsClusterAddressAvailable(_ context.Context, _, _ string) (bool, error) {
|
|
return true, nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) DeleteProxy(_ context.Context, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) ClusterSupportsCustomPorts(_ context.Context, _ string) *bool {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) ClusterRequireSubdomain(_ context.Context, _ string) *bool {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) ClusterSupportsCrowdSec(_ context.Context, _ string) *bool {
|
|
return nil
|
|
}
|
|
|
|
func (m *testValidateSessionProxyManager) ClusterSupportsPrivate(_ context.Context, _ string) *bool {
|
|
return nil
|
|
}
|
|
|
|
type testValidateSessionUsersManager struct {
|
|
store store.Store
|
|
}
|
|
|
|
func (m *testValidateSessionUsersManager) GetUser(ctx context.Context, userID string) (*types.User, error) {
|
|
return m.store.GetUserByUserID(ctx, store.LockingStrengthNone, userID)
|
|
}
|
|
|
|
func (m *testValidateSessionUsersManager) GetUserWithGroups(ctx context.Context, userID string) (*types.User, []*types.Group, error) {
|
|
user, err := m.store.GetUserByUserID(ctx, store.LockingStrengthNone, userID)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
if len(user.AutoGroups) == 0 {
|
|
return user, nil, nil
|
|
}
|
|
groupsMap, err := m.store.GetGroupsByIDs(ctx, store.LockingStrengthNone, user.AccountID, user.AutoGroups)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
groups := make([]*types.Group, 0, len(user.AutoGroups))
|
|
for _, id := range user.AutoGroups {
|
|
if g, ok := groupsMap[id]; ok && g != nil {
|
|
groups = append(groups, g)
|
|
}
|
|
}
|
|
return user, groups, nil
|
|
}
|