Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ type AzureProvider interface {
parameters authorization.RoleAssignmentCreateParameters) (authorization.RoleAssignment, error)
DeleteRoleAssignmentByID(ctx context.Context, roleID string) (authorization.RoleAssignment, error)

CreateAppRoleAssignment(ctx context.Context, roleName string, spnObjectID string, resourceID string) (*AppRoleAssignment, error)
DeleteAppRoleAssignmentByID(ctx context.Context, resourceID string, roleAssignmentID string) error

ListRoleDefinitions(ctx context.Context, scope string, filter string) ([]authorization.RoleDefinition, error)
GetRoleDefinitionByID(ctx context.Context, roleID string) (authorization.RoleDefinition, error)
}
Expand Down Expand Up @@ -61,3 +64,9 @@ type ApplicationResult struct {
ID *string `json:"id,omitempty"`
PasswordCredentials []*PasswordCredential `json:"passwordCredentials,omitempty"`
}

// AppRoleAssignment holds an the ID of an App Role Assignment
type AppRoleAssignment struct {
ID string `json:"id"`
ResourceID string `json:"resource_id"`
}
6 changes: 4 additions & 2 deletions api/application_msgraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,11 @@ func (c AppClient) removePasswordResponder(resp *http.Response) (autorest.Respon

func (c AppClient) createApplicationPreparer(ctx context.Context, displayName string) (*http.Request, error) {
parameters := struct {
DisplayName *string `json:"displayName"`
DisplayName *string `json:"displayName"`
SignInAudience *string `json:"signInAudience"`
}{
DisplayName: to.StringPtr(displayName),
DisplayName: to.StringPtr(displayName),
SignInAudience: to.StringPtr("AzureADMyOrg"),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed to fix an issue with persist_app since the default value will only allow 2 active tokens at a time.

If needed I can pull this into its own PR.

}

preparer := autorest.CreatePreparer(
Expand Down
49 changes: 49 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,55 @@ func (c *client) unassignRoles(ctx context.Context, roleIDs []string) error {
return merr.ErrorOrNil()
}

func (c *client) assignAppRoles(ctx context.Context, spnObjID string, roles []*AppRoleAssignments) ([]*api.AppRoleAssignment, error) {
var ids []*api.AppRoleAssignment

for _, role := range roles {
for _, appRole := range role.Roles {
resultRaw, err := retry(ctx, func() (interface{}, bool, error) {
ra, err := c.provider.CreateAppRoleAssignment(ctx, appRole.RoleName, spnObjID, role.AppID)

// Propagation delays within Azure can cause this error occasionally, so don't quit on it.
if err != nil && strings.Contains(err.Error(), "PrincipalNotFound") {
return nil, false, nil
} else if err != nil {
return "", true, err
}

return ra, true, nil
})

if err != nil {
return nil, fmt.Errorf("error while assigning app roles: %w", err)
}
ids = append(ids, resultRaw.(*api.AppRoleAssignment))
}
}

return ids, nil
}

// unassignAppRoles deletes app role assignments, if they existed.
// This is a clean-up operation that isn't essential to revocation. As such, an
// attempt is made to remove all assignments, and not return immediately if there
// is an error.
func (c *client) unassignAppRoles(ctx context.Context, roleIDs []*api.AppRoleAssignment) error {
var merr *multierror.Error

for _, assignment := range roleIDs {
if err := c.provider.DeleteAppRoleAssignmentByID(ctx, assignment.ResourceID, assignment.ID); err != nil {
// If a role was deleted manually then Azure returns a error and status 204
if strings.Contains(err.Error(), "204") || strings.Contains(err.Error(), "404") {
continue
}

merr = multierror.Append(merr, fmt.Errorf("error unassigning app role: %w", err))
}
}

return merr.ErrorOrNil()
}

// addGroupMemberships adds the service principal to the Azure groups.
func (c *client) addGroupMemberships(ctx context.Context, spID string, groups []*AzureGroup) error {
for _, group := range groups {
Expand Down
9 changes: 6 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/vault/api v1.9.0
github.com/hashicorp/vault/sdk v0.8.1
github.com/manicminer/hamilton v0.49.0
github.com/mitchellh/mapstructure v1.5.0
)

Expand All @@ -41,13 +42,13 @@ require (
github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0 // indirect
github.com/hashicorp/go-kms-wrapping/v2 v2.0.7 // indirect
github.com/hashicorp/go-plugin v1.4.5 // indirect
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/go-version v1.2.0 // indirect
github.com/hashicorp/go-version v1.3.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
Expand All @@ -64,10 +65,12 @@ require (
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.5.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 // indirect
google.golang.org/grpc v1.41.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
Expand Down
Loading