cmd/gitbayd/auditverify.go

9df917e73a67d15adecc3f45976690f6fcd4e47a
gitbay/cmd/gitbayd/auditverify.go history · blame · raw

53 lines · 1635 bytes

 1package main
 2
 3import (
 4	"fmt"
 5
 6	"github.com/spf13/cobra"
 7
 8	"gitbay.org/gitbay/internal/config"
 9)
10
11// auditVerifyCmd recomputes the audit log's hash chain. A break names
12// the first row that does not match. Rows removed from the end of the
13// log, and rows written after that under the reused ids, leave no
14// break: the last id and hash printed here are what an operator
15// compares with the daemon's journal copy to see either.
16func auditVerifyCmd() *cobra.Command {
17	return &cobra.Command{
18		Use:   "verify",
19		Short: "check the audit log's hash chain",
20		Args:  cobra.NoArgs,
21		RunE: func(cmd *cobra.Command, args []string) error {
22			cfg, err := config.Load(configPath)
23			if err != nil {
24				return err
25			}
26			st, err := openStore(cfg)
27			if err != nil {
28				return err
29			}
30			defer st.Close()
31			res, err := st.VerifyAuditChain()
32			if err != nil {
33				return err
34			}
35			fmt.Printf("rows %d\nunchained %d\n", res.Rows, res.Unchained)
36			if res.BrokenAt != 0 {
37				return fmt.Errorf("chain broken at row %d: %s", res.BrokenAt, res.Reason)
38			}
39			// Every row unchained is what dropping and re-adding the hash
40			// columns leaves. It is also an upgrade from before migration
41			// 0064 with no row written since; the first new row clears it.
42			if res.Rows > 0 && res.Unchained == res.Rows {
43				return fmt.Errorf("no row carries a hash: the chain columns were cleared, or no audit row has been written since the upgrade")
44			}
45			if res.Last == 0 {
46				fmt.Println("no rows yet")
47				return nil
48			}
49			fmt.Printf("first %d\nlast %d\nlast hash %s\nchain intact\n", res.First, res.Last, res.LastHash)
50			return nil
51		},
52	}
53}