generated from coulomb/repo-seed
81 lines
2.4 KiB
Go
81 lines
2.4 KiB
Go
package topaz
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/netkingdom/flex-auth/internal/policy"
|
|
)
|
|
|
|
// PolicyBundleFromPackage extracts the Rego module from a flex-auth
|
|
// Rego-in-Markdown package without translation.
|
|
func PolicyBundleFromPackage(pkg *policy.Package) PolicyBundle {
|
|
root := strings.ReplaceAll(pkg.Metadata.Package, ".", "/")
|
|
modulePath := filepath.ToSlash(filepath.Join("policy", root+".rego"))
|
|
return PolicyBundle{
|
|
ID: pkg.Metadata.ID,
|
|
Version: pkg.Metadata.Version,
|
|
Package: pkg.Metadata.Package,
|
|
Revision: pkg.Metadata.Version,
|
|
Roots: []string{root},
|
|
Modules: []PolicyModule{
|
|
{Path: modulePath, Source: pkg.RegoModule},
|
|
},
|
|
}
|
|
}
|
|
|
|
// FileBundleSink writes a Topaz-readable local OPA bundle directory.
|
|
type FileBundleSink struct {
|
|
Root string
|
|
}
|
|
|
|
// PutPolicyBundle writes .manifest and module files under Root.
|
|
func (s FileBundleSink) PutPolicyBundle(_ context.Context, bundle PolicyBundle) error {
|
|
if s.Root == "" {
|
|
return fmt.Errorf("bundle root is required")
|
|
}
|
|
if len(bundle.Modules) == 0 {
|
|
return fmt.Errorf("policy bundle %q contains no modules", bundle.ID)
|
|
}
|
|
if err := os.MkdirAll(s.Root, 0o755); err != nil {
|
|
return fmt.Errorf("create policy bundle root: %w", err)
|
|
}
|
|
|
|
manifest := struct {
|
|
Revision string `json:"revision,omitempty"`
|
|
Roots []string `json:"roots"`
|
|
}{
|
|
Revision: bundle.Revision,
|
|
Roots: append([]string(nil), bundle.Roots...),
|
|
}
|
|
manifestData, err := json.Marshal(manifest)
|
|
if err != nil {
|
|
return fmt.Errorf("marshal policy bundle manifest: %w", err)
|
|
}
|
|
manifestData = append(manifestData, '\n')
|
|
if err := os.WriteFile(filepath.Join(s.Root, ".manifest"), manifestData, 0o644); err != nil {
|
|
return fmt.Errorf("write policy bundle manifest: %w", err)
|
|
}
|
|
|
|
for _, module := range bundle.Modules {
|
|
if module.Path == "" {
|
|
return fmt.Errorf("policy bundle %q contains module with empty path", bundle.ID)
|
|
}
|
|
path := filepath.Clean(filepath.Join(s.Root, module.Path))
|
|
if !strings.HasPrefix(path, filepath.Clean(s.Root)+string(os.PathSeparator)) {
|
|
return fmt.Errorf("policy module path escapes bundle root: %s", module.Path)
|
|
}
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
return fmt.Errorf("create policy module directory: %w", err)
|
|
}
|
|
if err := os.WriteFile(path, []byte(module.Source), 0o644); err != nil {
|
|
return fmt.Errorf("write policy module %q: %w", module.Path, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|