Skip to content

Commit

Permalink
feat: add stdout repository activity (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
mabdh authored Apr 22, 2024
1 parent 8028b5a commit 535a1b3
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 18 deletions.
21 changes: 17 additions & 4 deletions cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"io"
"net/http"
"os"
"os/signal"
Expand All @@ -13,6 +14,7 @@ import (
_ "github.com/authzed/authzed-go/proto/authzed/api/v0"
_ "github.com/jackc/pgx/v4/stdlib"
newrelic "github.com/newrelic/go-agent"
"go.uber.org/zap"

"github.com/goto/shield/config"
"github.com/goto/shield/core/action"
Expand Down Expand Up @@ -92,8 +94,19 @@ func StartServer(logger *log.Zap, cfg *config.Shield) error {

schemaMigrationConfig := schema.NewSchemaMigrationConfig(cfg.App.DefaultSystemEmail)

//
activityRepository := postgres.NewActivityRepository(dbClient)
var activityRepository activity.Repository
switch cfg.Log.Activity.Sink {
case activity.SinkTypeDB:
activityRepository = postgres.NewActivityRepository(dbClient)
case activity.SinkTypeStdout:
stdoutLogger, err := zap.NewStdLogAt(logger.GetInternalZapLogger().Desugar(), logger.GetInternalZapLogger().Level())
if err != nil {
return err
}
activityRepository = activity.NewStdoutRepository(stdoutLogger.Writer())
default:
activityRepository = activity.NewStdoutRepository(io.Discard)
}
activityService := activity.NewService(activityRepository)

userRepository := postgres.NewUserRepository(dbClient)
Expand Down Expand Up @@ -128,7 +141,7 @@ func StartServer(logger *log.Zap, cfg *config.Shield) error {
return err
}

deps, err := BuildAPIDependencies(ctx, logger, resourceBlobRepository, dbClient, spiceDBClient)
deps, err := BuildAPIDependencies(ctx, logger, activityRepository, resourceBlobRepository, dbClient, spiceDBClient)
if err != nil {
return err
}
Expand Down Expand Up @@ -166,11 +179,11 @@ func StartServer(logger *log.Zap, cfg *config.Shield) error {
func BuildAPIDependencies(
ctx context.Context,
logger log.Logger,
activityRepository activity.Repository,
resourceBlobRepository *blob.ResourcesRepository,
dbc *db.Client,
sdb *spicedb.SpiceDB,
) (api.Deps, error) {
activityRepository := postgres.NewActivityRepository(dbc)
activityService := activity.NewService(activityRepository)

userRepository := postgres.NewUserRepository(dbc)
Expand Down
2 changes: 1 addition & 1 deletion cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func serverStartCommand() *cobra.Command {
if err != nil {
panic(err)
}
logger := shieldlogger.InitLogger(appConfig.Log)
logger := shieldlogger.InitLogger(shieldlogger.Config{Level: appConfig.Log.Level})

return StartServer(logger, appConfig)
},
Expand Down
18 changes: 16 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,28 @@ import (
"github.com/goto/shield/internal/server"
"github.com/goto/shield/internal/store/spicedb"
"github.com/goto/shield/pkg/db"
"github.com/goto/shield/pkg/logger"
)

type Log struct {
// log level - debug, info, warning, error, fatal
Level string `yaml:"level" mapstructure:"level" default:"info"`

// format strategy - plain, json
Format string `yaml:"format" mapstructure:"format" default:"json"`

Activity ActivityLogConfig `yaml:"activity" mapstructure:"activity"`
}

type ActivityLogConfig struct {
// activity sink strategy - db, stdout, none
Sink string `yaml:"sink" mapstructure:"sink" default:"none"`
}

type Shield struct {
// configuration version
Version int `yaml:"version"`
Proxy proxy.ServicesConfig `yaml:"proxy"`
Log logger.Config `yaml:"log"`
Log Log `yaml:"log"`
NewRelic NewRelic `yaml:"new_relic"`
App server.Config `yaml:"app"`
DB db.Config `yaml:"db"`
Expand Down
6 changes: 6 additions & 0 deletions core/activity/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import (
"github.com/goto/salt/audit"
)

const (
SinkTypeDB = "db"
SinkTypeStdout = "stdout"
SinkTypeNone = "none"
)

type Repository interface {
Insert(ctx context.Context, log *audit.Log) error
}
23 changes: 23 additions & 0 deletions core/activity/stdout_repository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package activity

import (
"context"
"encoding/json"
"io"

"github.com/goto/salt/audit"
)

type StdoutRepository struct {
writer io.Writer
}

func NewStdoutRepository(writer io.Writer) *StdoutRepository {
return &StdoutRepository{
writer: writer,
}
}

func (r StdoutRepository) Insert(ctx context.Context, log *audit.Log) error {
return json.NewEncoder(r.writer).Encode(log)
}
4 changes: 4 additions & 0 deletions docs/docs/reference/configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ version: 1
log:
# debug, info, warning, error, fatal - default 'info'
level: debug
activity:
# none, stdout, db - default 'none'
sink: stdout


app:
port: 8000
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ require (
contrib.go.opencensus.io/exporter/prometheus v0.4.2
github.com/MakeNowJust/heredoc v1.0.0
github.com/abbot/go-http-auth v0.4.0
github.com/antonmedv/expr v1.15.3
github.com/authzed/authzed-go v0.7.1-0.20221109204547-1aa903788b3b
github.com/authzed/grpcutil v0.0.0-20230109193425-40ce0530e048
github.com/authzed/spicedb v1.15.0
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,6 @@ github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
github.com/antonmedv/expr v1.15.3 h1:q3hOJZNvLvhqE8OHBs1cFRdbXFNKuA+bHmRaI+AmRmI=
github.com/antonmedv/expr v1.15.3/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE=
github.com/apache/arrow/go/arrow v0.0.0-20210818145353-234c94e4ce64/go.mod h1:2qMFB56yOP3KzkB3PbYZ4AlUFg3a88F67TIx5lB/WwY=
github.com/apache/arrow/go/arrow v0.0.0-20211013220434-5962184e7a30/go.mod h1:Q7yQnSMnLvcXlZ8RV+jwz/6y1rQTqbX6C82SndT52Zs=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
Expand Down
5 changes: 1 addition & 4 deletions internal/proxy/hook/authz/authz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,7 @@ func TestServeHook(t *testing.T) {
mockRelationTransformer = new(mocks.RelationTransformer)
)

logger := shieldlogger.InitLogger(shieldlogger.Config{
Level: "info",
Format: "json",
})
logger := shieldlogger.InitLogger(shieldlogger.Config{Level: "debug"})

rootHook := hook.New()
a := New(logger, rootHook, rootHook, mockResourceService, mockRelationService, mockRelationTransformer, "X-Shield-Email")
Expand Down
63 changes: 63 additions & 0 deletions pkg/body_extractor/json_payload_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package body_extractor

import (
"bytes"
"encoding/json"
"io"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
)

func TestJSONPayloadHandler_Extract(t *testing.T) {
defaultTestMessage := map[string]any{
"k1": "v1",
"nested_k1": map[string]any{
"k1_1": "v1",
"k2_2": 1,
},
}

tests := []struct {
name string
key string
testMessage any
want any
wantErrString string
}{
{
name: "should return error if field not exist",
key: "x",
testMessage: defaultTestMessage,
wantErrString: "failed to find field: x",
},
{
name: "should return value if field found",
key: "nested_k1.k2_2",
testMessage: defaultTestMessage,
want: float64(1),
},
}
for _, tt := range tests {
h := JSONPayloadHandler{}
t.Run(tt.name, func(t *testing.T) {
tt := tt
t.Parallel()

msg, err := json.Marshal(tt.testMessage)
assert.NoError(t, err)

testReader := io.NopCloser(bytes.NewBuffer(msg))
extractedData, err := h.Extract(&testReader, tt.key)

if tt.wantErrString != "" {
assert.Equal(t, tt.wantErrString, err.Error())
} else {
if diff := cmp.Diff(tt.want, extractedData); diff != "" {
t.Fatal(diff)
}
}
})
}
}
3 changes: 1 addition & 2 deletions pkg/expression/expression.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package expression

import (
"errors"
"fmt"
"reflect"
)
Expand All @@ -21,7 +20,7 @@ func (e Expression) Evaluate() (bool, error) {
output = reflect.DeepEqual(e.Attribute, e.Value)
err = nil
default:
err = errors.New(fmt.Sprintf("unsupported operator %s", e.Operator))
err = fmt.Errorf("unsupported operator %s", e.Operator)
}

return output, err
Expand Down
10 changes: 10 additions & 0 deletions pkg/expression/expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ func TestExpression_Evaluate(t *testing.T) {
wantNilErr: true,
wantOutput: false,
},
{
name: "unknown expression return error",
expression: Expression{
Attribute: "A",
Operator: "';l",
Value: "B",
},
wantNilErr: false,
wantOutput: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
3 changes: 1 addition & 2 deletions test/e2e_test/testbench/testbench.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"github.com/goto/shield/internal/store/postgres/migrations"
"github.com/goto/shield/internal/store/spicedb"
"github.com/goto/shield/pkg/db"
"github.com/goto/shield/pkg/logger"
shieldv1beta1 "github.com/goto/shield/proto/v1beta1"
"github.com/ory/dockertest"
"github.com/ory/dockertest/docker"
Expand Down Expand Up @@ -191,7 +190,7 @@ func SetupTests(t *testing.T) (shieldv1beta1.ShieldServiceClient, *config.Shield
}

appConfig := &config.Shield{
Log: logger.Config{
Log: config.Log{
Level: "fatal",
},
App: server.Config{
Expand Down

0 comments on commit 535a1b3

Please sign in to comment.