Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
68ecabf
add biscuit wrappers and helpers to generate, sign and verify hubauth…
daeMOn63 Oct 8, 2020
4db21fa
add biscuit metadata and expiration date
daeMOn63 Oct 12, 2020
fac0ee4
cleanup
daeMOn63 Oct 13, 2020
b4faed8
moved biscuit pkg to biscuit-go repo
daeMOn63 Oct 15, 2020
3bae14b
audience policies migration step1
daeMOn63 Dec 14, 2020
09d999f
add biscuit wrappers and helpers to generate, sign and verify hubauth…
daeMOn63 Oct 8, 2020
969a305
add biscuit metadata and expiration date
daeMOn63 Oct 12, 2020
db630ec
cleanup
daeMOn63 Oct 13, 2020
3067b97
moved biscuit pkg to biscuit-go repo
daeMOn63 Oct 15, 2020
b491717
lint fix
daeMOn63 Dec 10, 2020
12c39aa
add policy parser and printer
daeMOn63 Dec 10, 2020
6a70d95
use newest biscuit cookbook
daeMOn63 Dec 10, 2020
5a5dbce
add biscuit policy store
daeMOn63 Dec 10, 2020
76334e2
add policy cli commands
daeMOn63 Dec 10, 2020
f0762f7
bump biscuit to tmp version
daeMOn63 Dec 10, 2020
4c2850e
wip: wait for audience updates
daeMOn63 Dec 11, 2020
2038a0c
datastore: add audience policy support
daeMOn63 Dec 15, 2020
2bfb08a
policy: add parser test for empty policies
daeMOn63 Dec 15, 2020
5f0c2ad
cli: add audiences policies commands
daeMOn63 Dec 16, 2020
7f0f2c2
idp: add policy support to issued biscuits
daeMOn63 Dec 16, 2020
c01bfcd
fix bad rebase
daeMOn63 Dec 16, 2020
af77044
bump biscuit version, remove replace directive
daeMOn63 Dec 16, 2020
4ebd620
remove spurious newline
daeMOn63 Dec 17, 2020
e93c2d9
fix cancelled context when building access token
daeMOn63 Dec 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/hubauth-ext/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func main() {
}

