package app import ( "context" "fmt" "net/http" "os" "strings" 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" "github.com/xlgmokha/x/pkg/event" "github.com/xlgmokha/x/pkg/ioc" "github.com/xlgmokha/x/pkg/log" "github.com/xlgmokha/x/pkg/mapper" "github.com/xlgmokha/x/pkg/x" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/controllers/dashboard" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/controllers/sparkles" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/db" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/domain" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/authz" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/web" ) func init() { c := ioc.Default ioc.RegisterSingleton[*zerolog.Logger](c, func() *zerolog.Logger { return log.New(os.Stdout, log.Fields{"app": "sparkled"}) }) 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](c, func() authz.CheckPermissionService { return ioc.MustResolve[*authzed.Client](c) }) ioc.RegisterSingleton[*event.Aggregator](c, func() *event.Aggregator { return x.New[*event.Aggregator](event.WithDefaults()) }) 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](c, func() *http.ServeMux { return http.NewServeMux() }) ioc.Register[*dashboard.Controller](c, func() *dashboard.Controller { return dashboard.New() }) ioc.Register[*sparkles.Controller](c, func() *sparkles.Controller { return sparkles.New( ioc.MustResolve[domain.Repository[*domain.Sparkle]](c), ioc.MustResolve[authz.CheckPermissionService](c), ) }) ioc.RegisterSingleton[*http.Client](c, func() *http.Client { return &http.Client{ Transport: &web.Transport{ Logger: ioc.MustResolve[*zerolog.Logger](c), }, } }) http.DefaultClient = ioc.MustResolve[*http.Client](c) mapper.Register[*http.Request, log.Fields](func(r *http.Request) log.Fields { return log.Fields{ "host": r.URL.Host, "method": r.Method, "path": r.URL.Path, "remote_host": r.RemoteAddr, "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) resource := item.ToGID().ToObjectReference() response, err := client.WriteRelationships(context.Background(), &v1.WriteRelationshipsRequest{ Updates: []*v1.RelationshipUpdate{ &v1.RelationshipUpdate{ Operation: v1.RelationshipUpdate_OPERATION_CREATE, Relationship: &v1.Relationship{ Resource: resource, Relation: "sparkler", Subject: item.Author.ToSubjectReference(), }, }, &v1.RelationshipUpdate{ Operation: v1.RelationshipUpdate_OPERATION_CREATE, Relationship: &v1.Relationship{ Resource: resource, Relation: "sparklee", Subject: &v1.SubjectReference{ Object: &v1.ObjectReference{ ObjectType: "user", ObjectId: strings.TrimPrefix(item.Sparklee, "@"), }, }, }, }, &v1.RelationshipUpdate{ Operation: v1.RelationshipUpdate_OPERATION_CREATE, Relationship: &v1.Relationship{ Resource: resource, Relation: "reader", Subject: &v1.SubjectReference{ Object: &v1.ObjectReference{ ObjectType: "user", ObjectId: "*", }, }, }, }, }, }) if err != nil { fmt.Printf("%v\n", err) } fmt.Printf("%v\n", response) }) }