diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-24 14:01:44 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-24 14:01:44 -0600 |
| commit | 209239705fff9b3545d6856387203f12accd603b (patch) | |
| tree | 3cbd37efb9c150e32bd8142b472917aa23db4b01 | |
| parent | 7fe2df5a420ed8ee77c9f11d9403ed9a07f34e73 (diff) | |
refactor: use username as id for demo
| -rw-r--r-- | app/domain/user.go | 9 | ||||
| -rw-r--r-- | app/init.go | 84 | ||||
| -rw-r--r-- | app/middleware/require_permission_test.go | 4 |
3 files changed, 75 insertions, 22 deletions
diff --git a/app/domain/user.go b/app/domain/user.go index d59baac..e618b5f 100644 --- a/app/domain/user.go +++ b/app/domain/user.go @@ -41,9 +41,16 @@ func (self *User) ToGID() string { return "gid://sparkle/User/" + self.ID.String() } +func (self *User) ToSubjectReference() *v1.SubjectReference { + return &v1.SubjectReference{ + Object: self.ToObjectReference(), + } +} + func (self *User) ToObjectReference() *v1.ObjectReference { return &v1.ObjectReference{ ObjectType: "user", - ObjectId: self.ID.String(), + // ObjectId: self.ID.String(), + ObjectId: self.Username, } } diff --git a/app/init.go b/app/init.go index d26a962..b88cb00 100644 --- a/app/init.go +++ b/app/init.go @@ -5,6 +5,7 @@ import ( "net/http" "os" + v1 "github.com/authzed/authzed-go/proto/authzed/api/v1" "github.com/authzed/authzed-go/v1" "github.com/rs/zerolog" "github.com/xlgmokha/x/pkg/env" @@ -22,50 +23,53 @@ import ( ) func init() { - ioc.RegisterSingleton[*zerolog.Logger](ioc.Default, func() *zerolog.Logger { + c := ioc.Default + + ioc.RegisterSingleton[*zerolog.Logger](c, func() *zerolog.Logger { return log.New(os.Stdout, log.Fields{"app": "sparkled"}) }) - ioc.RegisterSingleton[*authzed.Client](ioc.Default, func() *authzed.Client { + ioc.RegisterSingleton[*authzed.Client](c, func() *authzed.Client { return authz.NewSpiceDBClient( context.Background(), env.Fetch("ZED_ENDPOINT", ":50051"), env.Fetch("ZED_TOKEN", "secret"), ) }) - ioc.Register[authz.CheckPermissionService](ioc.Default, func() authz.CheckPermissionService { - return ioc.MustResolve[*authzed.Client](ioc.Default) + ioc.Register[authz.CheckPermissionService](c, func() authz.CheckPermissionService { + return ioc.MustResolve[*authzed.Client](c) }) - ioc.RegisterSingleton[*event.Aggregator](ioc.Default, func() *event.Aggregator { + ioc.RegisterSingleton[*event.Aggregator](c, func() *event.Aggregator { return x.New[*event.Aggregator](event.WithDefaults()) }) - ioc.RegisterSingleton[domain.Repository[*domain.Sparkle]](ioc.Default, func() domain.Repository[*domain.Sparkle] { - return db.NewRepository[*domain.Sparkle]( - x.New[*event.TypedAggregator[*domain.Sparkle]](event.WithAggregator[*domain.Sparkle]( - ioc.MustResolve[*event.Aggregator](ioc.Default), - )), - ) + ioc.Register[*event.TypedAggregator[*domain.Sparkle]](c, func() *event.TypedAggregator[*domain.Sparkle] { + return x.New[*event.TypedAggregator[*domain.Sparkle]](event.WithAggregator[*domain.Sparkle]( + ioc.MustResolve[*event.Aggregator](c), + )) + }) + ioc.RegisterSingleton[domain.Repository[*domain.Sparkle]](c, func() domain.Repository[*domain.Sparkle] { + return db.NewRepository[*domain.Sparkle](ioc.MustResolve[*event.TypedAggregator[*domain.Sparkle]](c)) }) - ioc.RegisterSingleton[*http.ServeMux](ioc.Default, func() *http.ServeMux { + ioc.RegisterSingleton[*http.ServeMux](c, func() *http.ServeMux { return http.NewServeMux() }) - ioc.Register[*dashboard.Controller](ioc.Default, func() *dashboard.Controller { + ioc.Register[*dashboard.Controller](c, func() *dashboard.Controller { return dashboard.New() }) - ioc.Register[*sparkles.Controller](ioc.Default, func() *sparkles.Controller { + ioc.Register[*sparkles.Controller](c, func() *sparkles.Controller { return sparkles.New( - ioc.MustResolve[domain.Repository[*domain.Sparkle]](ioc.Default), - ioc.MustResolve[authz.CheckPermissionService](ioc.Default), + ioc.MustResolve[domain.Repository[*domain.Sparkle]](c), + ioc.MustResolve[authz.CheckPermissionService](c), ) }) - ioc.RegisterSingleton[*http.Client](ioc.Default, func() *http.Client { + ioc.RegisterSingleton[*http.Client](c, func() *http.Client { return &http.Client{ Transport: &web.Transport{ - Logger: ioc.MustResolve[*zerolog.Logger](ioc.Default), + Logger: ioc.MustResolve[*zerolog.Logger](c), }, } }) - http.DefaultClient = ioc.MustResolve[*http.Client](ioc.Default) + http.DefaultClient = ioc.MustResolve[*http.Client](c) mapper.Register[*http.Request, log.Fields](func(r *http.Request) log.Fields { return log.Fields{ @@ -76,4 +80,46 @@ func init() { "request_id": r.Header.Get("x-request-id"), } }) + + ioc.MustResolve[*event.TypedAggregator[*domain.Sparkle]](c).SubscribeTo("after.create", func(item *domain.Sparkle) { + client := ioc.MustResolve[*authzed.Client](c) + client.WriteRelationships(context.Background(), &v1.WriteRelationshipsRequest{ + Updates: []*v1.RelationshipUpdate{ + &v1.RelationshipUpdate{ + Operation: v1.RelationshipUpdate_OPERATION_CREATE, + Relationship: &v1.Relationship{ + Resource: item.ToObjectReference(), + Relation: "sparkler", + Subject: item.Author.ToSubjectReference(), + }, + }, + &v1.RelationshipUpdate{ + Operation: v1.RelationshipUpdate_OPERATION_CREATE, + Relationship: &v1.Relationship{ + Resource: item.ToObjectReference(), + Relation: "sparklee", + Subject: &v1.SubjectReference{ + Object: &v1.ObjectReference{ + ObjectType: "user", + ObjectId: item.Sparklee, + }, + }, + }, + }, + &v1.RelationshipUpdate{ + Operation: v1.RelationshipUpdate_OPERATION_CREATE, + Relationship: &v1.Relationship{ + Resource: item.ToObjectReference(), + Relation: "reader", + Subject: &v1.SubjectReference{ + Object: &v1.ObjectReference{ + ObjectType: "user", + ObjectId: "*", + }, + }, + }, + }, + }, + }) + }) } diff --git a/app/middleware/require_permission_test.go b/app/middleware/require_permission_test.go index 2023345..a936e1e 100644 --- a/app/middleware/require_permission_test.go +++ b/app/middleware/require_permission_test.go @@ -12,14 +12,14 @@ import ( ) func TestRequirePermission(t *testing.T) { - user := &domain.User{ID: domain.ID("1")} + user := &domain.User{ID: domain.ID("1"), Username: "tanuki"} ctx := cfg.CurrentUser.With(t.Context(), user) permission := domain.Permission("read") t.Run("when the permission is granted", func(t *testing.T) { r, w := test.RequestResponse("GET", "/sparkles", test.WithContext(ctx)) - middleware := RequirePermission(permission, stub.AllowWith(t, "user:1", permission.String(), "sparkle:*")) + middleware := RequirePermission(permission, stub.AllowWith(t, "user:tanuki", permission.String(), "sparkle:*")) server := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusTeapot) })) |