rootPubKey = biscuitKey.Public().Bytes()
accessTokenBuilder = token.NewBiscuitBuilder(kmsClient, audienceKeyNamer, biscuitKey)
accessTokenBuilder = token.NewBiscuitBuilder(kmsClient, datastore.New(dsClient), audienceKeyNamer, biscuitKey)
default:
log.Fatalf("invalid TOKEN_TYPE, must be one of: Bearer, Biscuit")
}
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ require (
cloud.google.com/go/datastore v1.3.0
contrib.go.opencensus.io/exporter/stackdriver v0.13.4
github.com/alecthomas/kong v0.2.12
github.com/alecthomas/participle/v2 v2.0.0-alpha3.0.20201208114601-14bec2482095
github.com/aws/aws-sdk-go v1.36.7 // indirect
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
github.com/flynn/biscuit-go v0.0.0-20201009174859-e7eb59a90195
github.com/flynn/biscuit-go v0.0.0-20201211135022-dbd2f8863bf4
github.com/golang/protobuf v1.4.3
github.com/googleapis/gax-go/v2 v2.0.5
github.com/jedib0t/go-pretty/v6 v6.0.5
Expand Down
14 changes: 11 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/alecthomas/kong v0.2.12 h1:X3kkCOXGUNzLmiu+nQtoxWqj4U2a39MpSJR3QdQXOwI=
github.com/alecthomas/kong v0.2.12/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE=
github.com/alecthomas/participle v0.6.0/go.mod h1:HfdmEuwvr12HXQN44HPWXR0lHmVolVYe4dyL6lQ3duY=
github.com/alecthomas/participle/v2 v2.0.0-alpha3.0.20201208114601-14bec2482095 h1:DCGcCFtR/4YWEOoszqekJRdDoq41G+btPdOSWf5FoSo=
github.com/alecthomas/participle/v2 v2.0.0-alpha3.0.20201208114601-14bec2482095/go.mod h1:Z1zPLDbcGsVsBYsThKXY00i84575bN/nMczzIrU4rWU=
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 h1:GDQdwm/gAcJcLAKQQZGOJ4knlw+7rfEQQcmwTbt4p5E=
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
github.com/aws/aws-sdk-go v1.23.20 h1:2CBuL21P0yKdZN5urf2NxKa1ha8fhnY+A3pBCHFeZoA=
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
Expand All @@ -77,9 +79,11 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/flynn/biscuit-go v0.0.0-20201015081742-15d7d351f345 h1:ME6bm5dwn9V2DUlfXJqeN121B5nM7rDFqLFOATALqYE=
github.com/flynn/biscuit-go v0.0.0-20201015081742-15d7d351f345/go.mod h1:Sj4oR2hNkrZH1cf3Cj5DPHc3Xq0o61GWeau6UkZR+3c=
github.com/flynn/biscuit-go v0.0.0-20201211135022-dbd2f8863bf4 h1:5TqasLkkptxZIP8TNawz76F+vMSf04Mab8/d8VdJWus=
github.com/flynn/biscuit-go v0.0.0-20201211135022-dbd2f8863bf4/go.mod h1:mY0paJD7nJ1hsxNzqHOKES2u+asFldh25X8WkveoMaw=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
Expand Down Expand Up @@ -291,6 +295,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -324,6 +329,7 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201214095126-aec9a390925b h1:tv7/y4pd+sR8bcNb2D6o7BNU6zjWm0VjQLac+w7fNNM=
golang.org/x/sys v0.0.0-20201214095126-aec9a390925b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down Expand Up @@ -386,6 +392,7 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u
golang.org/x/tools v0.0.0-20200916150407-587cf2330ce8/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2 h1:vEtypaVub6UvKkiXZ2xx9QIvp9TL7sI7xp7vdi2kezA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58 h1:1Bs6RVeBFtLZ8Yi1Hk07DiOqzvwLD/4hln4iahvFlag=
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
Expand Down Expand Up @@ -457,6 +464,7 @@ google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200916143405-f6a2fa72f0c4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc h1:BgQmMjmd7K1zov8j8lYULHW0WnmBGUIMp6+VDwlGErc=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201211151036-40ec1c210f7a h1:GnJAhasbD8HiT8DZMvsEx3QLVy/X0icq/MGr0MqRJ2M=
google.golang.org/genproto v0.0.0-20201211151036-40ec1c210f7a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
Expand Down
286 changes: 280 additions & 6 deletions pkg/cli/audiences.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,39 @@ import (
"encoding/base64"
"encoding/pem"
"fmt"
"io/ioutil"
"net/url"
"os"
"strings"

"github.com/flynn/hubauth/pkg/hubauth"
"github.com/flynn/hubauth/pkg/policy"
"github.com/jedib0t/go-pretty/v6/table"
"google.golang.org/genproto/googleapis/cloud/kms/v1"
)

type audiencesCmd struct {
List audiencesListCmd `kong:"cmd,help='list audiences',default:'1'"`
Create audiencesCreateCmd `kong:"cmd,help='create audience'"`
UpdateType audienceUpdateTypeCmd `kong:"cmd,name='update-type',help='change audience type'"`
UpdateClientIDs audiencesUpdateClientsIDsCmd `kong:"cmd,name='update-client-ids',help='add or remove audience client IDs'"`
Delete audiencesDeleteCmd `kong:"cmd,help='delete audience and all its keys'"`
List audiencesListCmd `kong:"cmd,help='list audiences',default:'1'"`
Create audiencesCreateCmd `kong:"cmd,help='create audience'"`
UpdateType audienceUpdateTypeCmd `kong:"cmd,name='update-type',help='change audience type'"`
UpdateClientIDs audiencesUpdateClientsIDsCmd `kong:"cmd,name='update-client-ids',help='add or remove audience client IDs'"`
Delete audiencesDeleteCmd `kong:"cmd,help='delete audience and all its keys'"`

ListUserGroups audiencesListUserGroupsCmd `kong:"cmd,name='list-user-groups',help='list audience user groups'"`
SetUserGroups audiencesSetUserGroupsCmd `kong:"cmd,name='set-user-groups',help='set audience auth user groups'"`
UpdateUserGroups audiencesUpdateUserGroupsCmd `kong:"cmd,name='update-user-groups',help='modify audience user groups api user or groups'"`
DeleteUserGroups audiencesDeleteUserGroupsCmd `kong:"cmd,name='delete-user-groups',help='delete audience auth user groups'"`
Key audiencesKeyCmd `kong:"cmd,help='get audience public key'"`

Key audiencesKeyCmd `kong:"cmd,help='get audience public key'"`

ListPolicies audiencesListPoliciesCmd `kong:"cmd,name='list-policies',help='list audience policies'"`
DumpPolicies audiencesDumpPoliciesCmd `kong:"cmd,name='dump-policies',help='dump audience policies'"`
SetPolicies audiencesSetPoliciesCmd `kong:"cmd,name='set-policies',help='set audience policies'"`
UpdatePolicy audiencesUpdatePolicyCmd `kong:"cmd,name='update-policy',help='modify audience policy content or groups'"`
DeletePolicy audiencesDeletePolicyCmd `kong:"cmd,name='delete-policy',help='delete audience policy'"`

NewPolicy audiencesNewPolicyCmd `kong:"cmd,name='new-policy',help='print a new empty policy document on stdout'"`
ValidatePolicies audiencesValidatePoliciesCmd `kong:"cmd,name='validate-policies',help='validate a policy file'"`
}

type audiencesListCmd struct{}
Expand Down Expand Up @@ -285,3 +298,264 @@ func (c *audiencesKeyCmd) Run(cfg *Config) error {
fmt.Println(base64.URLEncoding.EncodeToString(b.Bytes))
return nil
}

type audiencesListPoliciesCmd struct {
AudienceURL string `kong:"required,name='audience-url',help='audience URL'"`
}

func (c *audiencesListPoliciesCmd) Run(cfg *Config) error {
audience, err := cfg.DB.GetAudience(context.Background(), c.AudienceURL)
if err != nil {
return err
}

t := table.NewWriter()
t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{"Name", "Groups", "Description"})
for _, p := range audience.Policies {
t.AppendRow(table.Row{p.Name, p.Groups, getFirstComment(p)})
}
t.Render()
return nil
}

// getFirstComment parse the policy content and returns the first policy
// comment line if it exists. On failure to parse the policy content, or when unset, an empty string is returned.
func getFirstComment(p *hubauth.BiscuitPolicy) string {
doc, err := policy.ParseDocumentPolicy(strings.NewReader(p.Content))
if err != nil {
return ""
}
if len(doc.Comments) == 0 {
return ""
}
return string(*doc.Comments[0])
}

type audiencesSetPoliciesCmd struct {
AudienceURL string `kong:"required,name='audience-url',help='audience URL'"`
Filepath string `kong:"required,name='filepath',help='policy file'"`
Groups []string `kong:"help='comma-separated group IDs'"`
}

// Run parses Filepath for a list of policies, and creates or updates them on the audience identified by AudienceURL,
// forcing their groups to the provided Groups.
func (c *audiencesSetPoliciesCmd) Run(cfg *Config) error {
f, err := os.Open(c.Filepath)
if err != nil {
return err
}

doc, err := policy.ParseNamed(f.Name(), f)
if err != nil {
return err
}

muts := make([]*hubauth.AudienceMutation, len(doc.Policies))
for i, p := range doc.Policies {
muts[i] = &hubauth.AudienceMutation{
Op: hubauth.AudienceMutationSetPolicy,
Policy: hubauth.BiscuitPolicy{
Name: *p.Name,
Content: policy.PrintPolicy(p),
Groups: c.Groups,
},
}
}

return cfg.DB.MutateAudience(context.Background(), c.AudienceURL, muts)
}

type audiencesUpdatePolicyCmd struct {
AudienceURL string `kong:"required,name='audience-url',help='audience URL'"`
PolicyName string `kong:"required,help='policy name'"`
Filepath string `kong:"name='filepath',help='replace policy content from a file'"`
AddGroups []string `kong:"name='add-groups',help='comma-separated group IDs to add'"`
DeleteGroups []string `kong:"name='delete-groups',help='comma-separated group IDs to delete'"`
}

func (c *audiencesUpdatePolicyCmd) Run(cfg *Config) error {
var muts []*hubauth.AudiencePolicyMutation
for _, groupID := range c.AddGroups {
muts = append(muts, &hubauth.AudiencePolicyMutation{
Op: hubauth.AudiencePolicyMutationOpAddGroup,
Group: groupID,
})
}
for _, groupID := range c.DeleteGroups {
muts = append(muts, &hubauth.AudiencePolicyMutation{
Op: hubauth.AudiencePolicyMutationOpDeleteGroup,
Group: groupID,
})
}
if c.Filepath != "" {
doc, err := parsePolicy(c.Filepath)
if err != nil {
return err
}

var mutatedPolicy *policy.DocumentPolicy
for _, p := range doc.Policies {
if *p.Name == c.PolicyName {
mutatedPolicy = p
break
}
}
if mutatedPolicy == nil {
return fmt.Errorf("policy %q not found in file %q", c.PolicyName, c.Filepath)
}

muts = append(muts, &hubauth.AudiencePolicyMutation{
Op: hubauth.AudiencePolicyMutationOpSetContent,
Content: policy.PrintPolicy(mutatedPolicy),
})
}

return cfg.DB.MutateAudiencePolicy(context.Background(), c.AudienceURL, c.PolicyName, muts)
}

type audiencesDeletePolicyCmd struct {
AudienceURL string `kong:"required,name='audience-url',help='audience URL'"`
PolicyName string `kong:"required,help='policy name'"`
}

func (c *audiencesDeletePolicyCmd) Run(cfg *Config) error {
mut := &hubauth.AudienceMutation{
Op: hubauth.AudienceMutationDeletePolicy,
Policy: hubauth.BiscuitPolicy{
Name: c.PolicyName,
},
}
return cfg.DB.MutateAudience(context.Background(), c.AudienceURL, []*hubauth.AudienceMutation{mut})
}

type audiencesNewPolicyCmd struct {
Filepath string `kong:"name='filepath',short='f',help='optionnal filepath where to write the policy (default: stdout)'"`
}

var policyTemplate string = `// this is a template policy
policy "dummy" {
rules {
// this is a dummy rule
*head($var1)
<- body1(#ambient, $name),
body2($value)
@ $name == "example"
}

caveats {[
// this is a dummy caveat
*head($var1)
<- body1(#ambient, $name),
body2($value)
@ $name == "example"
]}
}`

func (c *audiencesNewPolicyCmd) Run(cfg *Config) error {
d, err := policy.Parse(strings.NewReader(policyTemplate))
if err != nil {
return err
}

out, err := policy.Print(d)
if err != nil {
return err
}

if c.Filepath != "" {
ioutil.WriteFile(c.Filepath, []byte(out), 0644)
fmt.Printf("written %s\n", c.Filepath)
return nil
}

fmt.Print(out)
return nil
}

type audiencesValidatePoliciesCmd struct {
Filepath string `kong:"required,name='filepath',short='f',help='a file containing policy definitions'"`
}

func (c *audiencesValidatePoliciesCmd) Run(cfg *Config) error {
f, err := os.Open(c.Filepath)
if err != nil {
return err
}

_, err = policy.ParseNamed(f.Name(), f)
if err != nil {
return err
}

return nil
}

type audiencesDumpPoliciesCmd struct {
AudienceURL string `kong:"required,name='audience-url',help='audience URL'"`
PolicyNames []string `kong:"name='policy-names',help='comma separated policy names to dump (default: all)'"`
Filepath string `kong:"name='filepath',short='f',help='optionnal filepath where to write the policies (default: stdout)'"`
}

func (c *audiencesDumpPoliciesCmd) Run(cfg *Config) error {
aud, err := cfg.DB.GetAudience(context.Background(), c.AudienceURL)
if err != nil {
return err
}

if len(aud.Policies) == 0 {
return fmt.Errorf("audience %s have no policy", c.AudienceURL)
}

dumpPolicies := aud.Policies
if len(c.PolicyNames) > 0 {
dumpPolicies = make([]*hubauth.BiscuitPolicy, 0, len(c.PolicyNames))
for _, p := range aud.Policies {
for _, name := range c.PolicyNames {
if name == p.Name {
dumpPolicies = append(dumpPolicies, p)
break
}
}
}
}

aggContent := ""
for _, p := range dumpPolicies {
aggContent += p.Content
}

doc, err := policy.Parse(strings.NewReader(aggContent))
if err != nil {
return err
}

out, err := policy.Print(doc)
if err != nil {
return err
}

if c.Filepath != "" {
ioutil.WriteFile(c.Filepath, []byte(out), 0644)
fmt.Printf("written %d policies to %s\n", len(dumpPolicies), c.Filepath)
return nil
}

fmt.Printf("%s", out)
return nil
}

func parsePolicy(path string) (*policy.Document, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()

doc, err := policy.ParseNamed(f.Name(), f)
if err != nil {
return nil, err
}

return doc, nil
}
Loading