Massive cleanup. Tests are passing.

This commit is contained in:
Jeff Mitchell committed 2021-11-10 13:59:21 -05:00
1 parent 073c3e1904
commit 933fc23905
6 files changed
+208 -248

No files matched your search

+1
View File
@@ -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
)
+140 -165
View File
@@ -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)
}
+4 -7
View File
@@ -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
+12 -21
View File
@@ -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 {
+31 -29
View File
@@ -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),
)
+20 -26
View File
@@ -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
}