Skip to content

Commit

Permalink
Implement 'wookie' protocol (#163)
Browse files Browse the repository at this point in the history
* Create zookie-like 'wookie' implementation for specifying consistency/freshness on reads

* Persist wookies on updates and send back in responses

* Fix postgres createWookie query

* Send back latest wookie in all check/read calls

* Simplify wookie service methods

* Check service Check() to use wookie read

* Implement wookie service methods

* Allow wookieSafeReads() within WithWookieUpdate()

* Don't err out if wookie values not present

* Add basic wookie token unit test

* Address cr comments
  • Loading branch information
akajla09 authored Jun 21, 2023
1 parent 336f944 commit 649eb59
Show file tree
Hide file tree
Showing 36 changed files with 1,104 additions and 311 deletions.
20 changes: 14 additions & 6 deletions cmd/warrant/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@ import (
tenant "github.com/warrant-dev/warrant/pkg/authz/tenant"
user "github.com/warrant-dev/warrant/pkg/authz/user"
warrant "github.com/warrant-dev/warrant/pkg/authz/warrant"
wookie "github.com/warrant-dev/warrant/pkg/authz/wookie"
"github.com/warrant-dev/warrant/pkg/config"
"github.com/warrant-dev/warrant/pkg/database"
"github.com/warrant-dev/warrant/pkg/event"
"github.com/warrant-dev/warrant/pkg/service"
)

const (
MySQLDatastoreMigrationVersion = 000004
MySQLDatastoreMigrationVersion = 000005
MySQLEventstoreMigrationVersion = 000003
PostgresDatastoreMigrationVersion = 000005
PostgresDatastoreMigrationVersion = 000006
PostgresEventstoreMigrationVersion = 000004
SQLiteDatastoreMigrationVersion = 000004
SQLiteDatastoreMigrationVersion = 000005
SQLiteEventstoreMigrationVersion = 000003
)

Expand Down Expand Up @@ -195,22 +196,29 @@ func main() {
}
eventSvc := event.NewService(svcEnv, eventRepository, cfg.Eventstore.SynchronizeEvents, nil)

// Init wookie repo and service
wookieRepository, err := wookie.NewRepository(svcEnv.DB())
if err != nil {
log.Fatal().Err(err).Msg("Could not initialize WookieRepository")
}
wookieSvc := wookie.NewService(svcEnv, wookieRepository)

// Init object type repo and service
objectTypeRepository, err := objecttype.NewRepository(svcEnv.DB())
if err != nil {
log.Fatal().Err(err).Msg("Could not initialize ObjectTypeRepository")
}
objectTypeSvc := objecttype.NewService(svcEnv, objectTypeRepository, eventSvc)
objectTypeSvc := objecttype.NewService(svcEnv, objectTypeRepository, eventSvc, wookieSvc)

// Init warrant repo and service
warrantRepository, err := warrant.NewRepository(svcEnv.DB())
if err != nil {
log.Fatal().Err(err).Msg("Could not initialize WarrantRepository")
}
warrantSvc := warrant.NewService(svcEnv, warrantRepository, eventSvc, objectTypeSvc)
warrantSvc := warrant.NewService(svcEnv, warrantRepository, eventSvc, objectTypeSvc, wookieSvc)

// Init check service
checkSvc := check.NewService(svcEnv, warrantRepository, eventSvc, objectTypeSvc)
checkSvc := check.NewService(svcEnv, warrantRepository, eventSvc, objectTypeSvc, wookieSvc)

// Init object repo and service
objectRepository, err := object.NewRepository(svcEnv.DB())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
BEGIN;

DROP TABLE IF EXISTS wookie;

COMMIT;
10 changes: 10 additions & 0 deletions migrations/datastore/mysql/000005_create_wookie_table.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
BEGIN;

CREATE TABLE IF NOT EXISTS wookie (
id bigint NOT NULL AUTO_INCREMENT,
ver bigint NOT NULL,
createdAt timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
BEGIN;

DROP TABLE IF EXISTS wookie;

COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
BEGIN;

CREATE TABLE IF NOT EXISTS wookie (
id bigserial PRIMARY KEY,
ver bigserial,
created_at timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP(6)
);

COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS wookie;
5 changes: 5 additions & 0 deletions migrations/datastore/sqlite/000005_create_wookie_table.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS wookie (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ver INTEGER,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
);
16 changes: 11 additions & 5 deletions pkg/authz/check/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ import (

objecttype "github.com/warrant-dev/warrant/pkg/authz/objecttype"
warrant "github.com/warrant-dev/warrant/pkg/authz/warrant"
wookie "github.com/warrant-dev/warrant/pkg/authz/wookie"
"github.com/warrant-dev/warrant/pkg/service"
)

func (svc CheckService) Routes() ([]service.Route, error) {
return []service.Route{
// Standard Authorization
service.WarrantRoute{
Pattern: "/v2/authorize",
Method: "POST",
Handler: service.NewRouteHandler(svc, AuthorizeHandler),
Pattern: "/v2/authorize",
Method: "POST",
Handler: service.ChainMiddleware(
service.NewRouteHandler(svc, AuthorizeHandler),
wookie.ClientTokenMiddleware,
),
OverrideAuthMiddlewareFunc: service.ApiKeyAndSessionAuthMiddleware,
},
}, nil
Expand Down Expand Up @@ -49,10 +53,11 @@ func AuthorizeHandler(svc CheckService, w http.ResponseWriter, r *http.Request)
Debug: sessionCheckManySpec.Debug,
}

checkResult, err := svc.CheckMany(r.Context(), authInfo, &checkManySpec)
checkResult, updatedWookie, err := svc.CheckMany(r.Context(), authInfo, &checkManySpec)
if err != nil {
return err
}
wookie.AddAsResponseHeader(w, updatedWookie)

service.SendJSONResponse(w, checkResult)
return nil
Expand All @@ -64,10 +69,11 @@ func AuthorizeHandler(svc CheckService, w http.ResponseWriter, r *http.Request)
return err
}

checkResult, err := svc.CheckMany(r.Context(), authInfo, &checkManySpec)
checkResult, updatedWookie, err := svc.CheckMany(r.Context(), authInfo, &checkManySpec)
if err != nil {
return err
}
wookie.AddAsResponseHeader(w, updatedWookie)

service.SendJSONResponse(w, checkResult)
return nil
Expand Down
Loading

0 comments on commit 649eb59

Please sign in to comment.