Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Organizations for Client Credentials #432

Merged
merged 11 commits into from
Aug 26, 2024
8 changes: 8 additions & 0 deletions management/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ type Client struct {

// RequireProofOfPossession Makes the use of Proof-of-Possession mandatory for this client (default: false).
RequireProofOfPossession *bool `json:"require_proof_of_possession,omitempty"`

DefaultOrganization *DefaultOrganization `json:"default_organization,omitempty"`
}

// DefaultOrganization allows the support for client credentials feature.
type DefaultOrganization struct {
Flows *[]string `json:"flows,omitempty"`
OrganizationID *string `json:"organization_id,omitempty"`
}

// ClientSignedRequestObject is used to configure JWT-secured Authorization Requests (JAR) settings for our Client.
Expand Down
29 changes: 29 additions & 0 deletions management/management.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions management/management.gen_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 77 additions & 0 deletions management/organization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"
"os"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -474,6 +475,82 @@ func TestOrganizationManager_ClientGrants(t *testing.T) {
assert.Len(t, associatedGrants.ClientGrants, 0)
}

func TestOrganizationManager_ClientGrantsWithOrg(t *testing.T) {
configureHTTPTestRecordings(t)

org := givenAnOrganization(t)
resourceServer := givenAResourceServer(t)

client := &Client{
Name: auth0.Stringf("Test Client (%s)", time.Now().Format(time.StampMilli)),
Description: auth0.String("This is just a test client."),
OrganizationUsage: auth0.String("allow"),
DefaultOrganization: &DefaultOrganization{
&[]string{"client_credentials"},
auth0.String(org.GetID()),
},
}
// Create a client that shall be used for testing.
err := api.Client.Create(context.Background(), client)
require.NoError(t, err)

t.Cleanup(func() {
cleanupClient(t, client.GetClientID())
})

clientGrant := &ClientGrant{
ClientID: client.ClientID,
Audience: resourceServer.Identifier,
Scope: &[]string{"create:resource", "create:organization_client_grants"},
AllowAnyOrganization: auth0.Bool(true),
OrganizationUsage: auth0.String("allow"),
}

// Create a clientGrant and associate with the client created above.
err = api.ClientGrant.Create(context.Background(), clientGrant)
require.NoError(t, err)
t.Cleanup(func() {
cleanupClientGrant(t, clientGrant.GetID())
})

// Associates the grant with an organization.
err = api.Organization.AssociateClientGrant(context.Background(), org.GetID(), clientGrant.GetID())
require.NoError(t, err)

// List all clients associated with a ClientGrant given an organizationID as query param
clients, err := api.Client.List(context.Background(), Parameter("q", fmt.Sprintf("client_grant.organization_id:%s", org.GetID())))
require.NoError(t, err)
for _, c := range clients.Clients {
assert.Equal(t, org.GetID(), c.DefaultOrganization.GetOrganizationID())
}

// List all ClientGrants given a list of grant_ids as query param
associatedGrants, err := api.Organization.ClientGrants(context.Background(), org.GetID(), Parameter("grant_ids", clientGrant.GetID()))
require.NoError(t, err)
assert.Greater(t, len(associatedGrants.ClientGrants), 0)
assert.Contains(t, associatedGrants.ClientGrants, clientGrant)

// Remove the associated ClientGrants
err = api.Organization.RemoveClientGrant(context.Background(), org.GetID(), clientGrant.GetID())
require.NoError(t, err)

// List all ClientGrants which should be an empty list since grant has been removed from the organization.
associatedGrants, err = api.Organization.ClientGrants(context.Background(), org.GetID(), Parameter("grant_ids", clientGrant.GetID()))
require.NoError(t, err)
assert.Len(t, associatedGrants.ClientGrants, 0)

// Delete the ClientGrant.
err = api.ClientGrant.Delete(context.Background(), clientGrant.GetID())
require.NoError(t, err)

// Retrieve the ClientGrant and ensure error is return since grant has been deleted.
retrievedGrant, err := api.ClientGrant.Read(context.Background(), clientGrant.GetID())
assert.Nil(t, retrievedGrant)
assert.Error(t, err)
assert.Implements(t, (*Error)(nil), err)
assert.Equal(t, http.StatusNotFound, err.(Error).Status())
}

func givenAnOrganization(t *testing.T) *Organization {
org := &Organization{
Name: auth0.String(fmt.Sprintf("test-organization%v", rand.Intn(999))),
Expand Down
12 changes: 8 additions & 4 deletions management/resource_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,11 @@ func TestResourceServer_List(t *testing.T) {
configureHTTPTestRecordings(t)

expectedResourceServer := givenAResourceServer(t)

resourceServerList, err := api.ResourceServer.List(context.Background(), IncludeFields("id"))

resourceServerList, err := api.ResourceServer.List(context.Background(), IncludeFields("id", "identifier"), Parameter("identifiers", expectedResourceServer.GetIdentifier()))
require.NoError(t, err)
assert.NotEqual(t, len(resourceServerList.ResourceServers), 0)
assert.NoError(t, err)
assert.Contains(t, resourceServerList.ResourceServers, &ResourceServer{ID: expectedResourceServer.ID})
assert.Contains(t, resourceServerList.ResourceServers, &ResourceServer{ID: expectedResourceServer.ID, Identifier: expectedResourceServer.Identifier})
}

func givenAResourceServer(t *testing.T) *ResourceServer {
Expand All @@ -243,6 +243,10 @@ func givenAResourceServer(t *testing.T) *ResourceServer {
Value: auth0.String("create:resource"),
Description: auth0.String("Create Resource"),
},
{
Value: auth0.String("create:organization_client_grants"),
Description: auth0.String("Create Org Client Grants"),
},
},
}

Expand Down
Loading