mirror of
https://github.com/SigNoz/signoz.git
synced 2026-06-25 09:30:31 +01:00
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix(authz): add attach detach permissions on metaresource * fix(authz): add role CRUD permissions * feat(authz): add support for supported verbs per metaresource * feat(authz): fix formatting for generated files * feat(authz): fix formatting for generated files * feat(authz): fix formatting for generated files * feat(authz): remove frontend changes * feat(authz): fix jest test
159 lines
4.2 KiB
Go
159 lines
4.2 KiB
Go
package cmd
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"os"
|
|
"sort"
|
|
"strings"
|
|
"text/template"
|
|
|
|
"github.com/SigNoz/signoz/pkg/types/coretypes"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
const permissionsTypePath = "frontend/src/hooks/useAuthZ/permissions.type.ts"
|
|
|
|
var permissionsTypeTemplate = template.Must(template.New("permissions").Parse(
|
|
`// AUTO GENERATED FILE - DO NOT EDIT - GENERATED BY cmd/enterprise/*.go generate authz
|
|
export default {
|
|
status: 'success',
|
|
data: {
|
|
resources: [
|
|
{{- range .Resources }}
|
|
{
|
|
kind: '{{ .Kind }}',
|
|
type: '{{ .Type }}',
|
|
{{ .FormattedAllowedVerbs }}
|
|
},
|
|
{{- end }}
|
|
],
|
|
relations: {
|
|
{{- range .Relations }}
|
|
{{ .Verb }}: [{{ range $i, $t := .Types }}{{ if $i }}, {{ end }}'{{ $t }}'{{ end }}],
|
|
{{- end }}
|
|
},
|
|
},
|
|
} as const;
|
|
`))
|
|
|
|
type permissionsTypeRelation struct {
|
|
Verb string
|
|
Types []string
|
|
}
|
|
|
|
type permissionsTypeResource struct {
|
|
Kind string
|
|
Type string
|
|
FormattedAllowedVerbs string
|
|
}
|
|
|
|
type permissionsTypeData struct {
|
|
Resources []permissionsTypeResource
|
|
Relations []permissionsTypeRelation
|
|
}
|
|
|
|
// formatAllowedVerbs returns a prettier-compatible formatted allowedVerbs line.
|
|
// indentLevel is the number of tabs for the property (matching kind/type indent).
|
|
// printWidth is prettier's printWidth; tabWidth is assumed to be 1 (each \t = 1 char).
|
|
func formatAllowedVerbs(verbs []string, indentLevel int, printWidth int) string {
|
|
quoted := make([]string, len(verbs))
|
|
for i, v := range verbs {
|
|
quoted[i] = "'" + v + "'"
|
|
}
|
|
indent := strings.Repeat("\t", indentLevel)
|
|
|
|
oneLine := indent + "allowedVerbs: [" + strings.Join(quoted, ", ") + "],"
|
|
if len(oneLine) <= printWidth {
|
|
return oneLine
|
|
}
|
|
|
|
var b strings.Builder
|
|
b.WriteString(indent + "allowedVerbs: [\n")
|
|
for _, q := range quoted {
|
|
b.WriteString(indent + "\t" + q + ",\n")
|
|
}
|
|
b.WriteString(indent + "],")
|
|
return b.String()
|
|
}
|
|
|
|
func registerGenerateAuthz(parentCmd *cobra.Command) {
|
|
authzCmd := &cobra.Command{
|
|
Use: "authz",
|
|
Short: "Generate authz permissions for the frontend",
|
|
RunE: func(currCmd *cobra.Command, args []string) error {
|
|
return runGenerateAuthz(currCmd.Context())
|
|
},
|
|
}
|
|
|
|
parentCmd.AddCommand(authzCmd)
|
|
}
|
|
|
|
func runGenerateAuthz(_ context.Context) error {
|
|
registry := coretypes.NewRegistry()
|
|
|
|
allowedResources := map[string]bool{
|
|
coretypes.NewResourceRef(coretypes.ResourceServiceAccount).String(): true,
|
|
coretypes.NewResourceRef(coretypes.ResourceRole).String(): true,
|
|
coretypes.NewResourceRef(coretypes.ResourceMetaResourceFactorAPIKey).String(): true,
|
|
}
|
|
|
|
allowedTypes := map[string]bool{}
|
|
|
|
refs := registry.ResourceRefs()
|
|
resources := make([]permissionsTypeResource, 0, len(refs))
|
|
for _, ref := range refs {
|
|
if !allowedResources[ref.String()] {
|
|
continue
|
|
}
|
|
allowedTypes[ref.Type.StringValue()] = true
|
|
|
|
resource, err := coretypes.NewResourceFromTypeAndKind(ref.Type, ref.Kind)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
verbs := resource.AllowedVerbs()
|
|
allowedVerbStrings := make([]string, 0, len(verbs))
|
|
for _, verb := range verbs {
|
|
allowedVerbStrings = append(allowedVerbStrings, verb.StringValue())
|
|
}
|
|
sort.Strings(allowedVerbStrings)
|
|
|
|
resources = append(resources, permissionsTypeResource{
|
|
Kind: ref.Kind.String(),
|
|
Type: ref.Type.StringValue(),
|
|
FormattedAllowedVerbs: formatAllowedVerbs(allowedVerbStrings, 4, 80),
|
|
})
|
|
}
|
|
|
|
typesByVerb := registry.TypesByVerb()
|
|
verbs := make([]coretypes.Verb, 0, len(typesByVerb))
|
|
for verb := range typesByVerb {
|
|
verbs = append(verbs, verb)
|
|
}
|
|
sort.Slice(verbs, func(i, j int) bool { return verbs[i].StringValue() < verbs[j].StringValue() })
|
|
|
|
relations := make([]permissionsTypeRelation, 0, len(verbs))
|
|
for _, verb := range verbs {
|
|
types := make([]string, 0, len(typesByVerb[verb]))
|
|
for _, t := range typesByVerb[verb] {
|
|
if !allowedTypes[t.StringValue()] {
|
|
continue
|
|
}
|
|
types = append(types, t.StringValue())
|
|
}
|
|
relations = append(relations, permissionsTypeRelation{
|
|
Verb: verb.StringValue(),
|
|
Types: types,
|
|
})
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
if err := permissionsTypeTemplate.Execute(&buf, permissionsTypeData{Resources: resources, Relations: relations}); err != nil {
|
|
return err
|
|
}
|
|
|
|
return os.WriteFile(permissionsTypePath, buf.Bytes(), 0o600)
|
|
}
|