Files
netbird/management/server/idp/idp.go
Yury Gargay bb40325977 Update GitHub Actions and Enhance golangci-lint (#1075)
This PR showcases the implementation of additional linter rules. I've updated the golangci-lint GitHub Actions to the latest available version. This update makes sure that the tool works the same way locally - assuming being updated regularly - and with the GitHub Actions.

I've also taken care of keeping all the GitHub Actions up to date, which helps our code stay current. But there's one part, goreleaser that's a bit tricky to test on our computers. So, it's important to take a close look at that.

To make it easier to understand what I've done, I've made separate changes for each thing that the new linters found. This should help the people reviewing the changes see what's going on more clearly. Some of the changes might not be obvious at first glance.

Things to consider for the future
CI runs on Ubuntu so the static analysis only happens for Linux. Consider running it for the rest: Darwin, Windows
2023-09-04 17:03:44 +02:00

178 lines
6.0 KiB
Go

package idp
import (
"fmt"
"net/http"
"strings"
"time"
"github.com/netbirdio/netbird/management/server/telemetry"
)
// Manager idp manager interface
type Manager interface {
UpdateUserAppMetadata(userId string, appMetadata AppMetadata) error
GetUserDataByID(userId string, appMetadata AppMetadata) (*UserData, error)
GetAccount(accountId string) ([]*UserData, error)
GetAllAccounts() (map[string][]*UserData, error)
CreateUser(email, name, accountID, invitedByEmail string) (*UserData, error)
GetUserByEmail(email string) ([]*UserData, error)
InviteUserByID(userID string) error
}
// ClientConfig defines common client configuration for all IdP manager
type ClientConfig struct {
Issuer string
TokenEndpoint string
ClientID string
ClientSecret string
GrantType string
}
// ExtraConfig stores IdP specific config that are unique to individual IdPs
type ExtraConfig map[string]string
// Config an idp configuration struct to be loaded from management server's config file
type Config struct {
ManagerType string
ClientConfig *ClientConfig
ExtraConfig ExtraConfig
Auth0ClientCredentials Auth0ClientConfig
AzureClientCredentials AzureClientConfig
KeycloakClientCredentials KeycloakClientConfig
ZitadelClientCredentials ZitadelClientConfig
}
// ManagerCredentials interface that authenticates using the credential of each type of idp
type ManagerCredentials interface {
Authenticate() (JWTToken, error)
}
// ManagerHTTPClient http client interface for API calls
type ManagerHTTPClient interface {
Do(req *http.Request) (*http.Response, error)
}
// ManagerHelper helper
type ManagerHelper interface {
Marshal(v interface{}) ([]byte, error)
Unmarshal(data []byte, v interface{}) error
}
type UserData struct {
Email string `json:"email"`
Name string `json:"name"`
ID string `json:"user_id"`
AppMetadata AppMetadata `json:"app_metadata"`
}
// AppMetadata user app metadata to associate with a profile
type AppMetadata struct {
// WTAccountID is a NetBird (previously Wiretrustee) account id to update in the IDP
// maps to wt_account_id when json.marshal
WTAccountID string `json:"wt_account_id,omitempty"`
WTPendingInvite *bool `json:"wt_pending_invite"`
WTInvitedBy string `json:"wt_invited_by_email"`
}
// JWTToken a JWT object that holds information of a token
type JWTToken struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
expiresInTime time.Time
Scope string `json:"scope"`
TokenType string `json:"token_type"`
}
// NewManager returns a new idp manager based on the configuration that it receives
func NewManager(config Config, appMetrics telemetry.AppMetrics) (Manager, error) {
if config.ClientConfig != nil {
config.ClientConfig.Issuer = strings.TrimSuffix(config.ClientConfig.Issuer, "/")
}
switch strings.ToLower(config.ManagerType) {
case "none", "":
return nil, nil //nolint:nilnil
case "auth0":
auth0ClientConfig := config.Auth0ClientCredentials
if config.ClientConfig != nil {
auth0ClientConfig = Auth0ClientConfig{
Audience: config.ExtraConfig["Audience"],
AuthIssuer: config.ClientConfig.Issuer,
ClientID: config.ClientConfig.ClientID,
ClientSecret: config.ClientConfig.ClientSecret,
GrantType: config.ClientConfig.GrantType,
}
}
return NewAuth0Manager(auth0ClientConfig, appMetrics)
case "azure":
azureClientConfig := config.AzureClientCredentials
if config.ClientConfig != nil {
azureClientConfig = AzureClientConfig{
ClientID: config.ClientConfig.ClientID,
ClientSecret: config.ClientConfig.ClientSecret,
GrantType: config.ClientConfig.GrantType,
TokenEndpoint: config.ClientConfig.TokenEndpoint,
ObjectID: config.ExtraConfig["ObjectId"],
GraphAPIEndpoint: config.ExtraConfig["GraphApiEndpoint"],
}
}
return NewAzureManager(azureClientConfig, appMetrics)
case "keycloak":
keycloakClientConfig := config.KeycloakClientCredentials
if config.ClientConfig != nil {
keycloakClientConfig = KeycloakClientConfig{
ClientID: config.ClientConfig.ClientID,
ClientSecret: config.ClientConfig.ClientSecret,
GrantType: config.ClientConfig.GrantType,
TokenEndpoint: config.ClientConfig.TokenEndpoint,
AdminEndpoint: config.ExtraConfig["AdminEndpoint"],
}
}
return NewKeycloakManager(keycloakClientConfig, appMetrics)
case "zitadel":
zitadelClientConfig := config.ZitadelClientCredentials
if config.ClientConfig != nil {
zitadelClientConfig = ZitadelClientConfig{
ClientID: config.ClientConfig.ClientID,
ClientSecret: config.ClientConfig.ClientSecret,
GrantType: config.ClientConfig.GrantType,
TokenEndpoint: config.ClientConfig.TokenEndpoint,
ManagementEndpoint: config.ExtraConfig["ManagementEndpoint"],
}
}
return NewZitadelManager(zitadelClientConfig, appMetrics)
case "authentik":
authentikConfig := AuthentikClientConfig{
Issuer: config.ClientConfig.Issuer,
ClientID: config.ClientConfig.ClientID,
TokenEndpoint: config.ClientConfig.TokenEndpoint,
GrantType: config.ClientConfig.GrantType,
Username: config.ExtraConfig["Username"],
Password: config.ExtraConfig["Password"],
}
return NewAuthentikManager(authentikConfig, appMetrics)
case "okta":
oktaClientConfig := OktaClientConfig{
Issuer: config.ClientConfig.Issuer,
TokenEndpoint: config.ClientConfig.TokenEndpoint,
GrantType: config.ClientConfig.GrantType,
APIToken: config.ExtraConfig["ApiToken"],
}
return NewOktaManager(oktaClientConfig, appMetrics)
case "google":
googleClientConfig := GoogleWorkspaceClientConfig{
ServiceAccountKey: config.ExtraConfig["ServiceAccountKey"],
CustomerID: config.ExtraConfig["CustomerId"],
}
return NewGoogleWorkspaceManager(googleClientConfig, appMetrics)
default:
return nil, fmt.Errorf("invalid manager type: %s", config.ManagerType)
}
}