From 933fc23905b4916c61b051340beb7f7070579bac Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Wed, 10 Nov 2021 13:59:21 -0500 Subject: [PATCH] Massive cleanup. Tests are passing. --- go.mod | 1 + plugin/auth.go | 305 +++++++++++++++++++----------------------- plugin/client.go | 11 +- plugin/option.go | 33 ++--- plugin/plugin.go | 60 +++++---- plugin/plugin_test.go | 46 +++---- 6 files changed, 208 insertions(+), 248 deletions(-) diff --git a/go.mod b/go.mod index 5a5471e..028df9a 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 github.com/kr/pretty v0.3.0 github.com/manicminer/hamilton v0.32.0 + github.com/mitchellh/mapstructure v1.4.1 github.com/stretchr/testify v1.7.0 google.golang.org/protobuf v1.27.1 ) diff --git a/plugin/auth.go b/plugin/auth.go index 719009d..0937c2c 100644 --- a/plugin/auth.go +++ b/plugin/auth.go @@ -9,196 +9,167 @@ import ( "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure/auth" "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostcatalogs" - pb "github.com/hashicorp/boundary/sdk/pbs/plugin" hauth "github.com/manicminer/hamilton/auth" "github.com/manicminer/hamilton/environments" "github.com/manicminer/hamilton/msgraph" "github.com/manicminer/hamilton/odata" - "google.golang.org/protobuf/types/known/structpb" + "github.com/mitchellh/mapstructure" ) -type WrappedHamiltonConfig struct { - hauth.Config - SecretId string +type AuthorizationInfo struct { + HamiltonConfig hauth.Config + AuthParams AuthParams } -func authParams(hc *hostcatalogs.HostCatalog, secrets *structpb.Struct) (map[string]string, error) { +type Attributes struct { + SubscriptionId string `mapstructure:"subscription_id"` + ClientId string `mapstructure:"client_id"` + TenantId string `mapstructure:"tenant_id"` + DisableCredentialRotation bool `mapstructure:"disable_credential_rotation"` +} + +type SecretData struct { + SecretValue string `mapstructure:"secret_value"` + SecretId string `mapstructure:"secret_id"` + CredsLastRotatedTime string `mapstructure:"creds_last_rotated_time"` +} + +type AuthParams struct { + SubscriptionId string + ClientId string + ClientObjectId string + TenantId string + SecretValue string + SecretId string + CredsLastRotatedTime time.Time +} + +func getAuthorizationInfo(hc *hostcatalogs.HostCatalog) (*AuthorizationInfo, error) { if hc == nil { return nil, errors.New("host catalog is nil") } if hc.GetAttributes() == nil { return nil, errors.New("host catalog attributes is nil") } - hcFields := hc.GetAttributes().GetFields() - if hcFields == nil { - return nil, errors.New("host catalog attributes fields is nil") + if hc.GetSecrets() == nil { + return nil, errors.New("host catalog secret data is nil") } - if secrets == nil { - return nil, errors.New("secrets is nil") + hcFields := hc.GetAttributes().AsMap() + var attrs Attributes + if err := mapstructure.Decode(hcFields, &attrs); err != nil { + return nil, fmt.Errorf("error decoding host catalog attribute fields: %w", err) } - pdFields := secrets.GetFields() - if pdFields == nil { - return nil, errors.New("secrets data fields is nil") + if attrs.SubscriptionId == "" { + return nil, errors.New("subscription id is empty") + } + if attrs.TenantId == "" { + return nil, errors.New("tenant id is empty") } - var subscriptionId string - if hcFields[constSubscriptionId] == nil { - return nil, errors.New("subscription id not provided in incoming data") + pdFields := hc.GetSecrets().AsMap() + var secrets SecretData + if err := mapstructure.Decode(pdFields, &secrets); err != nil { + return nil, fmt.Errorf("error decoding host catalog persisted data fields: %w", err) } - if subscriptionId = hcFields[constSubscriptionId].GetStringValue(); subscriptionId == "" { - return nil, errors.New("subscription id could not be read as a string value") + if secrets.SecretValue == "" { + return nil, errors.New("secret value is empty") } - - ret := map[string]string{ - constSubscriptionId: subscriptionId, - } - - clientId := hcFields[constClientId] - secretValue := pdFields[constSecretValue] - secretId := pdFields[constSecretId] - tenantId := hcFields[constTenantId] - - switch { - case clientId != nil && clientId.GetStringValue() != "" && - secretValue != nil && secretValue.GetStringValue() != "" && - tenantId != nil && tenantId.GetStringValue() != "": - ret[constClientId] = clientId.GetStringValue() - ret[constSecretValue] = secretValue.GetStringValue() - ret[constTenantId] = tenantId.GetStringValue() - if secretId != nil { - ret[constSecretId] = secretId.GetStringValue() - } - } - - return ret, nil -} - -func fetchAuthorizer(hc *hostcatalogs.HostCatalog, secrets *structpb.Struct) (string, autorest.Authorizer, error) { - aParams, err := authParams(hc, secrets) - if err != nil { - return "", nil, fmt.Errorf("error finding authentication params: %w", err) - } - - var authorizer autorest.Authorizer - // Switch between currently-understood authorization types - { - switch { - case aParams[constClientId] != "" && - aParams[constSecretValue] != "" && - aParams[constTenantId] != "": - credsConfig := auth.NewClientCredentialsConfig( - aParams[constClientId], - aParams[constSecretValue], - aParams[constTenantId], - ) - authorizer, err = credsConfig.Authorizer() - if err != nil { - return "", nil, fmt.Errorf("error authorizing to Azure: %w", err) - } - - default: - return "", nil, errors.New("no or incomplete authentication information available") - } - - if authorizer == nil { - return "", nil, fmt.Errorf("authorizer after authorizing to Azure is nil") - } - } - - return aParams[constSubscriptionId], authorizer, nil -} - -func getWrappedHamiltonConfig(hc *hostcatalogs.HostCatalog, persisted *pb.HostCatalogPersisted) (*WrappedHamiltonConfig, error) { - secrets := hc.GetSecrets() - if secrets == nil && persisted != nil { - secrets = persisted.GetSecrets() - } - aParams, err := authParams(hc, secrets) - if err != nil { - return nil, fmt.Errorf("error fetching authentication params when fetching: %w", err) - } - authConfig := &WrappedHamiltonConfig{} - authConfig.Environment = environments.Global - - switch { - case aParams[constClientId] != "" && - aParams[constSecretValue] != "" && - aParams[constTenantId] != "": - authConfig.TenantID = aParams[constTenantId] - authConfig.ClientID = aParams[constClientId] - authConfig.ClientSecret = aParams[constSecretValue] - if aParams[constSecretId] != "" { - authConfig.SecretId = aParams[constSecretId] - } - authConfig.EnableClientSecretAuth = true - - default: - return nil, errors.New("no or incomplete authentication information available") - } - - return authConfig, nil -} - -func getObjectId(ctx context.Context, hConfig *WrappedHamiltonConfig, opt ...Option) (string, error) { - opts, err := getOpts(opt...) - if err != nil { - return "", fmt.Errorf("error parsing ops: %w", err) - } - - objId := opts.withObjectId - if objId == "" { - clientId := opts.withClientId - if clientId == "" && hConfig != nil { - clientId = hConfig.ClientID - } - if clientId == "" { - return "", fmt.Errorf("neither client id nor object id passed in, cannot continue") - } - // First, find the appId - aClient, err := getApplicationsClient(ctx, hConfig) + var lastRotatedTime time.Time + var err error + if secrets.CredsLastRotatedTime != "" { + lastRotatedTime, err = time.Parse(time.RFC3339Nano, secrets.CredsLastRotatedTime) if err != nil { - return "", fmt.Errorf("error getting application client: %w", err) + return nil, fmt.Errorf("error parsing last rotated time: %w", err) } - if aClient == nil { - return "", errors.New("applications client is nil when getting object id") - } - apps, _, err := aClient.List(ctx, odata.Query{ - Filter: fmt.Sprintf("appId eq '%s'", clientId), - }) - if err != nil { - return "", fmt.Errorf("error listing applications to find objId: %w", err) - } - if apps == nil { - return "", errors.New("nil apps returned when listing to find objId") - } - if len(*apps) != 1 { - return "", fmt.Errorf("unexpected number of apps found, expected 1, found %d", len(*apps)) - } - objId = *(*apps)[0].DirectoryObject.ID } - return objId, nil + + return &AuthorizationInfo{ + HamiltonConfig: hauth.Config{ + Environment: environments.Global, + TenantID: attrs.TenantId, + ClientID: attrs.ClientId, + ClientSecret: secrets.SecretValue, + EnableClientSecretAuth: true, + }, + AuthParams: AuthParams{ + SubscriptionId: attrs.SubscriptionId, + ClientId: attrs.ClientId, + TenantId: attrs.TenantId, + SecretId: secrets.SecretId, + SecretValue: secrets.SecretValue, + CredsLastRotatedTime: lastRotatedTime, + }, + }, nil +} + +func (a *AuthorizationInfo) autorestAuthorizer() (autorest.Authorizer, error) { + credsConfig := auth.NewClientCredentialsConfig( + a.AuthParams.ClientId, + a.AuthParams.SecretValue, + a.AuthParams.TenantId, + ) + authorizer, err := credsConfig.Authorizer() + if err != nil { + return nil, fmt.Errorf("error authorizing to Azure: %w", err) + } + if authorizer == nil { + return nil, errors.New("generated authorizer is nil") + } + return authorizer, nil +} + +func (a *AuthorizationInfo) populateObjectId(ctx context.Context, opt ...Option) error { + if a.AuthParams.ClientObjectId != "" { + return nil + } + + if a.AuthParams.ClientId == "" { + return errors.New("client id not known at object id lookup time") + } + // First, find the appId + aClient, err := getApplicationsClient(ctx, a) + if err != nil { + return fmt.Errorf("error getting application client: %w", err) + } + if aClient == nil { + return errors.New("applications client is nil when getting object id") + } + apps, _, err := aClient.List(ctx, odata.Query{ + Filter: fmt.Sprintf("appId eq '%s'", a.AuthParams.ClientId), + }) + if err != nil { + return fmt.Errorf("error listing applications to find objId: %w", err) + } + if apps == nil { + return errors.New("nil apps returned when listing to find objId") + } + if len(*apps) != 1 { + return fmt.Errorf("unexpected number of apps found, expected 1, found %d", len(*apps)) + } + a.AuthParams.ClientObjectId = *(*apps)[0].DirectoryObject.ID + + return nil } // rotateCredentials creates a new password, then uses a client with that new // password to revoke the old. // // NOTE: the underlying auth config will be modified to use the new credentials! -func rotateCredential(ctx context.Context, hConfig *WrappedHamiltonConfig, opt ...Option) (*msgraph.PasswordCredential, error) { - if hConfig == nil { - return nil, errors.New("empty auth config id") +func rotateCredential(ctx context.Context, authzInfo *AuthorizationInfo, opt ...Option) (*msgraph.PasswordCredential, error) { + if authzInfo == nil { + return nil, errors.New("empty authz info") } - if hConfig.SecretId == "" { + if authzInfo.AuthParams.SecretId == "" { return nil, errors.New("missing original secret id") } - // Get the object ID here so we don't have to look it up twice - objId, err := getObjectId(ctx, hConfig) - if err != nil { + // Ensure the object ID is set + if err := authzInfo.populateObjectId(ctx); err != nil { return nil, fmt.Errorf("error fetching object id: %w", err) } - newCred, err := addCredential(ctx, hConfig, WithObjectId(objId)) + newCred, err := addCredential(ctx, authzInfo) if err != nil { return nil, fmt.Errorf("error adding password: %w", err) } @@ -209,19 +180,23 @@ func rotateCredential(ctx context.Context, hConfig *WrappedHamiltonConfig, opt . return nil, errors.New("new credential secret text is nil after adding") } - if err := removeCredential(ctx, hConfig, WithObjectId(objId)); err != nil { + if err := removeCredential(ctx, authzInfo); err != nil { return nil, fmt.Errorf("error removing previous credential: %w", err) } return newCred, nil } -func addCredential(ctx context.Context, hConfig *WrappedHamiltonConfig, opt ...Option) (*msgraph.PasswordCredential, error) { - objId, err := getObjectId(ctx, hConfig, opt...) - if err != nil { +func addCredential(ctx context.Context, authzInfo *AuthorizationInfo, opt ...Option) (*msgraph.PasswordCredential, error) { + if authzInfo == nil { + return nil, errors.New("empty authz info") + } + + // Ensure the object ID is set + if err := authzInfo.populateObjectId(ctx); err != nil { return nil, fmt.Errorf("error fetching object id: %w", err) } - aClient, err := getApplicationsClient(ctx, hConfig) + aClient, err := getApplicationsClient(ctx, authzInfo) if err != nil { return nil, fmt.Errorf("error getting application client: %w", err) } @@ -231,7 +206,7 @@ func addCredential(ctx context.Context, hConfig *WrappedHamiltonConfig, opt ...O // Create the new password displayName := fmt.Sprintf("boundary-rotated-%s", time.Now().Format(time.RFC3339)) - newPass, _, err := aClient.AddPassword(ctx, objId, msgraph.PasswordCredential{ + newPass, _, err := aClient.AddPassword(ctx, authzInfo.AuthParams.ClientObjectId, msgraph.PasswordCredential{ DisplayName: &displayName, }) if err != nil { @@ -250,9 +225,9 @@ func addCredential(ctx context.Context, hConfig *WrappedHamiltonConfig, opt ...O return newPass, nil } -func removeCredential(ctx context.Context, hConfig *WrappedHamiltonConfig, opt ...Option) error { - objId, err := getObjectId(ctx, hConfig, opt...) - if err != nil { +func removeCredential(ctx context.Context, authzInfo *AuthorizationInfo, opt ...Option) error { + // Ensure the object ID is set + if err := authzInfo.populateObjectId(ctx); err != nil { return fmt.Errorf("error fetching object id: %w", err) } @@ -261,12 +236,12 @@ func removeCredential(ctx context.Context, hConfig *WrappedHamiltonConfig, opt . return fmt.Errorf("error parsing ops: %w", err) } - secretId := hConfig.SecretId + secretId := authzInfo.AuthParams.SecretId if opts.withSecretId != "" { secretId = opts.withSecretId } - aClient, err := getApplicationsClient(ctx, hConfig) + aClient, err := getApplicationsClient(ctx, authzInfo) if err != nil { return fmt.Errorf("error getting application client: %w", err) } @@ -274,7 +249,7 @@ func removeCredential(ctx context.Context, hConfig *WrappedHamiltonConfig, opt . return errors.New("applications client is nil when removing credential") } - _, err = aClient.RemovePassword(ctx, objId, secretId) + _, err = aClient.RemovePassword(ctx, authzInfo.AuthParams.ClientObjectId, secretId) if err != nil { return fmt.Errorf("error removing old password: %w", err) } diff --git a/plugin/client.go b/plugin/client.go index b54c98d..55c58e9 100644 --- a/plugin/client.go +++ b/plugin/client.go @@ -112,20 +112,17 @@ func getPublicIpAddressesClient(opt ...Option) (*network.PublicIPAddressesClient return &client, nil } -func getApplicationsClient(ctx context.Context, authConfig *WrappedHamiltonConfig) (*msgraph.ApplicationsClient, error) { - if authConfig == nil { +func getApplicationsClient(ctx context.Context, authzInfo *AuthorizationInfo) (*msgraph.ApplicationsClient, error) { + if authzInfo == nil { return nil, errors.New("empty auth config id when fetching service principals client") } - if authConfig.TenantID == "" { - return nil, errors.New("empty tenant id in auth config when fetching service principals client") - } - authorizer, err := authConfig.NewAuthorizer(ctx, hauth.MsGraph) + authorizer, err := authzInfo.HamiltonConfig.NewAuthorizer(ctx, hauth.MsGraph) if err != nil { return nil, fmt.Errorf("error fetching hauth authorizer when fetching service principals client: %w", err) } - client := msgraph.NewApplicationsClient(authConfig.TenantID) + client := msgraph.NewApplicationsClient(authzInfo.AuthParams.TenantId) client.BaseClient.Authorizer = authorizer return client, nil diff --git a/plugin/option.go b/plugin/option.go index a66fad0..485b3f6 100644 --- a/plugin/option.go +++ b/plugin/option.go @@ -26,16 +26,15 @@ type Option func(*options) error // options = how options are represented type options struct { - withHostCatalogAttrs *structpb.Struct - withPersistedData *structpb.Struct - withSubscriptionId string - withAuthorizer autorest.Authorizer - withUserAgent string - withBaseUrl string - withWrappedHamiltonConfig *WrappedHamiltonConfig - withClientId string - withObjectId string - withSecretId string + withHostCatalogAttrs *structpb.Struct + withPersistedData *structpb.Struct + withSubscriptionId string + withAuthorizer autorest.Authorizer + withUserAgent string + withBaseUrl string + withAuthorizationInfo *AuthorizationInfo + withClientId string + withSecretId string } func getDefaultOptions() options { @@ -100,10 +99,10 @@ func WithBaseUrl(with string) Option { } } -// WithWrappedHamiltonConfig contains the hamilton package authentication config to use -func WithWrappedHamiltonConfig(with *WrappedHamiltonConfig) Option { +// WithAuthorizationInfo contains the authorization information to use +func WithAuthorizationInfo(with *AuthorizationInfo) Option { return func(o *options) error { - o.withWrappedHamiltonConfig = with + o.withAuthorizationInfo = with return nil } } @@ -116,14 +115,6 @@ func WithClientId(with string) Option { } } -// WithObjectId contains the object ID to use -func WithObjectId(with string) Option { - return func(o *options) error { - o.withObjectId = with - return nil - } -} - // WithSecretId contains the secret ID to use func WithSecretId(with string) Option { return func(o *options) error { diff --git a/plugin/plugin.go b/plugin/plugin.go index 40c6c3d..7003dcc 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -9,7 +9,7 @@ import ( "github.com/Azure/azure-sdk-for-go/profiles/latest/network/mgmt/network" "github.com/Azure/azure-sdk-for-go/profiles/latest/resources/mgmt/resources" - "github.com/kr/pretty" + "github.com/mitchellh/mapstructure" "google.golang.org/protobuf/types/known/structpb" "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostcatalogs" @@ -27,11 +27,11 @@ var ( ) func rotateCredFromCallback(ctx context.Context, catalog *hostcatalogs.HostCatalog) (*pb.HostCatalogPersisted, error) { - authConfig, err := getWrappedHamiltonConfig(catalog, nil) + authzInfo, err := getAuthorizationInfo(catalog) if err != nil { return nil, fmt.Errorf("error getting hauth config when creating catalog: %w", err) } - newPass, err := rotateCredential(ctx, authConfig) + newPass, err := rotateCredential(ctx, authzInfo) if err != nil { return nil, fmt.Errorf("error rotating credentials when creating catalog: %w", err) } @@ -67,14 +67,12 @@ func (p *AzurePlugin) OnCreateCatalog(ctx context.Context, req *pb.OnCreateCatal // Check if rotation is skipped. Always prefer attempting rotation unless we // explicitly are told not to var skipRotation bool - if attrs := catalog.GetAttributes(); attrs != nil { - if fields := attrs.GetFields(); fields != nil { - if field := fields[constDisableCredentialRotation]; field != nil { - if field.GetBoolValue() { - skipRotation = true - } - } + if catalog.GetAttributes() != nil { + var attrs Attributes + if err := mapstructure.Decode(catalog.GetAttributes().AsMap(), &attrs); err != nil { + return nil, fmt.Errorf("error decoding catalog attributes: %w", err) } + skipRotation = attrs.DisableCredentialRotation } if skipRotation { return &pb.OnCreateCatalogResponse{ @@ -117,13 +115,13 @@ func (p *AzurePlugin) OnUpdateCatalog(ctx context.Context, req *pb.OnUpdateCatal sanitizeSecretsFields(secrets) // If the old credential had been rotated, attempt to delete the old - // credential using itself; if it fails, proceed anyways, since in theory - // only Boundary knows this value so simply forgetting it is safe enough (if - // not clean). + // credentials using the new ones; if it fails, proceed anyways, since in + // theory only Boundary knows this value so simply forgetting it is safe + // enough (if not clean). var field *structpb.Value var pdFields map[string]*structpb.Value var err error - var authConfig *WrappedHamiltonConfig + var authzInfo *AuthorizationInfo persisted := req.GetPersisted() if persisted == nil { @@ -141,12 +139,13 @@ func (p *AzurePlugin) OnUpdateCatalog(ctx context.Context, req *pb.OnUpdateCatal goto after_revocation } // If the field exists, it is a timestamp here indicating last rotation time - authConfig, err = getWrappedHamiltonConfig(currentCatalog, req.GetPersisted()) + currentCatalog.Secrets = req.GetPersisted().Secrets + authzInfo, err = getAuthorizationInfo(currentCatalog) if err != nil { // TODO: warn in some way? goto after_revocation } - if err := removeCredential(ctx, authConfig); err != nil { + if err := removeCredential(ctx, authzInfo); err != nil { // TODO: warn goto after_revocation } @@ -199,14 +198,16 @@ func (p *AzurePlugin) OnDeleteCatalog(ctx context.Context, req *pb.OnDeleteCatal return nil, nil } // The field existing means it is a string containing the last time it was - // rotated. Delete the credential using itself. - authConfig, err := getWrappedHamiltonConfig(req.GetCatalog(), req.GetPersisted()) + // rotated. Delete the credential using current creds. + catalog := req.GetCatalog() + catalog.Secrets = req.GetPersisted().GetSecrets() + authzInfo, err := getAuthorizationInfo(catalog) if err != nil { return nil, fmt.Errorf("error getting auth config on catalog deletion: %w", err) } - if err := removeCredential(ctx, authConfig); err != nil { + if err := removeCredential(ctx, authzInfo); err != nil { if err != nil { - return nil, fmt.Errorf("error revoking credential on catalog deletion: %w, authConfig is %s", err, pretty.Sprint(authConfig)) + return nil, fmt.Errorf("error revoking credential on catalog deletion: %w", err) } } @@ -243,16 +244,17 @@ func (p *AzurePlugin) ListHosts(ctx context.Context, req *pb.ListHostsRequest) ( } // Create an authorizer - var secrets *structpb.Struct - if req.GetPersisted() != nil { - secrets = req.GetPersisted().GetSecrets() - } - subscriptionId, authorizer, err := fetchAuthorizer(catalog, secrets) + catalog.Secrets = req.GetPersisted().GetSecrets() + authzInfo, err := getAuthorizationInfo(catalog) if err != nil { - return nil, fmt.Errorf("error fetching subscription id and authorizer: %w", err) + return nil, fmt.Errorf("error fetching authorizationInfo: %w", err) } - if subscriptionId == "" { - return nil, errors.New("subscription id not discovered") + if authzInfo == nil { + return nil, errors.New("authorization info is nil") + } + authorizer, err := authzInfo.autorestAuthorizer() + if err != nil { + return nil, fmt.Errorf("error fetching autorest authorizer: %w", err) } if authorizer == nil { return nil, errors.New("fetched authorizer is nil") @@ -260,7 +262,7 @@ func (p *AzurePlugin) ListHosts(ctx context.Context, req *pb.ListHostsRequest) ( commonOpts := make([]Option, 0, 3) commonOpts = append(commonOpts, - WithSubscriptionId(subscriptionId), + WithSubscriptionId(authzInfo.AuthParams.SubscriptionId), WithAuthorizer(authorizer), ) diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go index a076464..5418794 100644 --- a/plugin/plugin_test.go +++ b/plugin/plugin_test.go @@ -51,7 +51,7 @@ func TestOnCreateOnDeleteCatalog(t *testing.T) { ctx := context.Background() p := &AzurePlugin{} hostCatalog, _ := testGetHostStructs(t) - objId, initialAuthConfig, initialCred, cleanup := testCreateInitialSecret(t, hostCatalog) + initialAuthConfig, initialCred, cleanup := testCreateInitialSecret(t, hostCatalog) defer cleanup() // At this point, remove secrets corresponding to those read in by @@ -106,7 +106,6 @@ func TestOnCreateOnDeleteCatalog(t *testing.T) { _ = removeCredential( ctx, &deferAuthConfig, - WithObjectId(objId), ) }() @@ -123,8 +122,9 @@ func TestOnCreateOnDeleteCatalog(t *testing.T) { // waitForCreds(t, &waitForCredsAuthConfig, false) // Make sure the new creds work, then sleep - waitForCredsAuthConfig.SecretId = newPdFields[constSecretId].GetStringValue() - waitForCredsAuthConfig.ClientSecret = newPdFields[constSecretValue].GetStringValue() + waitForCredsAuthConfig.AuthParams.SecretId = newPdFields[constSecretId].GetStringValue() + waitForCredsAuthConfig.AuthParams.SecretValue = newPdFields[constSecretValue].GetStringValue() + waitForCredsAuthConfig.HamiltonConfig.ClientSecret = newPdFields[constSecretValue].GetStringValue() waitForCreds(t, &waitForCredsAuthConfig, true) time.Sleep(10 * time.Minute) @@ -139,8 +139,8 @@ func TestOnCreateOnDeleteCatalog(t *testing.T) { // Now, use the credentials we got above to revoke this credential we got from OnCreate secrets = wrapMap(t, map[string]interface{}{ - constSecretValue: waitForCredsAuthConfig.ClientSecret, - constSecretId: waitForCredsAuthConfig.SecretId, + constSecretValue: waitForCredsAuthConfig.HamiltonConfig.ClientSecret, + constSecretId: waitForCredsAuthConfig.AuthParams.SecretId, }) cdResp, err = p.OnDeleteCatalog(ctx, &pb.OnDeleteCatalogRequest{ Catalog: hostCatalog, @@ -155,7 +155,7 @@ func TestOnCreateOnDeleteCatalog(t *testing.T) { // waitForCreds(t, &waitForCredsAuthConfig, false) } -func waitForCreds(t *testing.T, hConfig *WrappedHamiltonConfig, shouldWork bool) auth.Authorizer { +func waitForCreds(t *testing.T, authzInfo *AuthorizationInfo, shouldWork bool) auth.Authorizer { t.Helper() require := require.New(t) ctx := context.Background() @@ -164,9 +164,9 @@ func waitForCreds(t *testing.T, hConfig *WrappedHamiltonConfig, shouldWork bool) environments.Global, auth.MsGraph, auth.TokenVersion2, - hConfig.TenantID, - hConfig.ClientID, - hConfig.ClientSecret) + authzInfo.AuthParams.TenantId, + authzInfo.AuthParams.ClientId, + authzInfo.AuthParams.SecretValue) require.NoError(err) for { @@ -230,45 +230,39 @@ func testGetHostStructs(t *testing.T) (*hostcatalogs.HostCatalog, []*hostsets.Ho // leading into a test. This will serve as our "initial secret" for a test. We // also return a few cached items. It is expected that the host catalog contains // Secrets. -func testCreateInitialSecret(t *testing.T, hostCatalog *hostcatalogs.HostCatalog) (string, *WrappedHamiltonConfig, *msgraph.PasswordCredential, func()) { +func testCreateInitialSecret(t *testing.T, hostCatalog *hostcatalogs.HostCatalog) (*AuthorizationInfo, *msgraph.PasswordCredential, func()) { require := require.New(t) ctx := context.Background() var initialCred *msgraph.PasswordCredential - var objId string // The object ID of the application // Set up the data, get the config - persistedData := hostCatalog.GetSecrets() - authConfig, err := getWrappedHamiltonConfig(hostCatalog, &pb.HostCatalogPersisted{Secrets: persistedData}) - require.NoError(err) - - // Pre-cache the object ID - objId, err = getObjectId(ctx, authConfig, WithClientId(hostCatalog.GetAttributes().GetFields()[constClientId].GetStringValue())) + authzInfo, err := getAuthorizationInfo(hostCatalog) require.NoError(err) // Get the credential - initialCred, err = addCredential(ctx, authConfig, WithObjectId(objId)) + initialCred, err = addCredential(ctx, authzInfo) require.NoError(err) require.NotNil(initialCred) require.NotNil(initialCred.KeyId) require.NotNil(initialCred.SecretText) - origAuthConfig := *authConfig + origAuthConfig := *authzInfo + origAuthConfig.AuthParams.SecretId = *initialCred.KeyId cleanup := func() { if err := removeCredential( ctx, &origAuthConfig, - WithObjectId(objId), - WithSecretId(*initialCred.KeyId), ); err != nil { // It may not exist because it's been rotated require.Contains(err.Error(), "No password credential found with keyId", err.Error()) } } - authConfig.SecretId = *initialCred.KeyId - authConfig.ClientSecret = *initialCred.SecretText - waitForCreds(t, authConfig, true) + authzInfo.AuthParams.SecretId = *initialCred.KeyId + authzInfo.AuthParams.SecretValue = *initialCred.SecretText + authzInfo.HamiltonConfig.ClientSecret = *initialCred.SecretText + waitForCreds(t, authzInfo, true) - return objId, authConfig, initialCred, cleanup + return authzInfo, initialCred, cleanup }