Skip to content

Commit

Permalink
Skip not found errors when fetching large grant lists of groups/apps (#…
Browse files Browse the repository at this point in the history
…61)

* Skip not found errors when fetching large grant lists of groups/apps

* Convert not found errors to GRPC not found status so baton-sdk can skip errors syncing grants/entitlements.

* Upgrade baton-sdk to support continuing after a 404 when listing grants/entitlements for a resource.

---------

Co-authored-by: Geoff Greer <[email protected]>
  • Loading branch information
pquerna and ggreer authored Dec 16, 2024
1 parent 698ac2d commit 76de83d
Show file tree
Hide file tree
Showing 27 changed files with 3,383 additions and 891 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/conductorone/baton-okta
go 1.22.2

require (
github.com/conductorone/baton-sdk v0.2.44
github.com/conductorone/baton-sdk v0.2.52
github.com/deckarep/golang-set/v2 v2.6.0
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/okta/okta-sdk-golang/v2 v2.20.0
Expand Down
7 changes: 4 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/conductorone/baton-sdk v0.2.44 h1:bmPRs+esNsrcZrAd4YWTmyHFO89GwHu+GOp/57keeqY=
github.com/conductorone/baton-sdk v0.2.44/go.mod h1:hmd/Oz3DPIKD+9QmkusZaA18ZoiinnTDdrxh2skcdUc=
github.com/conductorone/baton-sdk v0.2.52 h1:Pz+kA4F9e/rknjT+2FXS32jmndjvv6VXX1kALsN5eKQ=
github.com/conductorone/baton-sdk v0.2.52/go.mod h1:CYyNk1kPIEgZmc3Z16TmpS1l3KbkNSjyJk16KuQw+JM=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -145,8 +145,9 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
Expand Down
4 changes: 2 additions & 2 deletions pkg/connector/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (o *appResourceType) listAppGroupGrants(
qp := queryParams(token.Size, page)
applicationGroupAssignments, respCtx, err := listApplicationGroupAssignments(ctx, o.client, resource.Id.GetResource(), token, qp)
if err != nil {
return nil, nil, nil, fmt.Errorf("okta-connectorv2: failed to list group users: %w", err)
return nil, nil, bag, convertNotFoundError(err, "okta-connectorv2: failed to list group users")
}

nextPage, annos, err := parseResp(respCtx.OktaResponse)
Expand Down Expand Up @@ -204,7 +204,7 @@ func (o *appResourceType) listAppUsersGrants(
qp := queryParams(token.Size, page)
applicationUsers, respCtx, err := listApplicationUsers(ctx, o.client, resource.Id.GetResource(), token, qp)
if err != nil {
return nil, nil, nil, fmt.Errorf("okta-connectorv2: failed to list group users: %w", err)
return nil, nil, bag, convertNotFoundError(err, "okta-connectorv2: failed to list group users")
}

nextPage, annos, err := parseResp(respCtx.OktaResponse)
Expand Down
2 changes: 2 additions & 0 deletions pkg/connector/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
)

const awsApp = "amazon_aws"

// TODO: use isNotFoundError() since E0000008 is also a not found error
const ResourceNotFoundExceptionErrorCode = "E0000007"
const AccessDeniedErrorCode = "E0000006"
const ExpectedIdentityProviderArnRegexCaptureGroups = 2
Expand Down
4 changes: 2 additions & 2 deletions pkg/connector/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func (o *groupResourceType) Grants(

users, respCtx, err := o.listGroupUsers(ctx, groupID, token, qp)
if err != nil {
return nil, "", nil, fmt.Errorf("okta-connectorv2: failed to list group users: %w", err)
return nil, "", nil, convertNotFoundError(err, "okta-connectorv2: failed to list group users")
}

nextPage, annos, err := parseResp(respCtx.OktaResponse)
Expand Down Expand Up @@ -195,7 +195,7 @@ func (o *groupResourceType) Grants(
}
return nil, pageToken, nil, nil
} else {
return nil, "", nil, fmt.Errorf("okta-connectorv2: failed to list group roles: %v", errOkta)
return nil, "", nil, convertNotFoundError(&errOkta, "okta-connectorv2: failed to list group roles")
}
}

Expand Down
26 changes: 26 additions & 0 deletions pkg/connector/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,29 @@ func handleOktaResponseError(resp *okta.Response, err error) error {
}
return err
}

// https://developer.okta.com/docs/reference/error-codes/?q=not%20found
var oktaNotFoundErrors = map[string]struct{}{
"E0000007": {},
"E0000008": {},
}

func convertNotFoundError(err error, message string) error {
if err == nil {
return nil
}

var oktaApiError *okta.Error
if !errors.As(err, &oktaApiError) {
return err
}

_, ok := oktaNotFoundErrors[oktaApiError.ErrorCode]
if !ok {
return err
}

grpcErr := status.Error(codes.NotFound, message)
allErrs := append([]error{grpcErr}, err)
return errors.Join(allErrs...)
}
Loading

0 comments on commit 76de83d

Please sign in to comment.