Skip to content

Commit

Permalink
Merge pull request #11 from ConductorOne/jirwin/admin-app
Browse files Browse the repository at this point in the history
Administration Child App
  • Loading branch information
jirwin authored Sep 1, 2023
2 parents 4959f0e + ce3a2fa commit fe58ec9
Show file tree
Hide file tree
Showing 644 changed files with 91,491 additions and 1,794 deletions.
31 changes: 1 addition & 30 deletions cmd/baton-jumpcloud/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"github.com/conductorone/baton-jumpcloud/pkg/connector"
"github.com/conductorone/baton-sdk/pkg/cli"
"github.com/conductorone/baton-sdk/pkg/connectorbuilder"
"github.com/conductorone/baton-sdk/pkg/sdk"
"github.com/conductorone/baton-sdk/pkg/types"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
"go.uber.org/zap"
Expand All @@ -20,7 +19,7 @@ func main() {
ctx := context.Background()

cfg := &config{}
cmd, err := cli.NewCmd(ctx, "baton-jumpcloud", cfg, validateConfig, getConnector, run)
cmd, err := cli.NewCmd(ctx, "baton-jumpcloud", cfg, validateConfig, getConnector)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
Expand Down Expand Up @@ -54,31 +53,3 @@ func getConnector(ctx context.Context, cfg *config) (types.ConnectorServer, erro

return c, nil
}

// run is where the process of syncing with the connector is implemented.
func run(ctx context.Context, cfg *config) error {
l := ctxzap.Extract(ctx)

c, err := getConnector(ctx, cfg)
if err != nil {
l.Error("error creating connector", zap.Error(err))
return err
}

var opts []sdk.Option

r, err := sdk.NewConnectorRunner(ctx, c, cfg.C1zPath, opts...)
if err != nil {
l.Error("error creating connector runner", zap.Error(err))
return err
}
defer r.Close()

err = r.Run(ctx)
if err != nil {
l.Error("error running connector", zap.Error(err))
return err
}

return nil
}
22 changes: 19 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ module github.com/conductorone/baton-jumpcloud
go 1.20

require (
github.com/conductorone/baton-sdk v0.0.30
github.com/conductorone/baton-sdk v0.1.5
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.1
github.com/stretchr/testify v1.8.2
go.uber.org/zap v1.24.0
google.golang.org/protobuf v1.30.0
)
Expand Down Expand Up @@ -38,34 +38,50 @@ require (
github.com/envoyproxy/protoc-gen-validate v0.9.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/glebarez/go-sqlite v1.20.3 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/klauspost/compress v1.15.15 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/pquerna/xjwt v0.1.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/segmentio/ksuid v1.0.4 // indirect
github.com/shirou/gopsutil/v3 v3.23.3 // indirect
github.com/shoenig/go-m1cpu v0.1.4 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.15.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
go.uber.org/ratelimit v0.2.0 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/oauth2 v0.4.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230221151758-ace64dc21148 // indirect
google.golang.org/grpc v1.53.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/libc v1.22.2 // indirect
modernc.org/mathutil v1.5.0 // indirect
Expand Down
52 changes: 47 additions & 5 deletions go.sum

Large diffs are not rendered by default.

122 changes: 0 additions & 122 deletions pkg/connector/admin_users.go

This file was deleted.

71 changes: 68 additions & 3 deletions pkg/connector/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@ import (
v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2"
"github.com/conductorone/baton-sdk/pkg/annotations"
"github.com/conductorone/baton-sdk/pkg/pagination"
sdkResources "github.com/conductorone/baton-sdk/pkg/types/resource"
)

const (
apiUserType = "user"
apiUserGroupType = "user_group"
adminAppID = "2UjI0eIRo77RGFwi2GKpAa0Til0"
)

type appResourceType struct {
resourceType *v2.ResourceType
client1 jc1Func
client2 jc2Func
ext *ExtensionClient
}

func (o *appResourceType) ResourceType(_ context.Context) *v2.ResourceType {
Expand All @@ -34,6 +37,17 @@ func (o *appResourceType) List(
resourceID *v2.ResourceId,
token *pagination.Token,
) ([]*v2.Resource, string, annotations.Annotations, error) {
var rv []*v2.Resource

// If this is the first call to List, we need to create the JumpCloud Administration app
if token.Token == "" {
adminApp, err := sdkResources.NewAppResource("JumpCloud Administration", resourceTypeApp, adminAppID, nil)
if err != nil {
return nil, "", nil, err
}
rv = append(rv, adminApp)
}

ctx, client := o.client1(ctx)

skip, b, err := unmarshalSkipToken(token)
Expand All @@ -47,7 +61,6 @@ func (o *appResourceType) List(
}
defer resp.Body.Close()

var rv []*v2.Resource
for i := range apps.Results {
ur, err := appResource(ctx, &apps.Results[i])
if err != nil {
Expand Down Expand Up @@ -114,21 +127,72 @@ func appEntitlement(ctx context.Context, resource *v2.Resource) *v2.Entitlement
Description: fmt.Sprintf("Assigned to %s app", resource.DisplayName),
GrantableTo: []*v2.ResourceType{resourceTypeUser},
Purpose: v2.Entitlement_PURPOSE_VALUE_ASSIGNMENT,
Slug: resource.DisplayName,
Slug: "access",
}
}

type graphRequest interface {
Execute() ([]jcapi2.GraphConnection, *http.Response, error)
}

func (o *appResourceType) adminGrants(ctx context.Context, resource *v2.Resource, pt *pagination.Token) ([]*v2.Grant, string, annotations.Annotations, error) {
skip, b, err := unmarshalSkipToken(pt)
if err != nil {
return nil, "", nil, err
}

appID := resource.Id.GetResource()

users, resp, err := o.ext.UserList().Skip(skip).Execute(ctx)
if err != nil {
return nil, "", nil, err
}
defer resp.Body.Close()

ctx, client := o.client1(ctx)

var rv []*v2.Grant
for _, u := range users {
user, err := fetchUserByEmail(ctx, client, u.GetEmail())
if err != nil {
return nil, "", nil, err
}

ur := &v2.Resource{Id: &v2.ResourceId{
ResourceType: resourceTypeUser.Id,
Resource: user.GetId(),
},
}

rv = append(rv, &v2.Grant{
Id: fmtResourceGrant(resource.Id, ur.Id, appID),
Entitlement: &v2.Entitlement{
Id: fmtResource(resource.Id, appID),
Resource: resource,
},
Principal: ur,
})
}

pageToken, err := marshalSkipToken(len(users), skip, b)
if err != nil {
return nil, "", nil, err
}

return rv, pageToken, nil, nil
}

func (o *appResourceType) Grants(
ctx context.Context,
resource *v2.Resource,
token *pagination.Token,
) ([]*v2.Grant, string, annotations.Annotations, error) {
ctx, client := o.client2(ctx)

if resource.Id.Resource == adminAppID {
return o.adminGrants(ctx, resource, token)
}

b := pagination.Bag{}
if token.Token == "" {
b.Push(pagination.PageState{
Expand Down Expand Up @@ -231,10 +295,11 @@ func appGrant(resource *v2.Resource, resoureTypeId string, member *jcapi2.GraphC
}
}

func newAppBuilder(jc1 jc1Func, jc2 jc2Func) *appResourceType {
func newAppBuilder(jc1 jc1Func, jc2 jc2Func, ext *ExtensionClient) *appResourceType {
return &appResourceType{
resourceType: resourceTypeApp,
client1: jc1,
client2: jc2,
ext: ext,
}
}
11 changes: 2 additions & 9 deletions pkg/connector/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,6 @@ var (
Traits: []v2.ResourceType_Trait{v2.ResourceType_TRAIT_USER},
Description: "JumpCloud User: The User account is the core identity for your employees, and is the account type that is used to authenticate resources agains",
}
resourceTypeAdminUser = &v2.ResourceType{
Id: "admin_user",
DisplayName: "Admin User",
Traits: []v2.ResourceType_Trait{v2.ResourceType_TRAIT_USER},
Description: "JumpCloud Administrator: The JumpCloud administrator account is responsible for the management of your JumpCloud organizational tenan",
}
resourceTypeGroup = &v2.ResourceType{
Id: "group",
DisplayName: "Group",
Expand Down Expand Up @@ -136,8 +130,7 @@ func (s *Jumpcloud) ResourceSyncers(ctx context.Context) []connectorbuilder.Reso
// https://support.jumpcloud.com/support/s/article/getting-started-jumpcloud-admin-accounts-vs-user-accounts-2019-08-21-10-36-47
newUserBuilder(s.client1, s.client2),
newGroupBuilder(s.client1, s.client2),
newAdminUserBuilder(s.ext),
newRoleBuilder(s.ext),
newAppBuilder(s.client1, s.client2),
newRoleBuilder(s.client1, s.ext),
newAppBuilder(s.client1, s.client2, s.ext),
}
}
Loading

0 comments on commit fe58ec9

Please sign in to comment.