Skip to content

Commit

Permalink
Listing resource-sets
Browse files Browse the repository at this point in the history
  • Loading branch information
mchavez committed Oct 18, 2024
1 parent 7c53567 commit 0086172
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pkg/connector/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ var (
DisplayName: "Account",
Annotations: v1AnnotationsForResourceType("account", false),
}
resourceTypeResourceSets = &v2.ResourceType{
Id: "resourcesets",
DisplayName: "Resource Sets",
Annotations: v1AnnotationsForResourceType("resourcesets", false),
}
defaultScopes = []string{
"okta.users.read",
"okta.groups.read",
Expand Down Expand Up @@ -172,6 +177,7 @@ func (o *Okta) ResourceSyncers(ctx context.Context) []connectorbuilder.ResourceS
userBuilder(o.domain, o.apiToken, o.client),
groupBuilder(o),
appBuilder(o.domain, o.apiToken, o.syncInactiveApps, o.client),
resourceSetsBuilder(o.client),
}
}

Expand Down
25 changes: 25 additions & 0 deletions pkg/connector/models.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package connector

import "time"

type ResourceSetsAPIData struct {
ResourceSets []ResourceSets `json:"resource-sets,omitempty"`
Links Link `json:"_links,omitempty"`
}

type ResourceSets struct {
ID string `json:"id,omitempty"`
Label string `json:"label,omitempty"`
Description string `json:"description,omitempty"`
Created time.Time `json:"created,omitempty"`
LastUpdated time.Time `json:"lastUpdated,omitempty"`
Links interface{} `json:"_links,omitempty"`
}

type Next struct {
Href string `json:"href,omitempty"`
}

type Link struct {
Next Next `json:"next,omitempty"`
}
133 changes: 133 additions & 0 deletions pkg/connector/resource_sets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package connector

import (
"context"
"fmt"
"net/http"

v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2"
"github.com/conductorone/baton-sdk/pkg/annotations"
"github.com/conductorone/baton-sdk/pkg/pagination"
sdkResource "github.com/conductorone/baton-sdk/pkg/types/resource"
"github.com/okta/okta-sdk-golang/v2/okta"
"github.com/okta/okta-sdk-golang/v2/okta/query"
)

type resourceSetsResourceType struct {
resourceType *v2.ResourceType
client *okta.Client
}

const apiPathListIamResourceSets = "/api/v1/iam/resource-sets"

func (rs *resourceSetsResourceType) ResourceType(ctx context.Context) *v2.ResourceType {
return rs.resourceType
}

func resourceSetsResource(ctx context.Context, rs *ResourceSets, parentResourceID *v2.ResourceId) (*v2.Resource, error) {
profile := map[string]interface{}{
"id": rs.ID,
"label": rs.Label,
"description": rs.Description,
}

return sdkResource.NewResource(
rs.Label,
resourceTypeResourceSets,
rs.ID,
sdkResource.WithParentResourceID(parentResourceID),
sdkResource.WithAppTrait(
sdkResource.WithAppProfile(profile),
),
)
}

func listOktaIamResourceSets(ctx context.Context,
client *okta.Client,
token *pagination.Token,
qp *query.Params,
) ([]ResourceSets, *responseContext, error) {
url := apiPathListIamResourceSets
if qp != nil {
url += qp.String()
}

rq := client.CloneRequestExecutor()
req, err := rq.WithAccept(ContentType).
WithContentType(ContentType).
NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, nil, err
}

var rSets *ResourceSetsAPIData
resp, err := rq.Do(ctx, req, &rSets)
if err != nil {
return nil, nil, err
}

respCtx, err := responseToContext(token, resp)
if err != nil {
return nil, nil, err
}

return rSets.ResourceSets, respCtx, nil
}

// List always returns an empty slice, we don't sync users.
func (rs *resourceSetsResourceType) List(ctx context.Context, parentResourceID *v2.ResourceId, pToken *pagination.Token) ([]*v2.Resource, string, annotations.Annotations, error) {
var rv []*v2.Resource
bag, page, err := parsePageToken(pToken.Token, &v2.ResourceId{ResourceType: resourceTypeResourceSets.Id})
if err != nil {
return nil, "", nil, fmt.Errorf("okta-connectorv2: failed to parse page token: %w", err)
}

qp := queryParams(pToken.Size, page)
rSets, respCtx, err := listOktaIamResourceSets(ctx, rs.client, pToken, qp)
if err != nil {
return nil, "", nil, fmt.Errorf("okta-connectorv2: failed to list resource-sets: %w", err)
}

nextPage, _, err := parseResp(respCtx.OktaResponse)
if err != nil {
return nil, "", nil, fmt.Errorf("okta-connectorv2: failed to parse response: %w", err)
}

err = bag.Next(nextPage)
if err != nil {
return nil, "", nil, fmt.Errorf("okta-connectorv2: failed to fetch bag.Next: %w", err)
}

for _, rSet := range rSets {
resource, err := resourceSetsResource(ctx, &rSet, nil)
if err != nil {
return nil, "", nil, fmt.Errorf("okta-connectorv2: failed to create resource-sets: %w", err)
}

rv = append(rv, resource)
}

pageToken, err := bag.Marshal()
if err != nil {
return nil, "", nil, err
}

return rv, pageToken, nil, nil
}

// Entitlements always returns an empty slice for users.
func (rs *resourceSetsResourceType) Entitlements(_ context.Context, resource *v2.Resource, _ *pagination.Token) ([]*v2.Entitlement, string, annotations.Annotations, error) {
return nil, "", nil, nil
}

// Grants always returns an empty slice for users since they don't have any entitlements.
func (rs *resourceSetsResourceType) Grants(ctx context.Context, resource *v2.Resource, pToken *pagination.Token) ([]*v2.Grant, string, annotations.Annotations, error) {
return nil, "", nil, nil
}

func resourceSetsBuilder(client *okta.Client) *resourceSetsResourceType {
return &resourceSetsResourceType{
resourceType: resourceTypeResourceSets,
client: client,
}
}

0 comments on commit 0086172

Please sign in to comment.