diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 363a01b..6a49c11 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -29,7 +29,7 @@ builds: ldflags: - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} archives: - - format: tar.gz + - formats: ['tar.gz'] name_template: >- {{ .ProjectName }}_ {{- title .Os }}_ @@ -40,7 +40,7 @@ archives: # use zip for windows archives format_overrides: - goos: windows - format: zip + formats: ['zip'] files: - README.md - LICENSE diff --git a/cmd/workos/schema.txt b/cmd/workos/schema.txt new file mode 100644 index 0000000..267e766 --- /dev/null +++ b/cmd/workos/schema.txt @@ -0,0 +1,78 @@ +version 0.3 + +type team + relation admin [dashboard_user] + relation developer [dashboard_user] + relation reader [] + relation support [dashboard_user] + relation writer [] + + inherit reader if + any_of + relation admin + relation developer + relation support + + inherit writer if + relation admin + +type plan + relation subscriber [organization] + + inherit subscriber if + relation reader on subscriber [organization] + +type organization + relation parent_environment [environment] + relation reader [] + relation writer [] + + inherit reader if + any_of + relation reader on parent_environment [environment] + relation writer + + inherit writer if + relation writer on parent_environment [environment] + +type feature + relation has_feature [] + relation plan [plan] + + inherit has_feature if + all_of + relation subscriber on plan [plan] + policy is_below_collaborator_limit + policy is_below_row_sync_limit + policy is_below_page_history_days_limit + +type environment + relation parent_team [team] + relation reader [dashboard_user, api_key] + relation writer [dashboard_user, api_key] + + inherit reader if + any_of + relation reader on parent_team [team] + relation writer + + inherit writer if + relation writer on parent_team [team] + +type dashboard_user + +type api_key + +policy is_below_collaborator_limit(collaborator_count integer, collaborator_limit integer) { + collaborator_count <= collaborator_limit +} + +policy is_below_page_history_days_limit(page_history_days_count integer, page_history_days_limit integer) { + page_history_days_count <= page_history_days_limit +} + +policy is_below_row_sync_limit(row_sync_count integer, row_sync_limit integer) { + row_sync_count <= row_sync_limit +} + + diff --git a/go.mod b/go.mod index 3294eb9..6608a01 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 - github.com/workos/workos-go/v4 v4.21.0 + github.com/workos/workos-go/v4 v4.33.0 ) require ( diff --git a/go.sum b/go.sum index 9f56534..e95b033 100644 --- a/go.sum +++ b/go.sum @@ -113,8 +113,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/workos/workos-go/v4 v4.21.0 h1:pEoAJzCsBPU46dL6/PwwwS5BrBV8LWOZQp0mERrRPCc= -github.com/workos/workos-go/v4 v4.21.0/go.mod h1:CwpXdAWhIE3SxV49qBVeYqWV8ojv0A0L9nM1xnho4/c= +github.com/workos/workos-go/v4 v4.33.0 h1:6dQvjd4WUYBSAUvCP7QLC7VYDX+ehAzSMg/TgjxRrQA= +github.com/workos/workos-go/v4 v4.33.0/go.mod h1:CwpXdAWhIE3SxV49qBVeYqWV8ojv0A0L9nM1xnho4/c= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= diff --git a/internal/cmd/fga.go b/internal/cmd/fga.go index 2b8f344..54cc5b9 100644 --- a/internal/cmd/fga.go +++ b/internal/cmd/fga.go @@ -70,6 +70,7 @@ func init() { convertSchemaCMD.Flags().String("to", "json", "output to (schema or json)") convertSchemaCMD.Flags().String("output", "pretty", "output pretty or raw. use raw for machine-readable output or writing to a file") schemaCmd.AddCommand(convertSchemaCMD) + schemaCmd.AddCommand(getSchemaCmd) applySchemaCmd.Flags().BoolP("verbose", "v", false, "print extra details about the request") applySchemaCmd.Flags().Bool("strict", false, "fail if there are warnings") schemaCmd.AddCommand(applySchemaCmd) @@ -689,6 +690,12 @@ var convertSchemaCMD = &cobra.Command{ printer.PrintMsg("Resource Types:") printer.PrintJson(response.ResourceTypes) } + if response.Policies != nil { + printer.PrintMsg("Policies:") + for key, policy := range response.Policies { + printer.PrintMsg(fmt.Sprintf("%s: %s", key, policy)) + } + } case "raw": if response.Schema != nil { printer.PrintMsg(*response.Schema) @@ -702,6 +709,31 @@ var convertSchemaCMD = &cobra.Command{ }, } +var getSchemaCmd = &cobra.Command{ + Use: "get", + Short: "Get the current schema", + Long: "Get the current schema, which includes the version, resource types, and policies.", + Example: `workos fga schema get`, + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + response, err := fga.GetSchema(context.Background()) + if err != nil { + return errors.Errorf("error getting schema: %v", err) + } + convertResponse, err := fga.ConvertResourceTypesToSchema(context.Background(), fga.ConvertResourceTypesToSchemaOpts(response)) + if err != nil { + return convertSchemaError(err) + } + + if convertResponse.Schema != nil { + printer.PrintMsg(*convertResponse.Schema) + } else { + return errors.New("error getting schema: no schema found") + } + return nil + }, +} + var applySchemaCmd = &cobra.Command{ Use: "apply ", Short: "Apply a schema", @@ -747,12 +779,17 @@ var applySchemaCmd = &cobra.Command{ printer.PrintJson(response.ResourceTypes) } - ops := make([]fga.UpdateResourceTypeOpts, 0) + resourceTypeOps := make([]fga.UpdateResourceTypeOpts, 0) for _, rt := range response.ResourceTypes { - ops = append(ops, fga.UpdateResourceTypeOpts(rt)) + resourceTypeOps = append(resourceTypeOps, fga.UpdateResourceTypeOpts(rt)) + } + + policyOps := make(map[string]fga.UpdatePolicyOpts, len(response.Policies)) + for key, p := range response.Policies { + policyOps[key] = fga.UpdatePolicyOpts(p) } - _, err = fga.BatchUpdateResourceTypes(context.Background(), ops) + _, err = fga.UpdateSchema(context.Background(), fga.UpdateSchemaOpts{ResourceTypes: resourceTypeOps, Policies: policyOps}) if err != nil { return errors.Errorf("error applying schema: %v", err) }