Skip to content

ACCT-4459: Support for domain scoped roles#1095

Merged
jacobbednarz merged 26 commits intomasterfrom
imobbs/ACCT-4459-domain-scoped-roles
Oct 13, 2022
Merged

ACCT-4459: Support for domain scoped roles#1095
jacobbednarz merged 26 commits intomasterfrom
imobbs/ACCT-4459-domain-scoped-roles

Conversation

@ianmobbs
Copy link
Copy Markdown

As we begin to GA domain-scoped roles, we'd like to add support for these new controls to the Cloudflare Go SDK.

Description

The primary changes here are:

  • Update AccountMember to contain both AccountRoles and Policies, our new struct for representing access control
  • Add structs for Policies and all required sub-structs

Has your change been tested?

Yes, we have extended existing tests, added new tests, and written a verification script

Screenshots (if appropriate):

n/a

Types of changes

What sort of change does your code introduce/modify?

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • This change is using publicly documented (api.cloudflare.com or developers.cloudflare.com) and stable APIs.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Sep 29, 2022

changelog detected ✅

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Sep 29, 2022

Codecov Report

❌ Patch coverage is 70.29703% with 30 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.29%. Comparing base (e39278e) to head (6f4b50f).

Files with missing lines Patch % Lines
permission_group.go 35.13% 16 Missing and 8 partials ⚠️
account_members.go 85.71% 4 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1095      +/-   ##
==========================================
+ Coverage   49.94%   50.29%   +0.34%     
==========================================
  Files         115      119       +4     
  Lines       10991    11455     +464     
==========================================
+ Hits         5490     5761     +271     
- Misses       4338     4463     +125     
- Partials     1163     1231      +68     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ianmobbs ianmobbs self-assigned this Sep 29, 2022
Comment thread account_members.go Outdated
// upon member invitation. We recommend upgrading to CreateAccountMemberWithPolicies to use policies.
//
// API reference: https://api.cloudflare.com/#account-members-add-member
func (api *API) CreateAccountMember(ctx context.Context, accountID string, emailAddress string, roles []string) (AccountMember, error) {
Copy link
Copy Markdown
Contributor

@jacobbednarz jacobbednarz Sep 29, 2022

Choose a reason for hiding this comment

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

if we're overhauling the invitations, let's update CreateAccountMember method signature to match the experimental client. this will also allow you to cut down on some of the boilerplate code we're repeating and putting into CreateAccountMemberInternal.

(incomplete but hopefully enough to get you started example)

type CreateAccountMemberParams struct {
	Email    string   `json:"email"`
	Roles    []string `json:"roles,omitempty"`
	Policies []Policy `json:"policies,omitempty"`
	Status   string   `json:"status,omitempty"`
}

func (api *API) CreateAccountMember(ctx context.Context, rc *ResourceContainer, params CreateAccountMemberParams) (AccountMember, error) {
	invite := AccountMemberInvitation{
		Email: params.Email,
	}

	if len(params.Roles) > 0 {
		invite.Roles = params.Roles
	}

	// ... etc
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good call, thanks! Can you confirm that this is the right way to go about things?

  • Re-write CreateAccountMember to match the experimental client
  • Remove the CreateAccountMemberInternal method
  • Re-factor utility methods (CreateAccountMemberWithStatus, CreateAccountMemberWithRoles, etc) to just call CreateAccountMember - the alternative I supposed is just removing the utility methods?

Here's my current CreateAccountMember impl, let me know if it looks okay and the above is correct and I'll push :)

func (api *API) CreateAccountMember(ctx context.Context, rc *ResourceContainer, params CreateAccountMemberParams) (AccountMember, error) {
	if rc.Level != AccountRouteLevel {
		return AccountMember{}, fmt.Errorf(errInvalidResourceContainerAccess, rc.Level)
	}

	invite := AccountMemberInvitation{
		Email:  params.EmailAddress,
		Status: params.Status,
	}

	roles := []AccountRole{}
	for i := 0; i < len(params.Roles); i++ {
		roles = append(roles, AccountRole{ID: invite.Roles[i]})
	}
	err := validateRolesAndPolicies(roles, params.Policies)
	if err != nil {
		return AccountMember{}, err
	}

	if params.Roles != nil {
		invite.Roles = params.Roles
	} else if params.Policies != nil {
		invite.Policies = params.Policies
	}

	uri := fmt.Sprintf("/accounts/%s/members", rc.Identifier)
	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, invite)
	if err != nil {
		return AccountMember{}, err
	}

	var accountMemberListResponse AccountMemberDetailResponse
	err = json.Unmarshal(res, &accountMemberListResponse)
	if err != nil {
		return AccountMember{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
	}

	return accountMemberListResponse.Result, nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

looks spot on! nice one.

Comment thread account_members.go Outdated
Comment thread errors.go Outdated
Comment thread resource_group.go
@ianmobbs ianmobbs force-pushed the imobbs/ACCT-4459-domain-scoped-roles branch from abc8db2 to c4f8f2e Compare September 30, 2022 23:19
Comment thread account_members_test.go Outdated
}

mux.HandleFunc("/accounts/01a7362d577a6c3019a474fd6f485823/members", handler)
accountResource := &ResourceContainer{
Copy link
Copy Markdown
Contributor

@jacobbednarz jacobbednarz Oct 3, 2022

Choose a reason for hiding this comment

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

from the code docs - https://github.com/cloudflare/cloudflare-go/blob/master/resource.go#L12-L14

// ResourceContainer defines an API resource you wish to target. Should not be
// used directly, use `UserIdentifier`, `ZoneIdentifier` and `AccountIdentifier`
// instead.

while you can do this, i'd recommend using the helpers instead incase we expand this struct. it's also a bit nicer to read 😄 AccountIdentifier("01a7362d577a6c3019a474fd6f485823")

@jacobbednarz jacobbednarz merged commit 40a64a8 into master Oct 13, 2022
@jacobbednarz jacobbednarz deleted the imobbs/ACCT-4459-domain-scoped-roles branch October 13, 2022 00:03
@github-actions github-actions Bot added this to the v0.53.0 milestone Oct 13, 2022
github-actions Bot pushed a commit that referenced this pull request Oct 13, 2022
@github-actions
Copy link
Copy Markdown

This functionality has been released in v0.53.0.

For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants