Skip to content
This repository was archived by the owner on Feb 16, 2023. It is now read-only.

Commit 7cc6b42

Browse files
Merge pull request #221 from secrethub/release/v0.32.0
Release v0.32.0
2 parents db78e76 + 796ac79 commit 7cc6b42

9 files changed

Lines changed: 327 additions & 244 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ require (
1616
github.com/mitchellh/mapstructure v1.1.2
1717
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
1818
github.com/secrethub/demo-app v0.1.0
19-
github.com/secrethub/secrethub-go v0.23.0
19+
github.com/secrethub/secrethub-go v0.24.0
2020
github.com/zalando/go-keyring v0.0.0-20190208082241-fbe81aec3a07
2121
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a
2222
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ github.com/secrethub/secrethub-go v0.21.0 h1:5xbC+gdku7MXUQmlP5SPhAPLF+/U31soLKb
8585
github.com/secrethub/secrethub-go v0.21.0/go.mod h1:rc2IfKKBJ4L0wGec0u4XnF5/pe0FFPE4Q1MWfrFso7s=
8686
github.com/secrethub/secrethub-go v0.23.0 h1:6NzVGcAJDXeORUc2uZyuaYRCXCawmOKYvhNPP3ASNSM=
8787
github.com/secrethub/secrethub-go v0.23.0/go.mod h1:rc2IfKKBJ4L0wGec0u4XnF5/pe0FFPE4Q1MWfrFso7s=
88+
github.com/secrethub/secrethub-go v0.23.1-0.20191120150410-759ed0ccde7e h1:9FjAfwJiwGWGo7I0LbQ7CTS2qvjpaI5DTeZVIWisGBQ=
89+
github.com/secrethub/secrethub-go v0.23.1-0.20191120150410-759ed0ccde7e/go.mod h1:rc2IfKKBJ4L0wGec0u4XnF5/pe0FFPE4Q1MWfrFso7s=
90+
github.com/secrethub/secrethub-go v0.23.1-0.20191126142216-0736401365d7 h1:GH23+Ig/6Gsqyat8FQ06bMUVJvy1tisKuWhj22oS344=
91+
github.com/secrethub/secrethub-go v0.23.1-0.20191126142216-0736401365d7/go.mod h1:rc2IfKKBJ4L0wGec0u4XnF5/pe0FFPE4Q1MWfrFso7s=
92+
github.com/secrethub/secrethub-go v0.23.1-0.20191126145052-23fd5b7a4363 h1:0lHIjcVCBFrlpKv6Ag2JhuI5FlvxiGXXRnJUqgrFiaE=
93+
github.com/secrethub/secrethub-go v0.23.1-0.20191126145052-23fd5b7a4363/go.mod h1:rc2IfKKBJ4L0wGec0u4XnF5/pe0FFPE4Q1MWfrFso7s=
94+
github.com/secrethub/secrethub-go v0.24.0 h1:psxPZzPk5DrZTTTvnIE9F1oj43QVwHjJ2ZnBvsXn0wc=
95+
github.com/secrethub/secrethub-go v0.24.0/go.mod h1:rc2IfKKBJ4L0wGec0u4XnF5/pe0FFPE4Q1MWfrFso7s=
8896
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
8997
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
9098
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=

internals/secrethub/audit.go

Lines changed: 177 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package secrethub
22

33
import (
4+
"fmt"
5+
"strings"
6+
"text/tabwriter"
7+
48
"github.com/secrethub/secrethub-cli/internals/cli/ui"
59
"github.com/secrethub/secrethub-cli/internals/secrethub/command"
10+
"github.com/secrethub/secrethub-go/pkg/secrethub"
11+
"github.com/secrethub/secrethub-go/pkg/secrethub/iterator"
612

713
"github.com/secrethub/secrethub-go/internals/api"
814
)
@@ -12,7 +18,9 @@ type AuditCommand struct {
1218
io ui.IO
1319
path api.Path
1420
useTimestamps bool
21+
timeFormatter TimeFormatter
1522
newClient newClientFunc
23+
perPage int
1624
}
1725

1826
// NewAuditCommand creates a new audit command.
@@ -27,34 +35,190 @@ func NewAuditCommand(io ui.IO, newClient newClientFunc) *AuditCommand {
2735
func (cmd *AuditCommand) Register(r command.Registerer) {
2836
clause := r.Command("audit", "Show the audit log.")
2937
clause.Arg("repo-path or secret-path", "Path to the repository or the secret to audit "+repoPathPlaceHolder+" or "+secretPathPlaceHolder).SetValue(&cmd.path)
38+
clause.Flag("per-page", "number of audit events shown per page").Default("20").IntVar(&cmd.perPage)
3039
registerTimestampFlag(clause).BoolVar(&cmd.useTimestamps)
3140

3241
command.BindAction(clause, cmd.Run)
3342
}
3443

3544
// Run prints all audit events for the given repository or secret.
3645
func (cmd *AuditCommand) Run() error {
46+
cmd.beforeRun()
47+
return cmd.run()
48+
}
49+
50+
// beforeRun configures the command using the flag values.
51+
func (cmd *AuditCommand) beforeRun() {
52+
cmd.timeFormatter = NewTimeFormatter(cmd.useTimestamps)
53+
}
54+
55+
// Run prints all audit events for the given repository or secret.
56+
func (cmd *AuditCommand) run() error {
57+
if cmd.perPage < 1 {
58+
return fmt.Errorf("per-page should be positive, got %d", cmd.perPage)
59+
}
60+
61+
iter, auditTable, err := cmd.iterAndAuditTable()
62+
if err != nil {
63+
return err
64+
}
65+
66+
tabWriter := tabwriter.NewWriter(cmd.io.Stdout(), 0, 4, 4, ' ', 0)
67+
header := strings.Join(auditTable.header(), "\t") + "\n"
68+
fmt.Fprint(tabWriter, header)
69+
70+
i := 0
71+
for {
72+
i++
73+
event, err := iter.Next()
74+
if err == iterator.Done {
75+
break
76+
} else if err != nil {
77+
return err
78+
}
79+
80+
row, err := auditTable.row(event)
81+
if err != nil {
82+
return err
83+
}
84+
85+
fmt.Fprint(tabWriter, strings.Join(row, "\t")+"\n")
86+
87+
if i == cmd.perPage {
88+
err = tabWriter.Flush()
89+
if err != nil {
90+
return err
91+
}
92+
i = 0
93+
94+
// wait for <ENTER> to continue.
95+
_, err := ui.Ask(cmd.io, "Press <ENTER> to show more results. Press <CTRL+C> to exit.")
96+
if err != nil {
97+
return err
98+
}
99+
fmt.Fprint(tabWriter, header)
100+
}
101+
}
102+
103+
err = tabWriter.Flush()
104+
if err != nil {
105+
return err
106+
}
107+
108+
return nil
109+
}
110+
111+
func (cmd *AuditCommand) iterAndAuditTable() (secrethub.AuditEventIterator, auditTable, error) {
37112
repoPath, err := cmd.path.ToRepoPath()
38113
if err == nil {
39-
auditRepoCommand := AuditRepoCommand{
40-
io: cmd.io,
41-
path: repoPath,
42-
useTimestamps: cmd.useTimestamps,
43-
newClient: cmd.newClient,
114+
client, err := cmd.newClient()
115+
if err != nil {
116+
return nil, nil, err
117+
}
118+
tree, err := client.Dirs().GetTree(repoPath.GetDirPath().Value(), -1, false)
119+
if err != nil {
120+
return nil, nil, err
44121
}
45-
return auditRepoCommand.Run()
122+
123+
iter := client.Repos().EventIterator(repoPath.Value(), &secrethub.AuditEventIteratorParams{})
124+
auditTable := newRepoAuditTable(tree, cmd.timeFormatter)
125+
return iter, auditTable, nil
126+
46127
}
47128

48129
secretPath, err := cmd.path.ToSecretPath()
49130
if err == nil {
50-
auditSecretCommand := AuditSecretCommand{
51-
io: cmd.io,
52-
path: secretPath,
53-
useTimestamps: cmd.useTimestamps,
54-
newClient: cmd.newClient,
131+
if cmd.path.HasVersion() {
132+
return nil, nil, ErrCannotAuditSecretVersion
133+
}
134+
135+
client, err := cmd.newClient()
136+
if err != nil {
137+
return nil, nil, err
55138
}
56-
return auditSecretCommand.Run()
139+
140+
isDir, err := client.Dirs().Exists(secretPath.Value())
141+
if err == nil && isDir {
142+
return nil, nil, ErrCannotAuditDir
143+
}
144+
145+
iter := client.Secrets().EventIterator(secretPath.Value(), &secrethub.AuditEventIteratorParams{})
146+
auditTable := newSecretAuditTable(cmd.timeFormatter)
147+
return iter, auditTable, nil
148+
}
149+
150+
return nil, nil, ErrNoValidRepoOrSecretPath
151+
}
152+
153+
type auditTable interface {
154+
header() []string
155+
row(event api.Audit) ([]string, error)
156+
}
157+
158+
func newBaseAuditTable(timeFormatter TimeFormatter) baseAuditTable {
159+
return baseAuditTable{
160+
timeFormatter: timeFormatter,
161+
}
162+
}
163+
164+
type baseAuditTable struct {
165+
timeFormatter TimeFormatter
166+
}
167+
168+
func (table baseAuditTable) header(content ...string) []string {
169+
res := append([]string{"AUTHOR", "EVENT"}, content...)
170+
return append(res, "IP ADDRESS", "DATE")
171+
}
172+
173+
func (table baseAuditTable) row(event api.Audit, content ...string) ([]string, error) {
174+
actor, err := getAuditActor(event)
175+
if err != nil {
176+
return nil, err
177+
}
178+
179+
res := append([]string{actor, getEventAction(event)}, content...)
180+
return append(res, event.IPAddress, table.timeFormatter.Format(event.LoggedAt)), nil
181+
}
182+
183+
func newSecretAuditTable(timeFormatter TimeFormatter) secretAuditTable {
184+
return secretAuditTable{
185+
baseAuditTable: newBaseAuditTable(timeFormatter),
186+
}
187+
}
188+
189+
type secretAuditTable struct {
190+
baseAuditTable
191+
}
192+
193+
func (table secretAuditTable) header() []string {
194+
return table.baseAuditTable.header()
195+
}
196+
197+
func (table secretAuditTable) row(event api.Audit) ([]string, error) {
198+
return table.baseAuditTable.row(event)
199+
}
200+
201+
func newRepoAuditTable(tree *api.Tree, timeFormatter TimeFormatter) repoAuditTable {
202+
return repoAuditTable{
203+
baseAuditTable: newBaseAuditTable(timeFormatter),
204+
tree: tree,
205+
}
206+
}
207+
208+
type repoAuditTable struct {
209+
baseAuditTable
210+
tree *api.Tree
211+
}
212+
213+
func (table repoAuditTable) header() []string {
214+
return table.baseAuditTable.header("EVENT SUBJECT")
215+
}
216+
217+
func (table repoAuditTable) row(event api.Audit) ([]string, error) {
218+
subject, err := getAuditSubject(event, table.tree)
219+
if err != nil {
220+
return nil, err
57221
}
58222

59-
return ErrNoValidRepoOrSecretPath
223+
return table.baseAuditTable.row(event, subject)
60224
}

internals/secrethub/audit_helper.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"github.com/secrethub/secrethub-go/internals/api"
77
)
88

9-
func getAuditActor(event *api.Audit) (string, error) {
9+
func getAuditActor(event api.Audit) (string, error) {
1010
if event.Actor.Deleted {
1111
return event.Actor.ActorID.String(), nil
1212
}
@@ -21,7 +21,7 @@ func getAuditActor(event *api.Audit) (string, error) {
2121
return "", ErrInvalidAuditActor
2222
}
2323

24-
func getAuditSubject(event *api.Audit, tree *api.Tree) (string, error) {
24+
func getAuditSubject(event api.Audit, tree *api.Tree) (string, error) {
2525
if event.Subject.Deleted {
2626
return event.Subject.SubjectID.String(), nil
2727
}
@@ -65,7 +65,7 @@ func getAuditSubject(event *api.Audit, tree *api.Tree) (string, error) {
6565

6666
}
6767

68-
func getEventAction(event *api.Audit) string {
68+
func getEventAction(event api.Audit) string {
6969
action := event.Action
7070
subjectType := event.Subject.Type
7171

internals/secrethub/audit_repo.go

Lines changed: 0 additions & 82 deletions
This file was deleted.

0 commit comments

Comments
 (0)