Skip to content

Commit

Permalink
Add Organizations for Client Credentials (#432)
Browse files Browse the repository at this point in the history
Co-authored-by: KunalOfficial <[email protected]>
  • Loading branch information
duedares-rvj and developerkunal authored Aug 26, 2024
1 parent e219463 commit 0c331b7
Show file tree
Hide file tree
Showing 15 changed files with 2,512 additions and 1,617 deletions.
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 *ClientDefaultOrganization `json:"default_organization,omitempty"`
}

// ClientDefaultOrganization allows the support for client credentials feature.
type ClientDefaultOrganization 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/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,35 @@ func TestClient_Create(t *testing.T) {
})
}

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

org := givenAnOrganization(t)

expectedClient := &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: &ClientDefaultOrganization{
Flows: &[]string{"client_credentials"},
OrganizationID: auth0.String(org.GetID()),
},
}

err := api.Client.Create(context.Background(), expectedClient)
assert.NoError(t, err)
assert.NotEmpty(t, expectedClient.GetClientID())

retrievedClient, err := api.Client.Read(context.Background(), expectedClient.GetClientID())
assert.NoError(t, err)
assert.NotEmpty(t, retrievedClient.DefaultOrganization.GetOrganizationID())
assert.NotEmpty(t, retrievedClient.DefaultOrganization.GetFlows())

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

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

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: &ClientDefaultOrganization{
Flows: &[]string{"client_credentials"},
OrganizationID: 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

0 comments on commit 0c331b7

Please sign in to comment.