Implement Auth0 IdP get all connections method (#1613)

This commit is contained in:
Yury Gargay 2024-02-28 16:57:35 +01:00 committed by GitHub
parent f64e73ca70
commit 5a8f1763a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 87 additions and 6 deletions

View File

@ -126,6 +126,7 @@ type AccountManager interface {
SavePostureChecks(accountID, userID string, postureChecks *posture.Checks) error SavePostureChecks(accountID, userID string, postureChecks *posture.Checks) error
DeletePostureChecks(accountID, postureChecksID, userID string) error DeletePostureChecks(accountID, postureChecksID, userID string) error
ListPostureChecks(accountID, userID string) ([]*posture.Checks, error) ListPostureChecks(accountID, userID string) ([]*posture.Checks, error)
GetIdpManager() idp.Manager
} }
type DefaultAccountManager struct { type DefaultAccountManager struct {
@ -900,6 +901,10 @@ func (am *DefaultAccountManager) GetExternalCacheManager() ExternalCacheManager
return am.externalCacheManager return am.externalCacheManager
} }
func (am *DefaultAccountManager) GetIdpManager() idp.Manager {
return am.idpManager
}
// UpdateAccountSettings updates Account settings. // UpdateAccountSettings updates Account settings.
// Only users with role UserRoleAdmin can update the account. // Only users with role UserRoleAdmin can update the account.
// User that performs the update has to belong to the account. // User that performs the update has to belong to the account.

View File

@ -114,6 +114,22 @@ type auth0Profile struct {
LastLogin string `json:"last_login"` LastLogin string `json:"last_login"`
} }
// Connections represents a single Auth0 connection
// https://auth0.com/docs/api/management/v2/connections/get-connections
type Connection struct {
Id string `json:"id"`
Name string `json:"name"`
DisplayName string `json:"display_name"`
IsDomainConnection bool `json:"is_domain_connection"`
Realms []string `json:"realms"`
Metadata map[string]string `json:"metadata"`
Options ConnectionOptions `json:"options"`
}
type ConnectionOptions struct {
DomainAliases []string `json:"domain_aliases"`
}
// NewAuth0Manager creates a new instance of the Auth0Manager // NewAuth0Manager creates a new instance of the Auth0Manager
func NewAuth0Manager(config Auth0ClientConfig, appMetrics telemetry.AppMetrics) (*Auth0Manager, error) { func NewAuth0Manager(config Auth0ClientConfig, appMetrics telemetry.AppMetrics) (*Auth0Manager, error) {
httpTransport := http.DefaultTransport.(*http.Transport).Clone() httpTransport := http.DefaultTransport.(*http.Transport).Clone()
@ -581,13 +597,13 @@ func (am *Auth0Manager) GetAllAccounts() (map[string][]*UserData, error) {
body, err := io.ReadAll(jobResp.Body) body, err := io.ReadAll(jobResp.Body)
if err != nil { if err != nil {
log.Debugf("Coudln't read export job response; %v", err) log.Debugf("Couldn't read export job response; %v", err)
return nil, err return nil, err
} }
err = am.helper.Unmarshal(body, &exportJobResp) err = am.helper.Unmarshal(body, &exportJobResp)
if err != nil { if err != nil {
log.Debugf("Coudln't unmarshal export job response; %v", err) log.Debugf("Couldn't unmarshal export job response; %v", err)
return nil, err return nil, err
} }
@ -635,7 +651,7 @@ func (am *Auth0Manager) GetUserByEmail(email string) ([]*UserData, error) {
err = am.helper.Unmarshal(body, &userResp) err = am.helper.Unmarshal(body, &userResp)
if err != nil { if err != nil {
log.Debugf("Coudln't unmarshal export job response; %v", err) log.Debugf("Couldn't unmarshal export job response; %v", err)
return nil, err return nil, err
} }
@ -684,13 +700,13 @@ func (am *Auth0Manager) CreateUser(email, name, accountID, invitedByEmail string
body, err := io.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
log.Debugf("Coudln't read export job response; %v", err) log.Debugf("Couldn't read export job response; %v", err)
return nil, err return nil, err
} }
err = am.helper.Unmarshal(body, &createResp) err = am.helper.Unmarshal(body, &createResp)
if err != nil { if err != nil {
log.Debugf("Coudln't unmarshal export job response; %v", err) log.Debugf("Couldn't unmarshal export job response; %v", err)
return nil, err return nil, err
} }
@ -777,6 +793,56 @@ func (am *Auth0Manager) DeleteUser(userID string) error {
return nil return nil
} }
// GetAllConnections returns detailed list of all connections filtered by given params.
// Note this method is not part of the IDP Manager interface as this is Auth0 specific.
func (am *Auth0Manager) GetAllConnections(strategy []string) ([]Connection, error) {
var connections []Connection
q := make(url.Values)
q.Set("strategy", strings.Join(strategy, ","))
req, err := am.createRequest(http.MethodGet, "/api/v2/connections?"+q.Encode(), nil)
if err != nil {
return connections, err
}
resp, err := am.httpClient.Do(req)
if err != nil {
log.Debugf("execute get connections request: %v", err)
if am.appMetrics != nil {
am.appMetrics.IDPMetrics().CountRequestError()
}
return connections, err
}
defer func() {
err = resp.Body.Close()
if err != nil {
log.Errorf("close get connections request body: %v", err)
}
}()
if resp.StatusCode != 200 {
if am.appMetrics != nil {
am.appMetrics.IDPMetrics().CountRequestStatusError()
}
return connections, fmt.Errorf("unable to get connections, statusCode %d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Debugf("Couldn't read get connections response; %v", err)
return connections, err
}
err = am.helper.Unmarshal(body, &connections)
if err != nil {
log.Debugf("Couldn't unmarshal get connection response; %v", err)
return connections, err
}
return connections, err
}
// checkExportJobStatus checks the status of the job created at CreateExportUsersJob. // checkExportJobStatus checks the status of the job created at CreateExportUsersJob.
// If the status is "completed", then return the downloadLink // If the status is "completed", then return the downloadLink
func (am *Auth0Manager) checkExportJobStatus(jobID string) (bool, string, error) { func (am *Auth0Manager) checkExportJobStatus(jobID string) (bool, string, error) {

View File

@ -11,6 +11,7 @@ import (
nbdns "github.com/netbirdio/netbird/dns" nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server" "github.com/netbirdio/netbird/management/server"
"github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/idp"
"github.com/netbirdio/netbird/management/server/jwtclaims" "github.com/netbirdio/netbird/management/server/jwtclaims"
nbpeer "github.com/netbirdio/netbird/management/server/peer" nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/netbird/management/server/posture" "github.com/netbirdio/netbird/management/server/posture"
@ -93,6 +94,7 @@ type MockAccountManager struct {
DeletePostureChecksFunc func(accountID, postureChecksID, userID string) error DeletePostureChecksFunc func(accountID, postureChecksID, userID string) error
ListPostureChecksFunc func(accountID, userID string) ([]*posture.Checks, error) ListPostureChecksFunc func(accountID, userID string) ([]*posture.Checks, error)
GetUsageFunc func(ctx context.Context, accountID string, start, end time.Time) (*server.AccountUsageStats, error) GetUsageFunc func(ctx context.Context, accountID string, start, end time.Time) (*server.AccountUsageStats, error)
GetIdpManagerFunc func() idp.Manager
} }
// GetUsersFromAccount mock implementation of GetUsersFromAccount from server.AccountManager interface // GetUsersFromAccount mock implementation of GetUsersFromAccount from server.AccountManager interface
@ -705,10 +707,18 @@ func (am *MockAccountManager) ListPostureChecks(accountID, userID string) ([]*po
return nil, status.Errorf(codes.Unimplemented, "method ListPostureChecks is not implemented") return nil, status.Errorf(codes.Unimplemented, "method ListPostureChecks is not implemented")
} }
// GetUsage mocks GetCurrentUsage of the AccountManager interface // GetUsage mocks GetUsage of the AccountManager interface
func (am *MockAccountManager) GetUsage(ctx context.Context, accountID string, start time.Time, end time.Time) (*server.AccountUsageStats, error) { func (am *MockAccountManager) GetUsage(ctx context.Context, accountID string, start time.Time, end time.Time) (*server.AccountUsageStats, error) {
if am.GetUsageFunc != nil { if am.GetUsageFunc != nil {
return am.GetUsageFunc(ctx, accountID, start, end) return am.GetUsageFunc(ctx, accountID, start, end)
} }
return nil, status.Errorf(codes.Unimplemented, "method GetUsage is not implemented") return nil, status.Errorf(codes.Unimplemented, "method GetUsage is not implemented")
} }
// GetIdpManager mocks GetIdpManager of the AccountManager interface
func (am *MockAccountManager) GetIdpManager() idp.Manager {
if am.GetIdpManagerFunc != nil {
return am.GetIdpManagerFunc()
}
return nil
}