diff --git a/Makefile b/Makefile index 9c7a0f430..21cfa2e6d 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,9 @@ GOVERSION := $(shell go version | cut -d ' ' -f 3 | cut -d '.' -f 2) NAME=github.com/raystack/frontier TAG := $(shell git rev-list --tags --max-count=1) VERSION := $(shell git describe --tags ${TAG}) -.PHONY: build check fmt lint test test-race vet test-cover-html help install proto ui +.PHONY: build check fmt lint test test-race vet test-cover-html help install proto ui compose-up-dev .DEFAULT_GOAL := build -PROTON_COMMIT := "acaad106cbc6ee1517eab2eecf8337b5c2d690ec" +PROTON_COMMIT := "608c3ccfe2f66db16bb82877037bc1edff795c63" ui: @echo " > generating ui build" diff --git a/cmd/serve.go b/cmd/serve.go index 3b2a2d15d..fabbf9d61 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -11,6 +11,8 @@ import ( "syscall" "time" + "github.com/raystack/frontier/core/webhook" + "github.com/raystack/frontier/core/event" "github.com/stripe/stripe-go/v75" @@ -449,7 +451,12 @@ func buildAPIDependencies( eventChannel := make(chan audit.Log, 0) logPublisher := event.NewChanPublisher(eventChannel) logListener := event.NewChanListener(eventChannel, eventProcessor) - auditService := audit.NewService("frontier", auditRepository, audit.WithLogPublisher(logPublisher)) + + webhookService := webhook.NewService(postgres.NewWebhookEndpointRepository(dbc, []byte(cfg.App.Webhook.EncryptionKey))) + auditService := audit.NewService("frontier", + auditRepository, webhookService, + audit.WithLogPublisher(logPublisher), + ) dependencies := api.Deps{ OrgService: organizationService, @@ -482,6 +489,7 @@ func buildAPIDependencies( UsageService: usageService, InvoiceService: invoiceService, LogListener: logListener, + WebhookService: webhookService, } return dependencies, nil } diff --git a/core/audit/context.go b/core/audit/context.go index dc668da4e..751c2f94f 100644 --- a/core/audit/context.go +++ b/core/audit/context.go @@ -11,7 +11,7 @@ import ( func GetService(ctx context.Context) *Service { u, ok := ctx.Value(consts.AuditServiceContextKey).(*Service) if !ok { - return NewService("default", NewNoopRepository()) + return NewService("default", NewNoopRepository(), NewNoopWebhookService()) } return u } diff --git a/core/audit/noop_repository.go b/core/audit/noop_repository.go index eeafaea4a..a0075a936 100644 --- a/core/audit/noop_repository.go +++ b/core/audit/noop_repository.go @@ -2,6 +2,8 @@ package audit import ( "context" + + "github.com/raystack/frontier/core/webhook" ) type NoopRepository struct{} @@ -21,3 +23,13 @@ func (r NoopRepository) List(ctx context.Context, filter Filter) ([]Log, error) func (r NoopRepository) GetByID(ctx context.Context, s string) (Log, error) { return Log{}, nil } + +type NoopWebhookService struct{} + +func NewNoopWebhookService() *NoopWebhookService { + return &NoopWebhookService{} +} + +func (s NoopWebhookService) Publish(ctx context.Context, e webhook.Event) error { + return nil +} diff --git a/core/audit/service.go b/core/audit/service.go index d2c846d14..95afaf777 100644 --- a/core/audit/service.go +++ b/core/audit/service.go @@ -2,6 +2,9 @@ package audit import ( "context" + + "github.com/google/uuid" + "github.com/raystack/frontier/core/webhook" ) type Repository interface { @@ -14,6 +17,10 @@ type Publisher interface { Publish(context.Context, Log) } +type WebhookService interface { + Publish(ctx context.Context, e webhook.Event) error +} + type Option func(*Service) func WithMetadataExtractor(fn func(context.Context) (map[string]string, bool)) Option { @@ -35,20 +42,22 @@ func WithLogPublisher(p Publisher) Option { } type Service struct { - source string - repository Repository - publisher Publisher + source string + repository Repository + publisher Publisher + webhookService WebhookService actorExtractor func(context.Context) (Actor, bool) metadataExtractor func(context.Context) (map[string]string, bool) } -func NewService(source string, repository Repository, opts ...Option) *Service { +func NewService(source string, repository Repository, webhookService WebhookService, opts ...Option) *Service { svc := &Service{ source: source, repository: repository, actorExtractor: defaultActorExtractor, metadataExtractor: defaultMetadataExtractor, + webhookService: webhookService, } for _, o := range opts { o(svc) @@ -57,13 +66,25 @@ func NewService(source string, repository Repository, opts ...Option) *Service { } func (s *Service) Create(ctx context.Context, l *Log) error { + if l.ID == "" { + l.ID = uuid.NewString() + } err := s.repository.Create(ctx, l) if err != nil { return err } + if s.publisher != nil { s.publisher.Publish(ctx, *l) } + if err := s.webhookService.Publish(ctx, webhook.Event{ + ID: l.ID, + Action: l.Action, + Data: TransformToEventData(l), + CreatedAt: l.CreatedAt, + }); err != nil { + return err + } return nil } @@ -74,3 +95,37 @@ func (s *Service) List(ctx context.Context, flt Filter) ([]Log, error) { func (s *Service) GetByID(ctx context.Context, id string) (Log, error) { return s.repository.GetByID(ctx, id) } + +func TransformToEventData(l *Log) map[string]interface{} { + anyMap := make(map[string]any) + for k, v := range l.Metadata { + anyMap[k] = v + } + result := map[string]any{ + "target": map[string]any{}, + "actor": map[string]any{}, + } + if l.Target.Name != "" { + result["target"].(map[string]any)["name"] = l.Target.Name + } + if l.Target.ID != "" { + result["target"].(map[string]any)["id"] = l.Target.ID + } + if l.Target.Type != "" { + result["target"].(map[string]any)["type"] = l.Target.Type + } + if l.Actor.Name != "" { + result["actor"].(map[string]any)["name"] = l.Actor.Name + } + if l.Actor.ID != "" { + result["actor"].(map[string]any)["id"] = l.Actor.ID + } + if l.Actor.Type != "" { + result["actor"].(map[string]any)["type"] = l.Actor.Type + } + if l.Source != "" { + result["source"] = l.Source + } + result["metadata"] = anyMap + return result +} diff --git a/core/audit/service_test.go b/core/audit/service_test.go new file mode 100644 index 000000000..810b5f56c --- /dev/null +++ b/core/audit/service_test.go @@ -0,0 +1,119 @@ +package audit + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/mitchellh/mapstructure" + "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/types/known/structpb" +) + +func TestStructPB(t *testing.T) { + input := make(map[string]interface{}) + input["key"] = "value" + input["data"] = map[string]interface{}{ + "key2": "value2", + } + + result, err := structpb.NewStruct(input) + assert.NoError(t, err) + assert.NotNil(t, result) + + // map of string fails + input["data2"] = map[string]string{ + "key3": "value3", + } + _, err = structpb.NewStruct(input) + assert.Error(t, err) + delete(input, "data2") + + now := time.Now() + logDecoded := map[string]interface{}{} + err = mapstructure.Decode(&Log{ + Source: "source", + Target: Target{ + ID: "target-id", + Type: "target-type", + }, + Actor: Actor{ + ID: "actor-id", + Type: "actor-type", + Name: "actor-name", + }, + Metadata: map[string]string{}, + Action: "action", + ID: "id", + CreatedAt: now, + }, &logDecoded) + assert.NoError(t, err) + assert.NotNil(t, logDecoded) +} + +func TestTransformToEventData(t *testing.T) { + now := time.Now() + type args struct { + l *Log + } + tests := []struct { + name string + args args + want map[string]interface{} + }{ + { + name: "should decode everything except metadata", + args: args{ + l: &Log{ + Source: "source", + Target: Target{ + ID: "target-id", + Type: "target-type", + }, + Actor: Actor{ + ID: "actor-id", + Type: "actor-type", + Name: "actor-name", + }, + Metadata: map[string]string{}, + Action: "action", + ID: "id", + CreatedAt: now, + }, + }, + want: map[string]interface{}{ + "source": "source", + "target": map[string]any{"id": "target-id", "type": "target-type"}, + "actor": map[string]any{"id": "actor-id", "type": "actor-type", "name": "actor-name"}, + "metadata": map[string]any{}, + }, + }, + { + name: "should decode metadata correctly", + args: args{ + l: &Log{ + Source: "source", + Metadata: map[string]string{ + "key": "value", + }, + }, + }, + want: map[string]interface{}{ + "source": "source", + "actor": map[string]any{}, + "target": map[string]any{}, + "metadata": map[string]any{ + "key": "value", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := TransformToEventData(tt.args.l) + if diff := cmp.Diff(tt.want, got); diff != "" { + t.Errorf("TransformToEventData() mismatch (-want +got):\n%s", diff) + } + }) + } +} diff --git a/core/serviceuser/service.go b/core/serviceuser/service.go index c444df865..e7c850a34 100644 --- a/core/serviceuser/service.go +++ b/core/serviceuser/service.go @@ -289,9 +289,6 @@ func (s Service) CreateToken(ctx context.Context, credential Credential) (Token, return Token{}, err } - // encode cred val to hex bytes - credVal := hex.EncodeToString(secretBytes) - // Hash the random bytes using SHA3-256 hash := sha3.Sum256(secretBytes) credential.SecretHash = hex.EncodeToString(hash[:]) @@ -302,6 +299,8 @@ func (s Service) CreateToken(ctx context.Context, credential Credential) (Token, return Token{}, err } + // encode cred val to hex bytes + credVal := hex.EncodeToString(secretBytes) return Token{ ID: createdCred.ID, Title: createdCred.Title, diff --git a/core/webhook/config.go b/core/webhook/config.go new file mode 100644 index 000000000..4f78ed1b7 --- /dev/null +++ b/core/webhook/config.go @@ -0,0 +1,5 @@ +package webhook + +type Config struct { + EncryptionKey string `yaml:"encryption_key" mapstructure:"encryption_key" default:"hash-secret-should-be-32-chars--"` +} diff --git a/core/webhook/errors.go b/core/webhook/errors.go new file mode 100644 index 000000000..0896a291d --- /dev/null +++ b/core/webhook/errors.go @@ -0,0 +1,11 @@ +package webhook + +import "errors" + +var ( + ErrNotFound = errors.New("webhook doesn't exist") + ErrInvalidDetail = errors.New("invalid webhook details") + ErrConflict = errors.New("webhook already exist") + ErrInvalidUUID = errors.New("invalid syntax of uuid") + ErrDisabled = errors.New("webhook is disabled") +) diff --git a/core/webhook/service.go b/core/webhook/service.go new file mode 100644 index 000000000..553962f3a --- /dev/null +++ b/core/webhook/service.go @@ -0,0 +1,167 @@ +package webhook + +import ( + "context" + "fmt" + "time" + + "golang.org/x/exp/slices" + + grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" + frontierv1beta1 "github.com/raystack/frontier/proto/v1beta1" + "go.uber.org/zap" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/go-resty/resty/v2" + "github.com/google/uuid" + "github.com/raystack/frontier/pkg/crypt" +) + +const ( + DefaultSecretID = "1" + SignatureHeader = "X-Signature" + EndpointRetryCount = 3 +) + +type EndpointRepository interface { + Create(ctx context.Context, endpoint Endpoint) (Endpoint, error) + UpdateByID(ctx context.Context, endpoint Endpoint) (Endpoint, error) + Delete(ctx context.Context, id string) error + List(ctx context.Context, filter EndpointFilter) ([]Endpoint, error) +} + +type Service struct { + eRepo EndpointRepository +} + +func NewService(eRepo EndpointRepository) *Service { + return &Service{eRepo: eRepo} +} + +func (s Service) CreateEndpoint(ctx context.Context, endpoint Endpoint) (Endpoint, error) { + if endpoint.ID == "" { + endpoint.ID = uuid.NewString() + } + if endpoint.State == "" { + endpoint.State = Enabled + } + + // generate a random secret in hex + secretHex, err := crypt.NewEncryptionKeyInHex() + if err != nil { + return Endpoint{}, err + } + endpoint.Secrets = append(endpoint.Secrets, Secret{ + ID: DefaultSecretID, + Value: secretHex, + }) + return s.eRepo.Create(ctx, endpoint) +} + +func (s Service) UpdateEndpoint(ctx context.Context, endpoint Endpoint) (Endpoint, error) { + if endpoint.ID == "" { + return Endpoint{}, ErrInvalidUUID + } + updated, err := s.eRepo.UpdateByID(ctx, endpoint) + if err != nil { + return Endpoint{}, err + } + updated.Secrets = nil + return updated, nil +} + +func (s Service) DeleteEndpoint(ctx context.Context, id string) error { + return s.eRepo.Delete(ctx, id) +} + +func (s Service) ListEndpoints(ctx context.Context, filter EndpointFilter) ([]Endpoint, error) { + endpoints, err := s.eRepo.List(ctx, filter) + if err != nil { + return nil, err + } + for i := range endpoints { + endpoints[i].Secrets = nil + } + return endpoints, nil +} + +func (s Service) Publish(ctx context.Context, evt Event) error { + logger := grpczap.Extract(ctx) + endpoints, err := s.eRepo.List(ctx, EndpointFilter{ + State: Enabled, + }) + if err != nil { + return err + } + + data, err := structpb.NewStruct(evt.Data) + if err != nil { + logger.Error("failed to convert data to structpb", zap.Error(err)) + return fmt.Errorf("failed to convert data to structpb: %w", err) + } + event := &frontierv1beta1.WebhookEvent{ + Id: evt.ID, + Action: evt.Action, + Data: data, + CreatedAt: timestamppb.New(evt.CreatedAt), + } + payload, err := protojson.Marshal(event) + if err != nil { + logger.Error("failed to marshal event", zap.Error(err)) + return fmt.Errorf("failed to marshal event: %w", err) + } + + // send event to endpoints + go func() { + var errs []error + for _, endpoint := range endpoints { + if len(endpoint.SubscribedEvents) > 0 && !slices.Contains(endpoint.SubscribedEvents, event.GetAction()) { + continue + } + if len(endpoint.Secrets) == 0 { + errs = append(errs, fmt.Errorf("no secret found for endpoint: %s", endpoint.ID)) + continue + } + + // just use the first secret to sign the payload for now + secret := endpoint.Secrets[0] + signature, err := crypt.GenerateHMACFromHex(payload, secret.Value) + if err != nil { + errs = append(errs, fmt.Errorf("failed to generate HMAC: %w", err)) + continue + } + + requestHeaders := make(map[string]string) + for k, v := range endpoint.Headers { + requestHeaders[k] = v + } + requestHeaders[SignatureHeader] = signatureHeader(signature, secret.ID) + if err := post(endpoint.URL, requestHeaders, payload); err != nil { + errs = append(errs, err) + } + } + if len(errs) > 0 { + logger.Error("failed to send events", zap.Errors("errs", errs)) + } + }() + return nil +} + +func signatureHeader(val string, id string) string { + return fmt.Sprintf("%s=%s", id, val) +} + +func post(url string, headers map[string]string, payload []byte) error { + // post event + client := resty.New(). + SetRetryCount(EndpointRetryCount). + SetRetryWaitTime(3 * time.Second). + SetRetryMaxWaitTime(20 * time.Second). + SetTimeout(3 * time.Second). + SetHeaders(headers) + + _, err := client.R().SetBody(payload).Post(url) + return err +} diff --git a/core/webhook/webhook.go b/core/webhook/webhook.go new file mode 100644 index 000000000..3c336adab --- /dev/null +++ b/core/webhook/webhook.go @@ -0,0 +1,54 @@ +package webhook + +import ( + "time" + + "github.com/raystack/frontier/pkg/metadata" +) + +type State string + +const ( + Enabled State = "enabled" + Disabled State = "disabled" +) + +type Secret struct { + ID string + // Value store the secret value in hex + Value string +} + +type Endpoint struct { + ID string + // Description is the description of the webhook + Description string + // URL is the URL of the webhook + URL string + // SubscribedEvents is the list of events that the webhook is subscribed to + SubscribedEvents []string + // Headers is the headers to be sent with the webhook + Headers map[string]string + // Secrets is the list of secrets to sign the payload + Secrets []Secret + // State is the state of the webhook + State State + + // Metadata is the metadata of the webhook + Metadata metadata.Metadata + // CreatedAt is the creation time of the webhook + CreatedAt time.Time + // UpdatedAt is the update time of the webhook + UpdatedAt time.Time +} + +type Event struct { + ID string + Action string + Data metadata.Metadata + CreatedAt time.Time +} + +type EndpointFilter struct { + State State +} diff --git a/docs/docs/reference/configurations.md b/docs/docs/reference/configurations.md index a70c6acd8..efe8f8d1b 100644 --- a/docs/docs/reference/configurations.md +++ b/docs/docs/reference/configurations.md @@ -136,6 +136,11 @@ app: smtp_insecure: true headers: from: "username@acme.org" + # webhook configuration for sending events to external services + webhook: + # encryption key used to encrypt the secrets stored in database not to encrypt + # the webhook payload + encryption_key: "encryption-key-should-be-32-chars--" db: driver: postgres url: postgres://frontier:@localhost:5432/frontier?sslmode=disable diff --git a/go.mod b/go.mod index 4f6ecf630..94a3e2587 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/doug-martin/goqu/v9 v9.18.0 github.com/envoyproxy/protoc-gen-validate v1.0.2 github.com/ghodss/yaml v1.0.0 + github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 github.com/go-webauthn/webauthn v0.8.6 github.com/golang-migrate/migrate/v4 v4.15.2 github.com/golang/protobuf v1.5.3 @@ -189,7 +190,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/schollz/progressbar/v3 v3.14.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/cast v1.5.1 github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.17.0 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect diff --git a/go.sum b/go.sum index 1a9e0a203..cc62a0248 100644 --- a/go.sum +++ b/go.sum @@ -1112,6 +1112,7 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTM github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 h1:JVrqSeQfdhYRFk24TvhTZWU0q8lfCojxZQFi3Ou7+uY= github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= diff --git a/internal/api/api.go b/internal/api/api.go index 09711d45e..d845d229f 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -30,6 +30,7 @@ import ( "github.com/raystack/frontier/core/role" "github.com/raystack/frontier/core/serviceuser" "github.com/raystack/frontier/core/user" + "github.com/raystack/frontier/core/webhook" "github.com/raystack/frontier/internal/bootstrap" ) @@ -64,6 +65,7 @@ type Deps struct { CreditService *credit.Service UsageService *usage.Service InvoiceService *invoice.Service + WebhookService *webhook.Service LogListener *event.ChanListener } diff --git a/internal/api/v1beta1/v1beta1.go b/internal/api/v1beta1/v1beta1.go index c842f3606..6ad156ada 100644 --- a/internal/api/v1beta1/v1beta1.go +++ b/internal/api/v1beta1/v1beta1.go @@ -41,6 +41,7 @@ type Handler struct { creditService CreditService usageService UsageService invoiceService InvoiceService + webhookService WebhookService } func Register(s *grpc.Server, deps api.Deps, authConf authenticate.Config) { @@ -75,6 +76,7 @@ func Register(s *grpc.Server, deps api.Deps, authConf authenticate.Config) { creditService: deps.CreditService, usageService: deps.UsageService, invoiceService: deps.InvoiceService, + webhookService: deps.WebhookService, } s.RegisterService(&frontierv1beta1.FrontierService_ServiceDesc, handler) s.RegisterService(&frontierv1beta1.AdminService_ServiceDesc, handler) diff --git a/internal/api/v1beta1/webhook.go b/internal/api/v1beta1/webhook.go new file mode 100644 index 000000000..77ccb6cac --- /dev/null +++ b/internal/api/v1beta1/webhook.go @@ -0,0 +1,140 @@ +package v1beta1 + +import ( + "context" + + grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" + "github.com/raystack/frontier/core/webhook" + "github.com/raystack/frontier/pkg/metadata" + frontierv1beta1 "github.com/raystack/frontier/proto/v1beta1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" +) + +type WebhookService interface { + CreateEndpoint(ctx context.Context, endpoint webhook.Endpoint) (webhook.Endpoint, error) + UpdateEndpoint(ctx context.Context, endpoint webhook.Endpoint) (webhook.Endpoint, error) + DeleteEndpoint(ctx context.Context, id string) error + ListEndpoints(ctx context.Context, filter webhook.EndpointFilter) ([]webhook.Endpoint, error) +} + +func (h Handler) CreateWebhook(ctx context.Context, req *frontierv1beta1.CreateWebhookRequest) (*frontierv1beta1.CreateWebhookResponse, error) { + logger := grpczap.Extract(ctx) + + var metaDataMap metadata.Metadata + if req.GetBody().GetMetadata() != nil { + metaDataMap = metadata.Build(req.GetBody().GetMetadata().AsMap()) + } + endpoint, err := h.webhookService.CreateEndpoint(ctx, webhook.Endpoint{ + Description: req.GetBody().GetDescription(), + SubscribedEvents: req.GetBody().GetSubscribedEvents(), + Headers: req.GetBody().GetHeaders(), + URL: req.GetBody().GetUrl(), + State: webhook.State(req.GetBody().GetState()), + Metadata: metaDataMap, + }) + if err != nil { + logger.Error(err.Error()) + return nil, status.Errorf(codes.Internal, err.Error()) + } + endpointPb, err := toProtoWebhookEndpoint(endpoint) + if err != nil { + logger.Error(err.Error()) + return nil, status.Errorf(codes.Internal, err.Error()) + } + return &frontierv1beta1.CreateWebhookResponse{ + Webhook: endpointPb, + }, nil +} + +func (h Handler) UpdateWebhook(ctx context.Context, req *frontierv1beta1.UpdateWebhookRequest) (*frontierv1beta1.UpdateWebhookResponse, error) { + logger := grpczap.Extract(ctx) + + var metaDataMap metadata.Metadata + if req.GetBody().GetMetadata() != nil { + metaDataMap = metadata.Build(req.GetBody().GetMetadata().AsMap()) + } + endpoint, err := h.webhookService.UpdateEndpoint(ctx, webhook.Endpoint{ + ID: req.GetId(), + Description: req.GetBody().GetDescription(), + SubscribedEvents: req.GetBody().GetSubscribedEvents(), + Headers: req.GetBody().GetHeaders(), + URL: req.GetBody().GetUrl(), + State: webhook.State(req.GetBody().GetState()), + Metadata: metaDataMap, + }) + if err != nil { + logger.Error(err.Error()) + return nil, status.Errorf(codes.Internal, err.Error()) + } + endpointPb, err := toProtoWebhookEndpoint(endpoint) + if err != nil { + logger.Error(err.Error()) + return nil, status.Errorf(codes.Internal, err.Error()) + } + return &frontierv1beta1.UpdateWebhookResponse{ + Webhook: endpointPb, + }, nil +} + +func (h Handler) ListWebhooks(ctx context.Context, req *frontierv1beta1.ListWebhooksRequest) (*frontierv1beta1.ListWebhooksResponse, error) { + logger := grpczap.Extract(ctx) + + filter := webhook.EndpointFilter{} + endpoints, err := h.webhookService.ListEndpoints(ctx, filter) + if err != nil { + logger.Error(err.Error()) + return nil, status.Errorf(codes.Internal, err.Error()) + } + var webhooks []*frontierv1beta1.Webhook + for _, endpoint := range endpoints { + endpointPb, err := toProtoWebhookEndpoint(endpoint) + if err != nil { + logger.Error(err.Error()) + return nil, status.Errorf(codes.Internal, err.Error()) + } + webhooks = append(webhooks, endpointPb) + } + return &frontierv1beta1.ListWebhooksResponse{ + Webhooks: webhooks, + }, nil +} + +func (h Handler) DeleteWebhook(ctx context.Context, req *frontierv1beta1.DeleteWebhookRequest) (*frontierv1beta1.DeleteWebhookResponse, error) { + logger := grpczap.Extract(ctx) + + err := h.webhookService.DeleteEndpoint(ctx, req.GetId()) + if err != nil { + logger.Error(err.Error()) + return nil, status.Errorf(codes.Internal, err.Error()) + } + return &frontierv1beta1.DeleteWebhookResponse{}, nil +} + +func toProtoWebhookEndpoint(endpoint webhook.Endpoint) (*frontierv1beta1.Webhook, error) { + metaData, err := endpoint.Metadata.ToStructPB() + if err != nil { + return nil, err + } + + var secrets []*frontierv1beta1.Webhook_Secret + for _, secret := range endpoint.Secrets { + secrets = append(secrets, &frontierv1beta1.Webhook_Secret{ + Id: secret.ID, + Value: secret.Value, + }) + } + return &frontierv1beta1.Webhook{ + Id: endpoint.ID, + Description: endpoint.Description, + SubscribedEvents: endpoint.SubscribedEvents, + Headers: endpoint.Headers, + Url: endpoint.URL, + State: string(endpoint.State), + Metadata: metaData, + Secrets: secrets, + CreatedAt: timestamppb.New(endpoint.CreatedAt), + UpdatedAt: timestamppb.New(endpoint.UpdatedAt), + }, nil +} diff --git a/internal/store/postgres/migrations/20240427034606_webhook_endpoint_table.down.sql b/internal/store/postgres/migrations/20240427034606_webhook_endpoint_table.down.sql new file mode 100644 index 000000000..b46aec296 --- /dev/null +++ b/internal/store/postgres/migrations/20240427034606_webhook_endpoint_table.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS webhook_endpoints; \ No newline at end of file diff --git a/internal/store/postgres/migrations/20240427034606_webhook_endpoint_table.up.sql b/internal/store/postgres/migrations/20240427034606_webhook_endpoint_table.up.sql new file mode 100644 index 000000000..95603af79 --- /dev/null +++ b/internal/store/postgres/migrations/20240427034606_webhook_endpoint_table.up.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS webhook_endpoints ( + id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), + description text, + subscribed_events text[], + headers jsonb NOT NULL DEFAULT '{}'::jsonb, + url text NOT NULL, + secrets text, + state text NOT NULL DEFAULT 'enabled', + metadata jsonb NOT NULL DEFAULT '{}'::jsonb, + created_at timestamptz NOT NULL DEFAULT NOW(), + updated_at timestamptz NOT NULL DEFAULT NOW() +); diff --git a/internal/store/postgres/postgres.go b/internal/store/postgres/postgres.go index 4379af86e..53da3fff3 100644 --- a/internal/store/postgres/postgres.go +++ b/internal/store/postgres/postgres.go @@ -48,6 +48,7 @@ const ( TABLE_BILLING_CHECKOUTS = "billing_checkouts" TABLE_BILLING_TRANSACTIONS = "billing_transactions" TABLE_BILLING_INVOICES = "billing_invoices" + TABLE_WEBHOOK_ENDPOINTS = "webhook_endpoints" ) func checkPostgresError(err error) error { diff --git a/internal/store/postgres/webhook_endpoint.go b/internal/store/postgres/webhook_endpoint.go new file mode 100644 index 000000000..45f7cad6f --- /dev/null +++ b/internal/store/postgres/webhook_endpoint.go @@ -0,0 +1,138 @@ +package postgres + +import ( + "database/sql/driver" + "encoding/base64" + "encoding/json" + "fmt" + "time" + + "github.com/jmoiron/sqlx/types" + "github.com/lib/pq" + "github.com/raystack/frontier/core/webhook" + "github.com/raystack/frontier/pkg/crypt" + "github.com/raystack/frontier/pkg/metadata" +) + +type WebhookHeaders struct { + KVs map[string]string `json:"kvs"` +} + +func (s *WebhookHeaders) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + return json.Unmarshal(src, s) + case string: + return json.Unmarshal([]byte(src), s) + case nil: + return nil + } + return fmt.Errorf("cannot convert %T to JsonB", src) +} + +func (s WebhookHeaders) Value() (driver.Value, error) { + return json.Marshal(s) +} + +func toDBWebHookHeaders(headers map[string]string) WebhookHeaders { + return WebhookHeaders{KVs: headers} +} + +type WebhookSecret struct { + ID string `json:"id"` + Value string `json:"value"` +} + +type WebhookSecrets struct { + Items []WebhookSecret `json:"items"` +} + +func toDBWebHookSecrets(secrets []webhook.Secret, encryptionKey []byte) (string, error) { + var items []WebhookSecret + for _, secret := range secrets { + items = append(items, WebhookSecret{ + ID: secret.ID, + Value: secret.Value, + }) + } + dbSecretRawBytes, err := json.Marshal(WebhookSecrets{Items: items}) + if err != nil { + return "", err + } + dbSecretEncryptedBytes, err := crypt.Encrypt(dbSecretRawBytes, encryptionKey) + if err != nil { + return "", err + } + + // base64 encode the encrypted secret + return base64.RawStdEncoding.EncodeToString(dbSecretEncryptedBytes), nil +} + +func fromDBWebHookSecrets(secrets string, encryptionKey []byte) ([]webhook.Secret, error) { + encryptedBytes, err := base64.RawStdEncoding.DecodeString(secrets) + if err != nil { + return nil, err + } + decryptedSecrets, err := crypt.Decrypt(encryptedBytes, encryptionKey) + if err != nil { + return nil, err + } + var dbSecrets WebhookSecrets + if err := json.Unmarshal(decryptedSecrets, &dbSecrets); err != nil { + return nil, err + } + var secretsList []webhook.Secret + for _, secret := range dbSecrets.Items { + secretsList = append(secretsList, webhook.Secret{ + ID: secret.ID, + Value: secret.Value, + }) + } + return secretsList, nil +} + +type WebhookEndpoint struct { + ID string `db:"id"` + Description *string `db:"description"` + SubscribedEvents pq.StringArray `db:"subscribed_events"` + Headers WebhookHeaders `db:"headers"` + Url string `db:"url"` + Secrets string `db:"secrets"` + + State string `db:"state"` + Metadata types.NullJSONText `db:"metadata"` + + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` +} + +func (i WebhookEndpoint) transform(encryptionKey []byte) (webhook.Endpoint, error) { + var unmarshalledMetadata metadata.Metadata + if i.Metadata.Valid { + if err := i.Metadata.Unmarshal(&unmarshalledMetadata); err != nil { + return webhook.Endpoint{}, err + } + } + var description string + if i.Description != nil { + description = *i.Description + } + secrets, err := fromDBWebHookSecrets(i.Secrets, encryptionKey) + if err != nil { + return webhook.Endpoint{}, err + } + return webhook.Endpoint{ + ID: i.ID, + Description: description, + SubscribedEvents: i.SubscribedEvents, + Secrets: secrets, + URL: i.Url, + Headers: i.Headers.KVs, + + State: webhook.State(i.State), + Metadata: unmarshalledMetadata, + + CreatedAt: i.CreatedAt, + UpdatedAt: i.UpdatedAt, + }, nil +} diff --git a/internal/store/postgres/webhook_endpoint_repository.go b/internal/store/postgres/webhook_endpoint_repository.go new file mode 100644 index 000000000..4362c7c78 --- /dev/null +++ b/internal/store/postgres/webhook_endpoint_repository.go @@ -0,0 +1,191 @@ +package postgres + +import ( + "context" + "database/sql" + "encoding/json" + "errors" + "fmt" + "strings" + + "github.com/doug-martin/goqu/v9" + "github.com/google/uuid" + "github.com/lib/pq" + "github.com/raystack/frontier/core/webhook" + "github.com/raystack/frontier/pkg/db" +) + +type WebhookEndpointRepository struct { + dbc *db.Client + encryptionKey []byte +} + +func NewWebhookEndpointRepository(dbc *db.Client, encryptionKey []byte) *WebhookEndpointRepository { + return &WebhookEndpointRepository{ + dbc: dbc, + encryptionKey: encryptionKey, + } +} + +func (r WebhookEndpointRepository) Create(ctx context.Context, toCreate webhook.Endpoint) (webhook.Endpoint, error) { + if toCreate.ID == "" { + toCreate.ID = uuid.New().String() + } + if toCreate.Metadata == nil { + toCreate.Metadata = make(map[string]any) + } + marshaledMetadata, err := json.Marshal(toCreate.Metadata) + if err != nil { + return webhook.Endpoint{}, err + } + secretString, err := toDBWebHookSecrets(toCreate.Secrets, r.encryptionKey) + if err != nil { + return webhook.Endpoint{}, fmt.Errorf("failed to encrypt webhook secrets: %w", err) + } + if toCreate.State == "" { + toCreate.State = webhook.Enabled + } + + query, params, err := dialect.Insert(TABLE_WEBHOOK_ENDPOINTS).Rows( + goqu.Record{ + "id": toCreate.ID, + "description": toCreate.Description, + "subscribed_events": pq.StringArray(toCreate.SubscribedEvents), + "secrets": secretString, + "headers": toDBWebHookHeaders(toCreate.Headers), + "url": toCreate.URL, + "state": toCreate.State, + "metadata": marshaledMetadata, + "created_at": goqu.L("now()"), + "updated_at": goqu.L("now()"), + }).Returning(&WebhookEndpoint{}).ToSQL() + if err != nil { + return webhook.Endpoint{}, fmt.Errorf("%w: %s", parseErr, err) + } + + var endpointModel WebhookEndpoint + if err = r.dbc.WithTimeout(ctx, TABLE_WEBHOOK_ENDPOINTS, "Create", func(ctx context.Context) error { + return r.dbc.QueryRowxContext(ctx, query, params...).StructScan(&endpointModel) + }); err != nil { + return webhook.Endpoint{}, fmt.Errorf("%w: %s", dbErr, err) + } + + return endpointModel.transform(r.encryptionKey) +} + +func (r WebhookEndpointRepository) GetByID(ctx context.Context, id string) (webhook.Endpoint, error) { + stmt := dialect.Select().From(TABLE_WEBHOOK_ENDPOINTS).Where(goqu.Ex{ + "id": id, + }) + query, params, err := stmt.ToSQL() + if err != nil { + return webhook.Endpoint{}, fmt.Errorf("%w: %s", parseErr, err) + } + + var endpointModel WebhookEndpoint + if err = r.dbc.WithTimeout(ctx, TABLE_WEBHOOK_ENDPOINTS, "GetByID", func(ctx context.Context) error { + return r.dbc.QueryRowxContext(ctx, query, params...).StructScan(&endpointModel) + }); err != nil { + err = checkPostgresError(err) + switch { + case errors.Is(err, sql.ErrNoRows): + return webhook.Endpoint{}, webhook.ErrNotFound + } + return webhook.Endpoint{}, fmt.Errorf("%w: %s", dbErr, err) + } + + return endpointModel.transform(r.encryptionKey) +} + +func (r WebhookEndpointRepository) List(ctx context.Context, flt webhook.EndpointFilter) ([]webhook.Endpoint, error) { + stmt := dialect.Select().From(TABLE_WEBHOOK_ENDPOINTS).Order(goqu.I("created_at").Desc()) + if flt.State != "" { + stmt = stmt.Where(goqu.Ex{ + "state": flt.State, + }) + } + query, params, err := stmt.ToSQL() + if err != nil { + return nil, fmt.Errorf("%w: %s", parseErr, err) + } + + var endpointModels []WebhookEndpoint + if err = r.dbc.WithTimeout(ctx, TABLE_WEBHOOK_ENDPOINTS, "List", func(ctx context.Context) error { + return r.dbc.SelectContext(ctx, &endpointModels, query, params...) + }); err != nil { + return nil, fmt.Errorf("%w: %s", dbErr, err) + } + + endpoints := make([]webhook.Endpoint, 0, len(endpointModels)) + for _, endpointModel := range endpointModels { + endpoint, err := endpointModel.transform(r.encryptionKey) + if err != nil { + return nil, err + } + endpoints = append(endpoints, endpoint) + } + return endpoints, nil +} + +func (r WebhookEndpointRepository) UpdateByID(ctx context.Context, toUpdate webhook.Endpoint) (webhook.Endpoint, error) { + if strings.TrimSpace(toUpdate.ID) == "" { + return webhook.Endpoint{}, webhook.ErrInvalidDetail + } + + updateRecord := goqu.Record{ + "description": toUpdate.Description, + "subscribed_events": pq.StringArray(toUpdate.SubscribedEvents), + "url": toUpdate.URL, + "headers": toDBWebHookHeaders(toUpdate.Headers), + "updated_at": goqu.L("now()"), + } + if toUpdate.Metadata != nil { + marshaledMetadata, err := json.Marshal(toUpdate.Metadata) + if err != nil { + return webhook.Endpoint{}, fmt.Errorf("%w: %s", parseErr, err) + } + updateRecord["metadata"] = marshaledMetadata + } + if toUpdate.State != "" { + updateRecord["state"] = toUpdate.State + } + + query, params, err := dialect.Update(TABLE_WEBHOOK_ENDPOINTS).Set(updateRecord).Where(goqu.Ex{ + "id": toUpdate.ID, + }).Returning(&WebhookEndpoint{}).ToSQL() + if err != nil { + return webhook.Endpoint{}, fmt.Errorf("%w: %s", queryErr, err) + } + + var endpointModel WebhookEndpoint + if err = r.dbc.WithTimeout(ctx, TABLE_WEBHOOK_ENDPOINTS, "UpdateByID", func(ctx context.Context) error { + return r.dbc.QueryRowxContext(ctx, query, params...).StructScan(&endpointModel) + }); err != nil { + err = checkPostgresError(err) + switch { + case errors.Is(err, sql.ErrNoRows): + return webhook.Endpoint{}, webhook.ErrNotFound + default: + return webhook.Endpoint{}, fmt.Errorf("%s: %w", txnErr, err) + } + } + + return endpointModel.transform(r.encryptionKey) +} + +func (r WebhookEndpointRepository) Delete(ctx context.Context, id string) error { + query, params, err := dialect.Delete(TABLE_WEBHOOK_ENDPOINTS).Where(goqu.Ex{ + "id": id, + }).ToSQL() + if err != nil { + return fmt.Errorf("%w: %s", queryErr, err) + } + + if err = r.dbc.WithTimeout(ctx, TABLE_WEBHOOK_ENDPOINTS, "Delete", func(ctx context.Context) error { + _, err := r.dbc.ExecContext(ctx, query, params...) + return err + }); err != nil { + return fmt.Errorf("%s: %w", txnErr, err) + } + return nil +} diff --git a/internal/store/postgres/webhook_endpoint_repository_test.go b/internal/store/postgres/webhook_endpoint_repository_test.go new file mode 100644 index 000000000..821fc1b3a --- /dev/null +++ b/internal/store/postgres/webhook_endpoint_repository_test.go @@ -0,0 +1,246 @@ +package postgres_test + +import ( + "context" + "fmt" + "testing" + + "github.com/raystack/frontier/core/webhook" + "github.com/raystack/frontier/pkg/metadata" + + "github.com/google/uuid" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/ory/dockertest" + "github.com/raystack/frontier/internal/store/postgres" + "github.com/raystack/frontier/pkg/db" + "github.com/raystack/salt/log" + "github.com/stretchr/testify/suite" +) + +type WebhookEndpointRepositoryTestSuite struct { + suite.Suite + ctx context.Context + client *db.Client + pool *dockertest.Pool + resource *dockertest.Resource + repository *postgres.WebhookEndpointRepository +} + +func (s *WebhookEndpointRepositoryTestSuite) SetupSuite() { + var err error + + logger := log.NewZap() + s.client, s.pool, s.resource, err = newTestClient(logger) + if err != nil { + s.T().Fatal(err) + } + + s.ctx = context.TODO() + s.repository = postgres.NewWebhookEndpointRepository(s.client, []byte("kmm4ECoWU21K2ZoyTcYLd6w7DfhoUoap")) +} + +func (s *WebhookEndpointRepositoryTestSuite) SetupTest() { +} + +func (s *WebhookEndpointRepositoryTestSuite) TearDownSuite() { + // Clean tests + if err := purgeDocker(s.pool, s.resource); err != nil { + s.T().Fatal(err) + } +} + +func (s *WebhookEndpointRepositoryTestSuite) TearDownTest() { + if err := s.cleanup(); err != nil { + s.T().Fatal(err) + } +} + +func (s *WebhookEndpointRepositoryTestSuite) cleanup() error { + queries := []string{ + fmt.Sprintf("TRUNCATE TABLE %s RESTART IDENTITY CASCADE", postgres.TABLE_WEBHOOK_ENDPOINTS), + } + return execQueries(context.TODO(), s.client, queries) +} + +func (s *WebhookEndpointRepositoryTestSuite) TestCreate() { + type testCase struct { + Description string + ToCreate webhook.Endpoint + Expected webhook.Endpoint + ErrString string + } + + var testCases = []testCase{ + { + Description: "should create a webhook", + ToCreate: webhook.Endpoint{ + ID: uuid.NewString(), + Description: "web1", + URL: "http://localhost:8080", + Headers: map[string]string{ + "Content-Type": "application/json", + }, + SubscribedEvents: []string{"event1", "event2"}, + Secrets: []webhook.Secret{ + { + ID: "secret1", + Value: "value1", + }, + }, + }, + Expected: webhook.Endpoint{ + Description: "web1", + URL: "http://localhost:8080", + Headers: map[string]string{ + "Content-Type": "application/json", + }, + SubscribedEvents: []string{"event1", "event2"}, + Secrets: []webhook.Secret{ + { + ID: "secret1", + Value: "value1", + }, + }, + State: webhook.Enabled, + Metadata: metadata.Metadata{}, + }, + }, + } + + for _, tc := range testCases { + s.Run(tc.Description, func() { + got, err := s.repository.Create(s.ctx, tc.ToCreate) + if tc.ErrString != "" { + if err.Error() != tc.ErrString { + s.T().Fatalf("got error %s, expected was %s", err.Error(), tc.ErrString) + } + } + if tc.ErrString == "" { + s.Assert().NoError(err) + } + if diff := cmp.Diff(tc.Expected, got, cmpopts.IgnoreFields(webhook.Endpoint{}, "ID", "CreatedAt", "UpdatedAt")); diff != "" { + s.T().Fatalf("expected -, got +:\n%s", diff) + } + }) + } +} + +func (s *WebhookEndpointRepositoryTestSuite) TestList() { + type testCase struct { + Description string + Expected []webhook.Endpoint + ErrString string + } + + created1, err := s.repository.Create(s.ctx, webhook.Endpoint{ + ID: uuid.NewString(), + Description: "web1", + URL: "http://localhost:8080", + State: webhook.Enabled, + }) + s.Assert().NoError(err) + created2, err := s.repository.Create(s.ctx, webhook.Endpoint{ + ID: uuid.NewString(), + Description: "web2", + URL: "http://localhost:8080", + State: webhook.Disabled, + }) + s.Assert().NoError(err) + + var testCases = []testCase{ + { + Description: "should get all webhooks", + Expected: []webhook.Endpoint{ + created2, + created1, + }, + }, + } + + for _, tc := range testCases { + s.Run(tc.Description, func() { + got, err := s.repository.List(s.ctx, webhook.EndpointFilter{}) + if tc.ErrString != "" { + if err.Error() != tc.ErrString { + s.T().Fatalf("got error %s, expected was %s", err.Error(), tc.ErrString) + } + } + if tc.ErrString == "" { + s.Assert().NoError(err) + } + if diff := cmp.Diff(tc.Expected, got, cmpopts.IgnoreFields(webhook.Endpoint{}, "ID", "CreatedAt", "UpdatedAt")); diff != "" { + s.T().Fatalf("expected (-), got (+):\n%s", diff) + } + }) + } +} + +func (s *WebhookEndpointRepositoryTestSuite) TestUpdateByID() { + type testCase struct { + Description string + ToUpdate webhook.Endpoint + Expected webhook.Endpoint + ErrString string + } + + created1, err := s.repository.Create(s.ctx, webhook.Endpoint{ + ID: uuid.NewString(), + Description: "web1", + URL: "http://localhost:8080", + State: webhook.Enabled, + }) + s.Assert().NoError(err) + + var testCases = []testCase{ + { + Description: "should return error if webhook not found", + ToUpdate: webhook.Endpoint{ + ID: uuid.New().String(), + Description: "not-exist", + }, + ErrString: webhook.ErrNotFound.Error(), + }, + { + Description: "should return error if webhook id is empty", + ErrString: webhook.ErrInvalidDetail.Error(), + }, + { + Description: "should update webhook", + ToUpdate: webhook.Endpoint{ + ID: created1.ID, + Description: "web1-updated", + URL: "http://localhost:8080", + }, + Expected: webhook.Endpoint{ + ID: created1.ID, + Description: "web1-updated", + URL: "http://localhost:8080", + State: webhook.Enabled, + Metadata: metadata.Metadata{}, + }, + }, + } + + for _, tc := range testCases { + s.Run(tc.Description, func() { + got, err := s.repository.UpdateByID(s.ctx, tc.ToUpdate) + if tc.ErrString != "" { + if err.Error() != tc.ErrString { + s.T().Fatalf("got error %s, expected was %s", err.Error(), tc.ErrString) + } + } + if tc.ErrString == "" { + s.Assert().NoError(err) + } + if diff := cmp.Diff(tc.Expected, got, cmpopts.IgnoreFields(webhook.Endpoint{}, "ID", "CreatedAt", "UpdatedAt")); diff != "" { + s.T().Fatalf("expected -, got +:\n%s", diff) + } + }) + } +} + +func TestWebhookEndpointRepository(t *testing.T) { + suite.Run(t, new(WebhookEndpointRepositoryTestSuite)) +} diff --git a/pkg/crypt/aes.go b/pkg/crypt/aes.go new file mode 100644 index 000000000..6b33ecd8d --- /dev/null +++ b/pkg/crypt/aes.go @@ -0,0 +1,79 @@ +package crypt + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/hex" + "fmt" + "io" +) + +// Encrypt encrypts data using 256-bit AES-GCM. +func Encrypt(plaintext []byte, key []byte) (ciphertext []byte, err error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + nonce := make([]byte, gcm.NonceSize()) + _, err = io.ReadFull(rand.Reader, nonce) + if err != nil { + return nil, err + } + + return gcm.Seal(nonce, nonce, plaintext, nil), nil +} + +func EncryptAndHex(plaintext []byte, hexKey string) (string, error) { + key, err := hex.DecodeString(hexKey) + if err != nil { + return "", err + } + ciphertext, err := Encrypt(plaintext, key) + if err != nil { + return "", err + } + return hex.EncodeToString(ciphertext), nil +} + +// Decrypt decrypts data using 256-bit AES-GCM. +func Decrypt(ciphertext []byte, key []byte) (plaintext []byte, err error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + if len(ciphertext) < gcm.NonceSize() { + return nil, fmt.Errorf("malformed ciphertext: nonce mismatch") + } + + return gcm.Open(nil, + ciphertext[:gcm.NonceSize()], + ciphertext[gcm.NonceSize():], + nil, + ) +} + +func DecryptFromHex(hexCiphertext string, hexKey string) ([]byte, error) { + key, err := hex.DecodeString(hexKey) + if err != nil { + return nil, err + } + + ciphertext, err := hex.DecodeString(hexCiphertext) + if err != nil { + return nil, err + } + return Decrypt(ciphertext, key) +} diff --git a/pkg/crypt/hmac.go b/pkg/crypt/hmac.go new file mode 100644 index 000000000..fdcfd42bf --- /dev/null +++ b/pkg/crypt/hmac.go @@ -0,0 +1,43 @@ +package crypt + +import ( + "crypto/hmac" + "crypto/sha512" + "encoding/hex" +) + +// GenerateHMAC produces a SHA-512/256 hash using 256-bit key +func GenerateHMAC(data []byte, key []byte) []byte { + h := hmac.New(sha512.New512_256, key) + h.Write(data) + return h.Sum(nil) +} + +// GenerateHMACFromHex produces a SHA-512/256 hash using 256-bit key +func GenerateHMACFromHex(data []byte, hexKey string) (string, error) { + key, err := hex.DecodeString(hexKey) + if err != nil { + return "", err + } + result := GenerateHMAC(data, key) + return hex.EncodeToString(result), nil +} + +// VerifyHMAC checks the supplied MAC against the hash of the data using the key +func VerifyHMAC(data []byte, key []byte, suppliedMAC []byte) bool { + expectedMAC := GenerateHMAC(data, key) + return hmac.Equal(expectedMAC, suppliedMAC) +} + +// VerifyHMACFromHex checks the supplied MAC against the hash of the data using the key +func VerifyHMACFromHex(data []byte, hexKey string, suppliedHexMAC string) (bool, error) { + key, err := hex.DecodeString(hexKey) + if err != nil { + return false, err + } + suppliedMAC, err := hex.DecodeString(suppliedHexMAC) + if err != nil { + return false, err + } + return VerifyHMAC(data, key, suppliedMAC), nil +} diff --git a/pkg/crypt/key.go b/pkg/crypt/key.go new file mode 100644 index 000000000..ffe5ec5cd --- /dev/null +++ b/pkg/crypt/key.go @@ -0,0 +1,25 @@ +package crypt + +import ( + "crypto/rand" + "encoding/hex" + "io" +) + +// NewEncryptionKey generates a random 256-bit key +func NewEncryptionKey() (*[32]byte, error) { + key := [32]byte{} + _, err := io.ReadFull(rand.Reader, key[:]) + if err != nil { + return nil, err + } + return &key, nil +} + +func NewEncryptionKeyInHex() (string, error) { + key, err := NewEncryptionKey() + if err != nil { + return "", err + } + return hex.EncodeToString(key[:]), nil +} diff --git a/pkg/server/config.go b/pkg/server/config.go index 38e8b2161..4a808e96a 100644 --- a/pkg/server/config.go +++ b/pkg/server/config.go @@ -3,6 +3,8 @@ package server import ( "fmt" + "github.com/raystack/frontier/core/webhook" + "github.com/raystack/frontier/pkg/server/interceptors" "github.com/raystack/frontier/pkg/mailer" @@ -63,4 +65,6 @@ type Config struct { Admin bootstrap.AdminConfig `yaml:"admin" mapstructure:"admin"` Mailer mailer.Config `yaml:"mailer" mapstructure:"mailer"` + + Webhook webhook.Config `yaml:"webhook" mapstructure:"webhook"` } diff --git a/pkg/server/interceptors/authorization.go b/pkg/server/interceptors/authorization.go index 28c2056d5..58d0654dd 100644 --- a/pkg/server/interceptors/authorization.go +++ b/pkg/server/interceptors/authorization.go @@ -941,6 +941,18 @@ var authorizationValidationMap = map[string]func(ctx context.Context, handler *v "/raystack.frontier.v1beta1.AdminService/RevertBillingUsage": func(ctx context.Context, handler *v1beta1.Handler, req any) error { return handler.IsAuthorized(ctx, relation.Object{Namespace: schema.PlatformNamespace, ID: schema.PlatformID}, schema.PlatformCheckPermission) }, + "/raystack.frontier.v1beta1.AdminService/CreateWebhook": func(ctx context.Context, handler *v1beta1.Handler, req any) error { + return handler.IsSuperUser(ctx) + }, + "/raystack.frontier.v1beta1.AdminService/ListWebhooks": func(ctx context.Context, handler *v1beta1.Handler, req any) error { + return handler.IsSuperUser(ctx) + }, + "/raystack.frontier.v1beta1.AdminService/UpdateWebhook": func(ctx context.Context, handler *v1beta1.Handler, req any) error { + return handler.IsSuperUser(ctx) + }, + "/raystack.frontier.v1beta1.AdminService/DeleteWebhook": func(ctx context.Context, handler *v1beta1.Handler, req any) error { + return handler.IsSuperUser(ctx) + }, } func ensureSubscriptionBelongToOrg(ctx context.Context, handler *v1beta1.Handler, orgID, billingID, subID string) error { diff --git a/pkg/webhook/validate.go b/pkg/webhook/validate.go new file mode 100644 index 000000000..1ae838587 --- /dev/null +++ b/pkg/webhook/validate.go @@ -0,0 +1,39 @@ +package webhook + +import ( + "fmt" + "time" + + "github.com/raystack/frontier/pkg/crypt" + frontierv1beta1 "github.com/raystack/frontier/proto/v1beta1" + "google.golang.org/protobuf/encoding/protojson" +) + +var ( + ErrInvalidEvent = fmt.Errorf("invalid event") + ErrInvalidSignature = fmt.Errorf("invalid signature") + ErrVerificationFailed = fmt.Errorf("verification failed") + ErrTimestampExpired = fmt.Errorf("timestamp expired") + + EventExpiryDuration = time.Minute * 10 +) + +func ParseAndValidateEvent(data []byte, hexKey string, suppliedHexMAC string) (*frontierv1beta1.WebhookEvent, error) { + validHmac, err := crypt.VerifyHMACFromHex(data, hexKey, suppliedHexMAC) + if err != nil { + return nil, fmt.Errorf("%s: %w", err.Error(), ErrVerificationFailed) + } + if !validHmac { + return nil, ErrInvalidSignature + } + var event frontierv1beta1.WebhookEvent + if err := protojson.Unmarshal(data, &event); err != nil { + return nil, fmt.Errorf("%s: %w", err.Error(), ErrInvalidEvent) + } + + // Check if the event is not older than N minutes + if event.GetCreatedAt() == nil || event.GetCreatedAt().AsTime().Before(time.Now().Add(-EventExpiryDuration)) { + return nil, ErrTimestampExpired + } + return &event, nil +} diff --git a/proto/apidocs.swagger.yaml b/proto/apidocs.swagger.yaml index 879c11fb1..b3c9d5065 100644 --- a/proto/apidocs.swagger.yaml +++ b/proto/apidocs.swagger.yaml @@ -703,6 +703,174 @@ paths: type: string tags: - User + /v1beta1/admin/webhooks: + get: + summary: List webhooks + description: List all webhooks. + operationId: AdminService_ListWebhooks + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/v1beta1ListWebhooksResponse' + "400": + description: Bad Request - The request was malformed or contained invalid parameters. + schema: + $ref: '#/definitions/rpcStatus' + "401": + description: Unauthorized - Authentication is required + schema: + $ref: '#/definitions/rpcStatus' + "403": + description: Forbidden - User does not have permission to access the resource + schema: + $ref: '#/definitions/rpcStatus' + "404": + description: Not Found - The requested resource was not found + schema: + $ref: '#/definitions/rpcStatus' + "500": + description: Internal Server Error. Returned when theres is something wrong with Frontier server. + schema: + $ref: '#/definitions/rpcStatus' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpcStatus' + tags: + - Webhook + post: + summary: Create webhook + description: Create a new webhook. + operationId: AdminService_CreateWebhook + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/v1beta1CreateWebhookResponse' + "400": + description: Bad Request - The request was malformed or contained invalid parameters. + schema: + $ref: '#/definitions/rpcStatus' + "401": + description: Unauthorized - Authentication is required + schema: + $ref: '#/definitions/rpcStatus' + "403": + description: Forbidden - User does not have permission to access the resource + schema: + $ref: '#/definitions/rpcStatus' + "404": + description: Not Found - The requested resource was not found + schema: + $ref: '#/definitions/rpcStatus' + "500": + description: Internal Server Error. Returned when theres is something wrong with Frontier server. + schema: + $ref: '#/definitions/rpcStatus' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpcStatus' + parameters: + - name: body + in: body + required: true + schema: + $ref: '#/definitions/v1beta1CreateWebhookRequest' + tags: + - Webhook + /v1beta1/admin/webhooks/{id}: + delete: + summary: Delete webhook + description: Delete a webhook. + operationId: AdminService_DeleteWebhook + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/v1beta1DeleteWebhookResponse' + "400": + description: Bad Request - The request was malformed or contained invalid parameters. + schema: + $ref: '#/definitions/rpcStatus' + "401": + description: Unauthorized - Authentication is required + schema: + $ref: '#/definitions/rpcStatus' + "403": + description: Forbidden - User does not have permission to access the resource + schema: + $ref: '#/definitions/rpcStatus' + "404": + description: Not Found - The requested resource was not found + schema: + $ref: '#/definitions/rpcStatus' + "500": + description: Internal Server Error. Returned when theres is something wrong with Frontier server. + schema: + $ref: '#/definitions/rpcStatus' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpcStatus' + parameters: + - name: id + description: The webhook id to delete. + in: path + required: true + type: string + tags: + - Webhook + put: + summary: Update webhook + description: Update a webhook. + operationId: AdminService_UpdateWebhook + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/v1beta1UpdateWebhookResponse' + "400": + description: Bad Request - The request was malformed or contained invalid parameters. + schema: + $ref: '#/definitions/rpcStatus' + "401": + description: Unauthorized - Authentication is required + schema: + $ref: '#/definitions/rpcStatus' + "403": + description: Forbidden - User does not have permission to access the resource + schema: + $ref: '#/definitions/rpcStatus' + "404": + description: Not Found - The requested resource was not found + schema: + $ref: '#/definitions/rpcStatus' + "500": + description: Internal Server Error. Returned when theres is something wrong with Frontier server. + schema: + $ref: '#/definitions/rpcStatus' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpcStatus' + parameters: + - name: id + description: The webhook id to update. + in: path + required: true + type: string + - name: body + in: body + required: true + schema: + type: object + properties: + body: + $ref: '#/definitions/v1beta1WebhookRequestBody' + tags: + - Webhook /v1beta1/auth: get: summary: List authentication strategies @@ -8758,6 +8926,13 @@ definitions: format: date-time plan_id: type: string + WebhookSecret: + type: object + properties: + id: + type: string + value: + type: string protobufAny: type: object properties: @@ -9425,6 +9600,16 @@ definitions: properties: user: $ref: '#/definitions/v1beta1User' + v1beta1CreateWebhookRequest: + type: object + properties: + body: + $ref: '#/definitions/v1beta1WebhookRequestBody' + v1beta1CreateWebhookResponse: + type: object + properties: + webhook: + $ref: '#/definitions/v1beta1Webhook' v1beta1DelegatedCheckoutResponse: type: object properties: @@ -9470,6 +9655,8 @@ definitions: type: object v1beta1DeleteUserResponse: type: object + v1beta1DeleteWebhookResponse: + type: object v1beta1DescribePreferencesResponse: type: object properties: @@ -10495,6 +10682,14 @@ definitions: items: type: object $ref: '#/definitions/v1beta1User' + v1beta1ListWebhooksResponse: + type: object + properties: + webhooks: + type: array + items: + type: object + $ref: '#/definitions/v1beta1Webhook' v1beta1MetaSchema: type: object properties: @@ -11395,6 +11590,11 @@ definitions: properties: user: $ref: '#/definitions/v1beta1User' + v1beta1UpdateWebhookResponse: + type: object + properties: + webhook: + $ref: '#/definitions/v1beta1Webhook' v1beta1Usage: type: object properties: @@ -11489,6 +11689,64 @@ definitions: properties: state: type: string + v1beta1Webhook: + type: object + properties: + id: + type: string + description: + type: string + url: + type: string + subscribed_events: + type: array + items: + type: string + headers: + type: object + additionalProperties: + type: string + title: headers to be sent with the webhook + secrets: + type: array + items: + type: object + $ref: '#/definitions/WebhookSecret' + title: |- + secret to sign the payload, there could be multiple enabled secrets for a webhook + but only one will be used to sign the payload, this is useful for rotating secrets + state: + type: string + metadata: + type: object + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + v1beta1WebhookRequestBody: + type: object + properties: + url: + type: string + title: URL to send the webhook to (valid absolute URI via RFC 3986) + description: + type: string + subscribed_events: + type: array + items: + type: string + title: events to subscribe to, if empty all events are subscribed + headers: + type: object + additionalProperties: + type: string + title: headers to be sent with the webhook + state: + type: string + metadata: + type: object securityDefinitions: Basic: type: basic diff --git a/proto/v1beta1/admin.pb.go b/proto/v1beta1/admin.pb.go index 6883c1b11..bb8c6569f 100644 --- a/proto/v1beta1/admin.pb.go +++ b/proto/v1beta1/admin.pb.go @@ -2265,6 +2265,462 @@ func (*RevertBillingUsageResponse) Descriptor() ([]byte, []int) { return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{42} } +type WebhookRequestBody struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // URL to send the webhook to (valid absolute URI via RFC 3986) + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // events to subscribe to, if empty all events are subscribed + SubscribedEvents []string `protobuf:"bytes,3,rep,name=subscribed_events,json=subscribedEvents,proto3" json:"subscribed_events,omitempty"` + // headers to be sent with the webhook + Headers map[string]string `protobuf:"bytes,4,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + State string `protobuf:"bytes,5,opt,name=state,proto3" json:"state,omitempty"` + Metadata *structpb.Struct `protobuf:"bytes,20,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *WebhookRequestBody) Reset() { + *x = WebhookRequestBody{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WebhookRequestBody) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WebhookRequestBody) ProtoMessage() {} + +func (x *WebhookRequestBody) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WebhookRequestBody.ProtoReflect.Descriptor instead. +func (*WebhookRequestBody) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{43} +} + +func (x *WebhookRequestBody) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *WebhookRequestBody) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *WebhookRequestBody) GetSubscribedEvents() []string { + if x != nil { + return x.SubscribedEvents + } + return nil +} + +func (x *WebhookRequestBody) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + +func (x *WebhookRequestBody) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *WebhookRequestBody) GetMetadata() *structpb.Struct { + if x != nil { + return x.Metadata + } + return nil +} + +type CreateWebhookRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *WebhookRequestBody `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` +} + +func (x *CreateWebhookRequest) Reset() { + *x = CreateWebhookRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateWebhookRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateWebhookRequest) ProtoMessage() {} + +func (x *CreateWebhookRequest) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateWebhookRequest.ProtoReflect.Descriptor instead. +func (*CreateWebhookRequest) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{44} +} + +func (x *CreateWebhookRequest) GetBody() *WebhookRequestBody { + if x != nil { + return x.Body + } + return nil +} + +type CreateWebhookResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Webhook *Webhook `protobuf:"bytes,1,opt,name=webhook,proto3" json:"webhook,omitempty"` +} + +func (x *CreateWebhookResponse) Reset() { + *x = CreateWebhookResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateWebhookResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateWebhookResponse) ProtoMessage() {} + +func (x *CreateWebhookResponse) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateWebhookResponse.ProtoReflect.Descriptor instead. +func (*CreateWebhookResponse) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{45} +} + +func (x *CreateWebhookResponse) GetWebhook() *Webhook { + if x != nil { + return x.Webhook + } + return nil +} + +type UpdateWebhookRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Body *WebhookRequestBody `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"` +} + +func (x *UpdateWebhookRequest) Reset() { + *x = UpdateWebhookRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateWebhookRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateWebhookRequest) ProtoMessage() {} + +func (x *UpdateWebhookRequest) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[46] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateWebhookRequest.ProtoReflect.Descriptor instead. +func (*UpdateWebhookRequest) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{46} +} + +func (x *UpdateWebhookRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateWebhookRequest) GetBody() *WebhookRequestBody { + if x != nil { + return x.Body + } + return nil +} + +type UpdateWebhookResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Webhook *Webhook `protobuf:"bytes,1,opt,name=webhook,proto3" json:"webhook,omitempty"` +} + +func (x *UpdateWebhookResponse) Reset() { + *x = UpdateWebhookResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateWebhookResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateWebhookResponse) ProtoMessage() {} + +func (x *UpdateWebhookResponse) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[47] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateWebhookResponse.ProtoReflect.Descriptor instead. +func (*UpdateWebhookResponse) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{47} +} + +func (x *UpdateWebhookResponse) GetWebhook() *Webhook { + if x != nil { + return x.Webhook + } + return nil +} + +type DeleteWebhookRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteWebhookRequest) Reset() { + *x = DeleteWebhookRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteWebhookRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteWebhookRequest) ProtoMessage() {} + +func (x *DeleteWebhookRequest) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[48] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteWebhookRequest.ProtoReflect.Descriptor instead. +func (*DeleteWebhookRequest) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{48} +} + +func (x *DeleteWebhookRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type DeleteWebhookResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteWebhookResponse) Reset() { + *x = DeleteWebhookResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteWebhookResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteWebhookResponse) ProtoMessage() {} + +func (x *DeleteWebhookResponse) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[49] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteWebhookResponse.ProtoReflect.Descriptor instead. +func (*DeleteWebhookResponse) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{49} +} + +type ListWebhooksRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListWebhooksRequest) Reset() { + *x = ListWebhooksRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListWebhooksRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListWebhooksRequest) ProtoMessage() {} + +func (x *ListWebhooksRequest) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[50] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListWebhooksRequest.ProtoReflect.Descriptor instead. +func (*ListWebhooksRequest) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{50} +} + +type ListWebhooksResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Webhooks []*Webhook `protobuf:"bytes,1,rep,name=webhooks,proto3" json:"webhooks,omitempty"` +} + +func (x *ListWebhooksResponse) Reset() { + *x = ListWebhooksResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListWebhooksResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListWebhooksResponse) ProtoMessage() {} + +func (x *ListWebhooksResponse) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_admin_proto_msgTypes[51] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListWebhooksResponse.ProtoReflect.Descriptor instead. +func (*ListWebhooksResponse) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP(), []int{51} +} + +func (x *ListWebhooksResponse) GetWebhooks() []*Webhook { + if x != nil { + return x.Webhooks + } + return nil +} + var File_raystack_frontier_v1beta1_admin_proto protoreflect.FileDescriptor var file_raystack_frontier_v1beta1_admin_proto_rawDesc = []byte{ @@ -2693,345 +3149,430 @@ var file_raystack_frontier_v1beta1_admin_proto_rawDesc = []byte{ 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x22, 0x02, 0x28, 0x00, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xde, 0x30, 0x0a, 0x0c, 0x41, 0x64, 0x6d, - 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xaf, 0x02, 0x0a, 0x0c, 0x4c, 0x69, - 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbd, 0x01, 0x92, 0x41, - 0x9d, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, - 0x6c, 0x6c, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x84, 0x01, 0x4c, 0x69, 0x73, 0x74, 0x73, - 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x66, - 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, - 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, - 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x2c, - 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x9c, 0x02, 0x0a, 0x0a, - 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf9, 0x02, 0x0a, 0x12, 0x57, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x12, + 0x1a, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, + 0x05, 0x72, 0x03, 0x88, 0x01, 0x01, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, + 0x11, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x54, 0x0a, 0x07, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x12, 0x31, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x1b, 0xfa, 0x42, 0x18, 0x72, 0x16, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, + 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0xd0, 0x01, 0x01, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x59, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x04, + 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, + 0x55, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x77, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x07, 0x77, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x22, 0x94, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x39, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x29, 0x92, 0x41, 0x1b, + 0x32, 0x19, 0x54, 0x68, 0x65, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x20, 0x69, 0x64, + 0x20, 0x74, 0x6f, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0xe0, 0x41, 0x02, 0xfa, 0x42, + 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x41, 0x0a, 0x04, 0x62, 0x6f, + 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb0, 0x01, 0x92, 0x41, 0x8f, 0x01, 0x0a, 0x05, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x1a, 0x75, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, - 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x66, 0x72, 0x6f, - 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, - 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, - 0x6d, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0xb3, 0x02, 0x0a, 0x14, 0x4c, - 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x36, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, - 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x72, 0x61, - 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, - 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa9, 0x01, 0x92, 0x41, 0x81, 0x01, 0x0a, 0x0c, 0x4f, 0x72, 0x67, - 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x20, - 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x1a, 0x59, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, - 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, - 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x75, 0x73, 0x65, - 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0xaa, 0x02, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x55, 0x0a, + 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x07, 0x77, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x22, 0x51, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x29, 0x92, 0x41, 0x1b, 0x32, 0x19, 0x54, + 0x68, 0x65, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x20, 0x69, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x2e, 0xe0, 0x41, 0x02, 0xfa, 0x42, 0x05, 0x72, 0x03, + 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x56, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x57, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3e, 0x0a, 0x08, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x65, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x08, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x32, + 0x83, 0x37, 0x0a, 0x0c, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0xaf, 0x02, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0xb8, 0x01, 0x92, 0x41, 0x95, 0x01, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x1a, 0x77, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x20, 0x66, 0x72, - 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, - 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, - 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0xb5, 0x01, - 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0xbd, 0x01, 0x92, 0x41, 0x9d, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, + 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, + 0x84, 0x01, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, + 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6b, + 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x75, 0x73, 0x65, + 0x72, 0x73, 0x12, 0x9c, 0x02, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, - 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x41, 0x92, 0x41, 0x1e, 0x0a, 0x08, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x72, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xc5, 0x02, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd0, 0x01, 0x92, 0x41, 0xac, - 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x4c, 0x69, 0x73, - 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, - 0x8b, 0x01, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, - 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, - 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, - 0x62, 0x79, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x2c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, - 0x6d, 0x69, 0x6e, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x98, 0x02, - 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x72, - 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, - 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb0, + 0x01, 0x92, 0x41, 0x8f, 0x01, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x0f, 0x4c, 0x69, + 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x1a, 0x75, 0x4c, + 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, + 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, + 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x73, 0x12, 0xb3, 0x02, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x36, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xac, 0x01, 0x92, 0x41, 0x8c, 0x01, - 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x70, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x6e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x20, 0x77, 0x69, 0x64, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, - 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, - 0x61, 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, - 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x16, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x0e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0xd5, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6a, 0x92, 0x41, 0x46, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, - 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x31, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x74, 0x69, 0x74, 0x6c, - 0x65, 0x2c, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x13, 0x2f, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, - 0x12, 0xdc, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, - 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x71, 0x92, 0x41, - 0x53, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x35, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x61, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x20, 0x77, 0x69, 0x64, 0x65, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, - 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x2a, 0x13, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, - 0xb1, 0x02, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, - 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb3, 0x01, - 0x92, 0x41, 0x90, 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x66, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, - 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, - 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0xbf, 0x02, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, + 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa9, 0x01, 0x92, 0x41, + 0x81, 0x01, 0x0a, 0x0c, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x59, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, + 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, + 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xaa, 0x02, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, - 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xc1, 0x01, 0x92, 0x41, 0x96, 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x1a, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x70, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x49, 0x44, 0x2e, 0x20, 0x49, 0x74, - 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, - 0x67, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, - 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x19, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc9, 0x01, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x92, 0x41, 0x28, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x12, 0xb0, 0x02, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb5, 0x01, 0x92, - 0x41, 0x95, 0x01, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, - 0x19, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x6c, 0x52, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6c, - 0x6c, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x20, 0x65, 0x2e, 0x67, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x74, 0x63, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, - 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x73, 0x12, 0xfb, 0x02, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfa, 0x01, 0x92, 0x41, 0xd7, 0x01, 0x0a, 0x0a, 0x50, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0xab, 0x01, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x6e, - 0x65, 0x77, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x73, 0x20, 0x2a, 0x2a, 0x6e, 0x61, 0x6d, 0x65, 0x2a, 0x2a, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, - 0x62, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6f, 0x6e, - 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, - 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x64, 0x61, 0x73, 0x68, - 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, - 0x65, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x73, 0x12, 0x83, 0x03, 0x0a, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x65, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb8, 0x01, 0x92, 0x41, 0x95, 0x01, + 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x20, + 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x1a, 0x77, 0x4c, 0x69, + 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, + 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x73, 0x12, 0xb5, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x43, 0x2e, 0x72, 0x61, + 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x92, 0x41, 0x1e, 0x0a, 0x08, + 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, + 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, + 0x69, 0x6e, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xc5, 0x02, 0x0a, + 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2f, + 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xd0, 0x01, 0x92, 0x41, 0xac, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x8b, 0x01, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, + 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, + 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x12, 0x98, 0x02, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xac, 0x01, 0x92, 0x41, 0x8c, 0x01, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x72, + 0x6f, 0x6c, 0x65, 0x1a, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x77, 0x69, 0x64, 0x65, 0x20, 0x72, 0x6f, 0x6c, + 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, + 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, + 0x0e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, + 0xd5, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2c, + 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, + 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6a, 0x92, 0x41, 0x46, + 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x72, + 0x6f, 0x6c, 0x65, 0x1a, 0x31, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x72, 0x6f, + 0x6c, 0x65, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x2c, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x04, 0x62, 0x6f, + 0x64, 0x79, 0x1a, 0x13, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, + 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xdc, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x71, 0x92, 0x41, 0x53, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, + 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x35, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x61, 0x20, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x77, 0x69, 0x64, 0x65, 0x20, 0x72, 0x6f, 0x6c, + 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, + 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x15, 0x2a, 0x13, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x6c, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xb1, 0x02, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x65, 0x64, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0xd5, 0x01, 0x92, 0x41, 0xb2, 0x01, 0x0a, 0x05, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x12, 0x05, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x1a, 0xa1, 0x01, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, - 0x74, 0x72, 0x75, 0x65, 0x20, 0x69, 0x66, 0x20, 0x61, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, - 0x70, 0x61, 0x6c, 0x20, 0x68, 0x61, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, - 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, - 0x72, 0x77, 0x69, 0x73, 0x65, 0x2e, 0x3c, 0x62, 0x72, 0x2f, 0x3e, 0x20, 0x4e, 0x6f, 0x74, 0x65, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x20, 0x63, - 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, - 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0xe0, 0x01, 0x0a, 0x0f, 0x41, 0x64, 0x64, - 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x12, 0x31, 0x2e, 0x72, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb3, 0x01, 0x92, 0x41, 0x90, 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, + 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x1a, 0x66, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, + 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, + 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, + 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xbf, 0x02, 0x0a, 0x10, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc1, 0x01, 0x92, 0x41, 0x96, 0x01, 0x0a, + 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, + 0x20, 0x61, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x79, + 0x20, 0x49, 0x44, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, + 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x20, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6c, 0x6c, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x20, 0x69, 0x6e, + 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x04, 0x62, 0x6f, 0x64, + 0x79, 0x1a, 0x19, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc9, 0x01, 0x0a, + 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x92, 0x41, 0x28, 0x0a, + 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xb0, 0x02, 0x0a, 0x0f, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x50, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x66, 0x92, 0x41, 0x3b, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x12, 0x11, 0x41, 0x64, 0x64, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x20, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x1c, 0x41, 0x64, 0x64, 0x73, 0x20, 0x61, 0x20, 0x75, 0x73, - 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0xf3, 0x01, 0x0a, 0x11, - 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, + 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xb5, 0x01, 0x92, 0x41, 0x95, 0x01, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x70, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x1a, 0x6c, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x64, 0x20, + 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69, + 0x6e, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x20, 0x65, 0x2e, 0x67, 0x20, + 0x75, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x6f, + 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x74, 0x63, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, + 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0xfb, 0x02, 0x0a, 0x11, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, - 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x73, 0x92, 0x41, - 0x4b, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x13, 0x4c, 0x69, 0x73, - 0x74, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, - 0x1a, 0x2a, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x72, - 0x73, 0x12, 0x81, 0x03, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, - 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x80, 0x02, 0x92, 0x41, 0xad, 0x01, 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x6f, 0x75, 0x74, 0x12, 0x22, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x20, - 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x7d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, - 0x74, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, - 0x75, 0x79, 0x20, 0x69, 0x74, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, - 0x72, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x61, - 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x20, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x62, 0x79, - 0x70, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x65, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49, 0x3a, 0x01, 0x2a, 0x22, - 0x44, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, - 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, - 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x7b, - 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x6f, 0x75, 0x74, 0x73, 0x12, 0xb1, 0x02, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, - 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x76, - 0x6f, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, - 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, - 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0xb6, 0x01, 0x92, 0x41, 0x8b, 0x01, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, - 0x12, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x69, - 0x63, 0x65, 0x73, 0x1a, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, + 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfa, 0x01, 0x92, + 0x41, 0xd7, 0x01, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, + 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0xab, 0x01, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x20, + 0x54, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x2a, 0x2a, 0x6e, 0x61, 0x6d, 0x65, 0x2a, + 0x2a, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, + 0x73, 0x2c, 0x20, 0x64, 0x61, 0x73, 0x68, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, + 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, + 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x83, 0x03, 0x0a, 0x20, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x42, + 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x43, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, + 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd5, 0x01, 0x92, 0x41, 0xb2, 0x01, 0x0a, 0x05, + 0x41, 0x75, 0x74, 0x68, 0x7a, 0x12, 0x05, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x1a, 0xa1, 0x01, 0x52, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x69, 0x66, 0x20, 0x61, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x20, 0x68, 0x61, 0x73, 0x20, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x61, 0x20, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x2e, 0x3c, 0x62, 0x72, + 0x2f, 0x3e, 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x63, 0x69, 0x70, 0x61, 0x6c, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x75, + 0x73, 0x65, 0x72, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, + 0xe0, 0x01, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, + 0x73, 0x65, 0x72, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x41, 0x64, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x66, 0x92, 0x41, 0x3b, 0x0a, + 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x11, 0x41, 0x64, 0x64, 0x20, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x1c, 0x41, 0x64, + 0x64, 0x73, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, + 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, + 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x75, 0x73, 0x65, + 0x72, 0x73, 0x12, 0xf3, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, + 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x73, 0x92, 0x41, 0x4b, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x12, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x2a, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, + 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x64, 0x64, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x81, 0x03, 0x0a, 0x11, 0x44, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x33, + 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x80, 0x02, 0x92, 0x41, 0xad, 0x01, + 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x22, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x20, 0x6f, + 0x72, 0x20, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x7d, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x75, 0x79, 0x20, 0x69, 0x74, 0x20, 0x6f, 0x6e, 0x65, + 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, + 0x20, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6c, + 0x61, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, + 0x2e, 0x20, 0x49, 0x74, 0x20, 0x62, 0x79, 0x70, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x62, 0x69, + 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x49, 0x3a, 0x01, 0x2a, 0x22, 0x44, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x69, + 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, + 0x64, 0x7d, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x73, 0x12, 0xb1, 0x02, 0x0a, + 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, + 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb6, 0x01, 0x92, 0x41, 0x8b, 0x01, 0x0a, 0x07, + 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x1a, 0x6d, 0x4c, 0x69, 0x73, 0x74, + 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, + 0x65, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, + 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, + 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, + 0x1f, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, + 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, + 0x12, 0xd6, 0x02, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x42, 0x69, 0x6c, 0x6c, + 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x38, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x42, + 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xc6, 0x01, 0x92, 0x41, 0x9b, 0x01, 0x0a, 0x07, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, + 0x12, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, + 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x1a, 0x75, 0x4c, 0x69, 0x73, + 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, + 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, @@ -3039,171 +3580,200 @@ var file_raystack_frontier_v1beta1_admin_proto_rawDesc = []byte{ 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, - 0x2f, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x12, 0xd6, 0x02, 0x0a, 0x16, 0x4c, 0x69, - 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x73, 0x12, 0x38, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, - 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, + 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0xe4, 0x02, 0x0a, 0x12, 0x52, 0x65, + 0x76, 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, + 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, + 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe0, 0x01, + 0x92, 0x41, 0x4c, 0x0a, 0x07, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x52, 0x65, + 0x76, 0x65, 0x72, 0x74, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x61, + 0x67, 0x65, 0x1a, 0x2b, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, + 0x6e, 0x67, 0x20, 0x75, 0x73, 0x61, 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x62, + 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x8a, 0x01, 0x3a, 0x01, 0x2a, 0x5a, 0x31, 0x3a, 0x01, 0x2a, 0x22, 0x2c, + 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x75, + 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x22, 0x52, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x62, 0x69, 0x6c, + 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x2f, 0x7b, + 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, + 0x12, 0xc9, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, + 0x6f, 0x6b, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, + 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x92, 0x41, 0x30, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x12, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x77, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x1a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x6e, 0x65, + 0x77, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, + 0x3a, 0x01, 0x2a, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, + 0x6d, 0x69, 0x6e, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0xca, 0x01, 0x0a, + 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x6c, 0x6c, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc6, 0x01, 0x92, 0x41, 0x9b, 0x01, - 0x0a, 0x07, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x20, - 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x73, 0x1a, 0x75, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, - 0x69, 0x6e, 0x20, 0x61, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, - 0x65, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, - 0x6e, 0x2f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x73, 0x12, 0xe4, 0x02, 0x0a, 0x12, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, - 0x6c, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x69, 0x6c, 0x6c, - 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x35, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x65, - 0x72, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe0, 0x01, 0x92, 0x41, 0x4c, 0x0a, 0x07, 0x42, 0x69, - 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, 0x62, 0x69, - 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x2b, 0x52, 0x65, 0x76, - 0x65, 0x72, 0x74, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x61, 0x67, - 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x8a, 0x01, 0x3a, - 0x01, 0x2a, 0x5a, 0x31, 0x3a, 0x01, 0x2a, 0x22, 0x2c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, - 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x72, - 0x65, 0x76, 0x65, 0x72, 0x74, 0x22, 0x52, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x62, 0x69, 0x6c, - 0x6c, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x2f, 0x7b, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0xf4, 0x0e, 0x92, 0x41, 0x84, 0x0e, - 0x12, 0xfe, 0x06, 0x0a, 0x1b, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x41, 0x64, - 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x50, 0x49, - 0x12, 0xcf, 0x05, 0x54, 0x68, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, - 0x41, 0x50, 0x49, 0x73, 0x20, 0x61, 0x64, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, - 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2c, - 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x20, - 0x61, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x61, - 0x70, 0x70, 0x72, 0x6f, 0x61, 0x63, 0x68, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x73, 0x69, - 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x69, - 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x69, 0x6e, - 0x67, 0x20, 0x52, 0x45, 0x53, 0x54, 0x66, 0x75, 0x6c, 0x20, 0x41, 0x50, 0x49, 0x73, 0x2e, 0x20, - 0x57, 0x69, 0x74, 0x68, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x2c, 0x20, 0x79, 0x6f, - 0x75, 0x20, 0x67, 0x61, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x20, 0x75, - 0x6e, 0x64, 0x65, 0x72, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x41, 0x50, 0x49, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x73, 0x2c, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2f, 0x72, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2c, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x6d, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x73, 0x20, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, - 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x73, 0x2e, 0x20, 0x42, 0x79, - 0x20, 0x6c, 0x65, 0x76, 0x65, 0x72, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, - 0x73, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x65, 0x61, 0x73, 0x69, 0x6c, 0x79, 0x20, 0x65, 0x78, 0x70, - 0x6c, 0x6f, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, - 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x73, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, - 0x20, 0x76, 0x61, 0x72, 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x6f, 0x6f, 0x6c, - 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x2e, - 0x20, 0x54, 0x68, 0x65, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x20, 0x73, 0x70, 0x65, - 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x20, 0x63, 0x6f, 0x64, - 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x41, 0x50, 0x49, 0x20, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x73, 0x65, 0x61, 0x6d, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x41, 0x50, 0x49, 0x20, 0x74, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x2c, 0x20, 0x6d, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x74, 0x20, 0x65, 0x61, 0x73, - 0x69, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x65, 0x76, 0x65, 0x72, 0x20, 0x74, 0x6f, - 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x65, 0x78, - 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x73, 0x2e, 0x22, 0x40, 0x0a, 0x13, 0x52, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x46, - 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x68, 0x74, 0x74, 0x70, 0x73, - 0x3a, 0x2f, 0x2f, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x6f, 0x72, 0x67, 0x2f, - 0x1a, 0x12, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x40, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x6f, 0x72, 0x67, 0x2a, 0x44, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x20, 0x32, - 0x2e, 0x30, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, - 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, - 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x30, 0x2e, 0x32, 0x2e, - 0x30, 0x1a, 0x0e, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x3a, 0x37, 0x34, 0x30, - 0x30, 0x2a, 0x01, 0x01, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x52, 0x3c, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, - 0x35, 0x0a, 0x1b, 0x4f, 0x4b, 0x20, 0x2d, 0x20, 0x41, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x66, 0x75, 0x6c, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x12, 0x16, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x56, 0x92, 0x41, 0x2c, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, + 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x1a, + 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x1a, 0x1c, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x77, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc7, 0x01, 0x0a, 0x0d, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x2f, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, + 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x53, + 0x92, 0x41, 0x2c, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x0e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x1a, 0x11, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x20, 0x61, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x2a, 0x1c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x12, 0xbf, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x92, 0x41, 0x2c, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x12, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x73, 0x1a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x77, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x77, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x42, 0xf4, 0x0e, 0x92, 0x41, 0x84, 0x0e, 0x12, 0xfe, 0x06, 0x0a, + 0x1b, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69, + 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x50, 0x49, 0x12, 0xcf, 0x05, 0x54, + 0x68, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x73, + 0x20, 0x61, 0x64, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4f, + 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x20, 0x61, 0x73, 0x20, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2c, 0x20, 0x77, 0x68, 0x69, + 0x63, 0x68, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, + 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x61, 0x70, 0x70, 0x72, 0x6f, + 0x61, 0x63, 0x68, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, + 0x67, 0x2c, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x2c, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x52, 0x45, + 0x53, 0x54, 0x66, 0x75, 0x6c, 0x20, 0x41, 0x50, 0x49, 0x73, 0x2e, 0x20, 0x57, 0x69, 0x74, 0x68, + 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x2c, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x67, 0x61, + 0x69, 0x6e, 0x20, 0x61, 0x20, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, + 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x41, 0x50, 0x49, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, + 0x65, 0x63, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x6d, 0x73, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x73, 0x2e, 0x20, 0x42, 0x79, 0x20, 0x6c, 0x65, 0x76, + 0x65, 0x72, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4f, 0x70, 0x65, 0x6e, + 0x41, 0x50, 0x49, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2c, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x73, 0x20, 0x63, 0x61, + 0x6e, 0x20, 0x65, 0x61, 0x73, 0x69, 0x6c, 0x79, 0x20, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, + 0x41, 0x50, 0x49, 0x73, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x76, 0x61, 0x72, + 0x69, 0x65, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, + 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x61, + 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x41, 0x50, 0x49, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x61, + 0x6d, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x41, 0x50, 0x49, 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x2c, 0x20, 0x6d, + 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x74, 0x20, 0x65, 0x61, 0x73, 0x69, 0x65, 0x72, 0x20, + 0x74, 0x68, 0x61, 0x6e, 0x20, 0x65, 0x76, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x65, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, + 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x2e, 0x22, 0x40, + 0x0a, 0x13, 0x52, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x72, + 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x1a, 0x12, 0x68, 0x65, + 0x6c, 0x6c, 0x6f, 0x40, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x6f, 0x72, 0x67, + 0x2a, 0x44, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x20, 0x32, 0x2e, 0x30, 0x12, 0x36, + 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, + 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x30, 0x2e, 0x32, 0x2e, 0x30, 0x1a, 0x0e, 0x31, + 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x3a, 0x37, 0x34, 0x30, 0x30, 0x2a, 0x01, 0x01, + 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, + 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, + 0x6a, 0x73, 0x6f, 0x6e, 0x52, 0x3c, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x35, 0x0a, 0x1b, 0x4f, + 0x4b, 0x20, 0x2d, 0x20, 0x41, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, + 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x69, 0x0a, 0x03, 0x34, 0x30, 0x30, 0x12, 0x62, 0x0a, 0x48, 0x42, 0x61, 0x64, + 0x20, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x6c, 0x66, 0x6f, + 0x72, 0x6d, 0x65, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x64, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x73, 0x2e, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x4a, 0x0a, + 0x03, 0x34, 0x30, 0x31, 0x12, 0x43, 0x0a, 0x29, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x20, 0x2d, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x64, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, + 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x61, 0x0a, 0x03, 0x34, 0x30, 0x33, + 0x12, 0x5a, 0x0a, 0x40, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x20, 0x2d, 0x20, + 0x55, 0x73, 0x65, 0x72, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, + 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x51, 0x0a, 0x03, + 0x34, 0x30, 0x34, 0x12, 0x4a, 0x0a, 0x30, 0x4e, 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, + 0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x75, 0x0a, 0x03, 0x35, 0x30, 0x30, 0x12, 0x6e, 0x0a, 0x54, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, + 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x73, 0x20, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, + 0x6e, 0x67, 0x20, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x46, 0x72, + 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x69, 0x0a, 0x03, 0x34, 0x30, 0x30, 0x12, 0x62, 0x0a, - 0x48, 0x42, 0x61, 0x64, 0x20, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x2d, 0x20, 0x54, - 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6d, - 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x65, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x4a, 0x0a, 0x03, 0x34, 0x30, 0x31, 0x12, 0x43, 0x0a, 0x29, 0x55, 0x6e, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x2d, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, - 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x61, 0x0a, - 0x03, 0x34, 0x30, 0x33, 0x12, 0x5a, 0x0a, 0x40, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, 0x64, 0x65, - 0x6e, 0x20, 0x2d, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, - 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x51, 0x0a, 0x03, 0x34, 0x30, 0x34, 0x12, 0x4a, 0x0a, 0x30, 0x4e, 0x6f, 0x74, 0x20, 0x46, - 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x65, 0x64, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x77, 0x61, - 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x14, 0x1a, - 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x75, 0x0a, 0x03, 0x35, 0x30, 0x30, 0x12, 0x6e, 0x0a, 0x54, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x2e, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x77, 0x68, - 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x73, 0x20, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x6d, - 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, - 0x68, 0x20, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x12, 0x16, 0x0a, 0x14, 0x1a, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5a, 0xa8, 0x01, 0x0a, 0x4e, 0x0a, - 0x05, 0x42, 0x61, 0x73, 0x69, 0x63, 0x12, 0x45, 0x08, 0x01, 0x12, 0x37, 0x75, 0x73, 0x65, 0x20, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x49, 0x44, 0x20, 0x61, 0x73, 0x20, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x20, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x20, 0x61, 0x73, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x1a, 0x06, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x20, 0x02, 0x0a, 0x56, 0x0a, - 0x06, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x12, 0x4c, 0x08, 0x03, 0x12, 0x3d, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x4a, 0x57, 0x54, - 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2c, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x64, - 0x20, 0x62, 0x79, 0x20, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x3a, 0x20, 0x42, 0x65, 0x61, 0x72, - 0x65, 0x72, 0x20, 0x3c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3e, 0x1a, 0x07, 0x42, 0x65, 0x61, 0x72, - 0x65, 0x72, 0x20, 0x20, 0x02, 0x62, 0x0b, 0x0a, 0x09, 0x0a, 0x05, 0x42, 0x61, 0x73, 0x69, 0x63, - 0x12, 0x00, 0x62, 0x0c, 0x0a, 0x0a, 0x0a, 0x06, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x12, 0x00, - 0x6a, 0x06, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x6a, 0x07, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x6a, 0x0e, 0x0a, 0x0c, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x6a, 0x09, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x6a, 0x0a, 0x0a, 0x08, - 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6a, 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x6a, 0x08, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x6a, 0x06, - 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x6a, 0x0c, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x23, 0x69, 0x6f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, - 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x3b, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5a, 0xa8, 0x01, 0x0a, 0x4e, 0x0a, 0x05, 0x42, 0x61, 0x73, + 0x69, 0x63, 0x12, 0x45, 0x08, 0x01, 0x12, 0x37, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x20, 0x49, 0x44, 0x20, 0x61, 0x73, 0x20, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x20, 0x61, 0x73, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x1a, + 0x06, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x20, 0x02, 0x0a, 0x56, 0x0a, 0x06, 0x42, 0x65, 0x61, + 0x72, 0x65, 0x72, 0x12, 0x4c, 0x08, 0x03, 0x12, 0x3d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x4a, 0x57, 0x54, 0x20, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x2c, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, + 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x3a, 0x20, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x20, 0x3c, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3e, 0x1a, 0x07, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x20, 0x20, + 0x02, 0x62, 0x0b, 0x0a, 0x09, 0x0a, 0x05, 0x42, 0x61, 0x73, 0x69, 0x63, 0x12, 0x00, 0x62, 0x0c, + 0x0a, 0x0a, 0x0a, 0x06, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x12, 0x00, 0x6a, 0x06, 0x0a, 0x04, + 0x55, 0x73, 0x65, 0x72, 0x6a, 0x07, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x6a, 0x0e, 0x0a, + 0x0c, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6a, 0x09, 0x0a, + 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x6a, 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x6a, 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x6a, 0x08, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x6a, 0x06, 0x0a, 0x04, 0x52, 0x6f, + 0x6c, 0x65, 0x6a, 0x0c, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x0a, 0x23, 0x69, 0x6f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x6e, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x5a, + 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x61, 0x79, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3218,7 +3788,7 @@ func file_raystack_frontier_v1beta1_admin_proto_rawDescGZIP() []byte { return file_raystack_frontier_v1beta1_admin_proto_rawDescData } -var file_raystack_frontier_v1beta1_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 43) +var file_raystack_frontier_v1beta1_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 53) var file_raystack_frontier_v1beta1_admin_proto_goTypes = []interface{}{ (*ListAllUsersRequest)(nil), // 0: raystack.frontier.v1beta1.ListAllUsersRequest (*ListAllUsersResponse)(nil), // 1: raystack.frontier.v1beta1.ListAllUsersResponse @@ -3263,100 +3833,126 @@ var file_raystack_frontier_v1beta1_admin_proto_goTypes = []interface{}{ (*ListAllBillingAccountsResponse)(nil), // 40: raystack.frontier.v1beta1.ListAllBillingAccountsResponse (*RevertBillingUsageRequest)(nil), // 41: raystack.frontier.v1beta1.RevertBillingUsageRequest (*RevertBillingUsageResponse)(nil), // 42: raystack.frontier.v1beta1.RevertBillingUsageResponse - (*User)(nil), // 43: raystack.frontier.v1beta1.User - (*Group)(nil), // 44: raystack.frontier.v1beta1.Group - (*Organization)(nil), // 45: raystack.frontier.v1beta1.Organization - (*Project)(nil), // 46: raystack.frontier.v1beta1.Project - (*Relation)(nil), // 47: raystack.frontier.v1beta1.Relation - (*Resource)(nil), // 48: raystack.frontier.v1beta1.Resource - (*RoleRequestBody)(nil), // 49: raystack.frontier.v1beta1.RoleRequestBody - (*Role)(nil), // 50: raystack.frontier.v1beta1.Role - (*structpb.Struct)(nil), // 51: google.protobuf.Struct - (*Permission)(nil), // 52: raystack.frontier.v1beta1.Permission - (*Preference)(nil), // 53: raystack.frontier.v1beta1.Preference - (*PreferenceRequestBody)(nil), // 54: raystack.frontier.v1beta1.PreferenceRequestBody - (*ServiceUser)(nil), // 55: raystack.frontier.v1beta1.ServiceUser - (*CheckoutSubscriptionBody)(nil), // 56: raystack.frontier.v1beta1.CheckoutSubscriptionBody - (*CheckoutProductBody)(nil), // 57: raystack.frontier.v1beta1.CheckoutProductBody - (*Subscription)(nil), // 58: raystack.frontier.v1beta1.Subscription - (*Product)(nil), // 59: raystack.frontier.v1beta1.Product - (*Invoice)(nil), // 60: raystack.frontier.v1beta1.Invoice - (*BillingAccount)(nil), // 61: raystack.frontier.v1beta1.BillingAccount + (*WebhookRequestBody)(nil), // 43: raystack.frontier.v1beta1.WebhookRequestBody + (*CreateWebhookRequest)(nil), // 44: raystack.frontier.v1beta1.CreateWebhookRequest + (*CreateWebhookResponse)(nil), // 45: raystack.frontier.v1beta1.CreateWebhookResponse + (*UpdateWebhookRequest)(nil), // 46: raystack.frontier.v1beta1.UpdateWebhookRequest + (*UpdateWebhookResponse)(nil), // 47: raystack.frontier.v1beta1.UpdateWebhookResponse + (*DeleteWebhookRequest)(nil), // 48: raystack.frontier.v1beta1.DeleteWebhookRequest + (*DeleteWebhookResponse)(nil), // 49: raystack.frontier.v1beta1.DeleteWebhookResponse + (*ListWebhooksRequest)(nil), // 50: raystack.frontier.v1beta1.ListWebhooksRequest + (*ListWebhooksResponse)(nil), // 51: raystack.frontier.v1beta1.ListWebhooksResponse + nil, // 52: raystack.frontier.v1beta1.WebhookRequestBody.HeadersEntry + (*User)(nil), // 53: raystack.frontier.v1beta1.User + (*Group)(nil), // 54: raystack.frontier.v1beta1.Group + (*Organization)(nil), // 55: raystack.frontier.v1beta1.Organization + (*Project)(nil), // 56: raystack.frontier.v1beta1.Project + (*Relation)(nil), // 57: raystack.frontier.v1beta1.Relation + (*Resource)(nil), // 58: raystack.frontier.v1beta1.Resource + (*RoleRequestBody)(nil), // 59: raystack.frontier.v1beta1.RoleRequestBody + (*Role)(nil), // 60: raystack.frontier.v1beta1.Role + (*structpb.Struct)(nil), // 61: google.protobuf.Struct + (*Permission)(nil), // 62: raystack.frontier.v1beta1.Permission + (*Preference)(nil), // 63: raystack.frontier.v1beta1.Preference + (*PreferenceRequestBody)(nil), // 64: raystack.frontier.v1beta1.PreferenceRequestBody + (*ServiceUser)(nil), // 65: raystack.frontier.v1beta1.ServiceUser + (*CheckoutSubscriptionBody)(nil), // 66: raystack.frontier.v1beta1.CheckoutSubscriptionBody + (*CheckoutProductBody)(nil), // 67: raystack.frontier.v1beta1.CheckoutProductBody + (*Subscription)(nil), // 68: raystack.frontier.v1beta1.Subscription + (*Product)(nil), // 69: raystack.frontier.v1beta1.Product + (*Invoice)(nil), // 70: raystack.frontier.v1beta1.Invoice + (*BillingAccount)(nil), // 71: raystack.frontier.v1beta1.BillingAccount + (*Webhook)(nil), // 72: raystack.frontier.v1beta1.Webhook } var file_raystack_frontier_v1beta1_admin_proto_depIdxs = []int32{ - 43, // 0: raystack.frontier.v1beta1.ListAllUsersResponse.users:type_name -> raystack.frontier.v1beta1.User - 44, // 1: raystack.frontier.v1beta1.ListGroupsResponse.groups:type_name -> raystack.frontier.v1beta1.Group - 45, // 2: raystack.frontier.v1beta1.ListAllOrganizationsResponse.organizations:type_name -> raystack.frontier.v1beta1.Organization - 46, // 3: raystack.frontier.v1beta1.ListProjectsResponse.projects:type_name -> raystack.frontier.v1beta1.Project - 47, // 4: raystack.frontier.v1beta1.ListRelationsResponse.relations:type_name -> raystack.frontier.v1beta1.Relation - 48, // 5: raystack.frontier.v1beta1.ListResourcesResponse.resources:type_name -> raystack.frontier.v1beta1.Resource - 49, // 6: raystack.frontier.v1beta1.CreateRoleRequest.body:type_name -> raystack.frontier.v1beta1.RoleRequestBody - 50, // 7: raystack.frontier.v1beta1.CreateRoleResponse.role:type_name -> raystack.frontier.v1beta1.Role - 49, // 8: raystack.frontier.v1beta1.UpdateRoleRequest.body:type_name -> raystack.frontier.v1beta1.RoleRequestBody - 50, // 9: raystack.frontier.v1beta1.UpdateRoleResponse.role:type_name -> raystack.frontier.v1beta1.Role - 51, // 10: raystack.frontier.v1beta1.PermissionRequestBody.metadata:type_name -> google.protobuf.Struct + 53, // 0: raystack.frontier.v1beta1.ListAllUsersResponse.users:type_name -> raystack.frontier.v1beta1.User + 54, // 1: raystack.frontier.v1beta1.ListGroupsResponse.groups:type_name -> raystack.frontier.v1beta1.Group + 55, // 2: raystack.frontier.v1beta1.ListAllOrganizationsResponse.organizations:type_name -> raystack.frontier.v1beta1.Organization + 56, // 3: raystack.frontier.v1beta1.ListProjectsResponse.projects:type_name -> raystack.frontier.v1beta1.Project + 57, // 4: raystack.frontier.v1beta1.ListRelationsResponse.relations:type_name -> raystack.frontier.v1beta1.Relation + 58, // 5: raystack.frontier.v1beta1.ListResourcesResponse.resources:type_name -> raystack.frontier.v1beta1.Resource + 59, // 6: raystack.frontier.v1beta1.CreateRoleRequest.body:type_name -> raystack.frontier.v1beta1.RoleRequestBody + 60, // 7: raystack.frontier.v1beta1.CreateRoleResponse.role:type_name -> raystack.frontier.v1beta1.Role + 59, // 8: raystack.frontier.v1beta1.UpdateRoleRequest.body:type_name -> raystack.frontier.v1beta1.RoleRequestBody + 60, // 9: raystack.frontier.v1beta1.UpdateRoleResponse.role:type_name -> raystack.frontier.v1beta1.Role + 61, // 10: raystack.frontier.v1beta1.PermissionRequestBody.metadata:type_name -> google.protobuf.Struct 18, // 11: raystack.frontier.v1beta1.CreatePermissionRequest.bodies:type_name -> raystack.frontier.v1beta1.PermissionRequestBody - 52, // 12: raystack.frontier.v1beta1.CreatePermissionResponse.permissions:type_name -> raystack.frontier.v1beta1.Permission + 62, // 12: raystack.frontier.v1beta1.CreatePermissionResponse.permissions:type_name -> raystack.frontier.v1beta1.Permission 18, // 13: raystack.frontier.v1beta1.UpdatePermissionRequest.body:type_name -> raystack.frontier.v1beta1.PermissionRequestBody - 52, // 14: raystack.frontier.v1beta1.UpdatePermissionResponse.permission:type_name -> raystack.frontier.v1beta1.Permission - 53, // 15: raystack.frontier.v1beta1.ListPreferencesResponse.preferences:type_name -> raystack.frontier.v1beta1.Preference - 54, // 16: raystack.frontier.v1beta1.CreatePreferencesRequest.preferences:type_name -> raystack.frontier.v1beta1.PreferenceRequestBody - 53, // 17: raystack.frontier.v1beta1.CreatePreferencesResponse.preference:type_name -> raystack.frontier.v1beta1.Preference - 43, // 18: raystack.frontier.v1beta1.ListPlatformUsersResponse.users:type_name -> raystack.frontier.v1beta1.User - 55, // 19: raystack.frontier.v1beta1.ListPlatformUsersResponse.serviceusers:type_name -> raystack.frontier.v1beta1.ServiceUser - 56, // 20: raystack.frontier.v1beta1.DelegatedCheckoutRequest.subscription_body:type_name -> raystack.frontier.v1beta1.CheckoutSubscriptionBody - 57, // 21: raystack.frontier.v1beta1.DelegatedCheckoutRequest.product_body:type_name -> raystack.frontier.v1beta1.CheckoutProductBody - 58, // 22: raystack.frontier.v1beta1.DelegatedCheckoutResponse.subscription:type_name -> raystack.frontier.v1beta1.Subscription - 59, // 23: raystack.frontier.v1beta1.DelegatedCheckoutResponse.product:type_name -> raystack.frontier.v1beta1.Product - 60, // 24: raystack.frontier.v1beta1.ListAllInvoicesResponse.invoices:type_name -> raystack.frontier.v1beta1.Invoice - 61, // 25: raystack.frontier.v1beta1.ListAllBillingAccountsResponse.billing_accounts:type_name -> raystack.frontier.v1beta1.BillingAccount - 0, // 26: raystack.frontier.v1beta1.AdminService.ListAllUsers:input_type -> raystack.frontier.v1beta1.ListAllUsersRequest - 2, // 27: raystack.frontier.v1beta1.AdminService.ListGroups:input_type -> raystack.frontier.v1beta1.ListGroupsRequest - 4, // 28: raystack.frontier.v1beta1.AdminService.ListAllOrganizations:input_type -> raystack.frontier.v1beta1.ListAllOrganizationsRequest - 6, // 29: raystack.frontier.v1beta1.AdminService.ListProjects:input_type -> raystack.frontier.v1beta1.ListProjectsRequest - 8, // 30: raystack.frontier.v1beta1.AdminService.ListRelations:input_type -> raystack.frontier.v1beta1.ListRelationsRequest - 10, // 31: raystack.frontier.v1beta1.AdminService.ListResources:input_type -> raystack.frontier.v1beta1.ListResourcesRequest - 12, // 32: raystack.frontier.v1beta1.AdminService.CreateRole:input_type -> raystack.frontier.v1beta1.CreateRoleRequest - 14, // 33: raystack.frontier.v1beta1.AdminService.UpdateRole:input_type -> raystack.frontier.v1beta1.UpdateRoleRequest - 16, // 34: raystack.frontier.v1beta1.AdminService.DeleteRole:input_type -> raystack.frontier.v1beta1.DeleteRoleRequest - 19, // 35: raystack.frontier.v1beta1.AdminService.CreatePermission:input_type -> raystack.frontier.v1beta1.CreatePermissionRequest - 21, // 36: raystack.frontier.v1beta1.AdminService.UpdatePermission:input_type -> raystack.frontier.v1beta1.UpdatePermissionRequest - 23, // 37: raystack.frontier.v1beta1.AdminService.DeletePermission:input_type -> raystack.frontier.v1beta1.DeletePermissionRequest - 25, // 38: raystack.frontier.v1beta1.AdminService.ListPreferences:input_type -> raystack.frontier.v1beta1.ListPreferencesRequest - 27, // 39: raystack.frontier.v1beta1.AdminService.CreatePreferences:input_type -> raystack.frontier.v1beta1.CreatePreferencesRequest - 29, // 40: raystack.frontier.v1beta1.AdminService.CheckFederatedResourcePermission:input_type -> raystack.frontier.v1beta1.CheckFederatedResourcePermissionRequest - 31, // 41: raystack.frontier.v1beta1.AdminService.AddPlatformUser:input_type -> raystack.frontier.v1beta1.AddPlatformUserRequest - 33, // 42: raystack.frontier.v1beta1.AdminService.ListPlatformUsers:input_type -> raystack.frontier.v1beta1.ListPlatformUsersRequest - 35, // 43: raystack.frontier.v1beta1.AdminService.DelegatedCheckout:input_type -> raystack.frontier.v1beta1.DelegatedCheckoutRequest - 37, // 44: raystack.frontier.v1beta1.AdminService.ListAllInvoices:input_type -> raystack.frontier.v1beta1.ListAllInvoicesRequest - 39, // 45: raystack.frontier.v1beta1.AdminService.ListAllBillingAccounts:input_type -> raystack.frontier.v1beta1.ListAllBillingAccountsRequest - 41, // 46: raystack.frontier.v1beta1.AdminService.RevertBillingUsage:input_type -> raystack.frontier.v1beta1.RevertBillingUsageRequest - 1, // 47: raystack.frontier.v1beta1.AdminService.ListAllUsers:output_type -> raystack.frontier.v1beta1.ListAllUsersResponse - 3, // 48: raystack.frontier.v1beta1.AdminService.ListGroups:output_type -> raystack.frontier.v1beta1.ListGroupsResponse - 5, // 49: raystack.frontier.v1beta1.AdminService.ListAllOrganizations:output_type -> raystack.frontier.v1beta1.ListAllOrganizationsResponse - 7, // 50: raystack.frontier.v1beta1.AdminService.ListProjects:output_type -> raystack.frontier.v1beta1.ListProjectsResponse - 9, // 51: raystack.frontier.v1beta1.AdminService.ListRelations:output_type -> raystack.frontier.v1beta1.ListRelationsResponse - 11, // 52: raystack.frontier.v1beta1.AdminService.ListResources:output_type -> raystack.frontier.v1beta1.ListResourcesResponse - 13, // 53: raystack.frontier.v1beta1.AdminService.CreateRole:output_type -> raystack.frontier.v1beta1.CreateRoleResponse - 15, // 54: raystack.frontier.v1beta1.AdminService.UpdateRole:output_type -> raystack.frontier.v1beta1.UpdateRoleResponse - 17, // 55: raystack.frontier.v1beta1.AdminService.DeleteRole:output_type -> raystack.frontier.v1beta1.DeleteRoleResponse - 20, // 56: raystack.frontier.v1beta1.AdminService.CreatePermission:output_type -> raystack.frontier.v1beta1.CreatePermissionResponse - 22, // 57: raystack.frontier.v1beta1.AdminService.UpdatePermission:output_type -> raystack.frontier.v1beta1.UpdatePermissionResponse - 24, // 58: raystack.frontier.v1beta1.AdminService.DeletePermission:output_type -> raystack.frontier.v1beta1.DeletePermissionResponse - 26, // 59: raystack.frontier.v1beta1.AdminService.ListPreferences:output_type -> raystack.frontier.v1beta1.ListPreferencesResponse - 28, // 60: raystack.frontier.v1beta1.AdminService.CreatePreferences:output_type -> raystack.frontier.v1beta1.CreatePreferencesResponse - 30, // 61: raystack.frontier.v1beta1.AdminService.CheckFederatedResourcePermission:output_type -> raystack.frontier.v1beta1.CheckFederatedResourcePermissionResponse - 32, // 62: raystack.frontier.v1beta1.AdminService.AddPlatformUser:output_type -> raystack.frontier.v1beta1.AddPlatformUserResponse - 34, // 63: raystack.frontier.v1beta1.AdminService.ListPlatformUsers:output_type -> raystack.frontier.v1beta1.ListPlatformUsersResponse - 36, // 64: raystack.frontier.v1beta1.AdminService.DelegatedCheckout:output_type -> raystack.frontier.v1beta1.DelegatedCheckoutResponse - 38, // 65: raystack.frontier.v1beta1.AdminService.ListAllInvoices:output_type -> raystack.frontier.v1beta1.ListAllInvoicesResponse - 40, // 66: raystack.frontier.v1beta1.AdminService.ListAllBillingAccounts:output_type -> raystack.frontier.v1beta1.ListAllBillingAccountsResponse - 42, // 67: raystack.frontier.v1beta1.AdminService.RevertBillingUsage:output_type -> raystack.frontier.v1beta1.RevertBillingUsageResponse - 47, // [47:68] is the sub-list for method output_type - 26, // [26:47] is the sub-list for method input_type - 26, // [26:26] is the sub-list for extension type_name - 26, // [26:26] is the sub-list for extension extendee - 0, // [0:26] is the sub-list for field type_name + 62, // 14: raystack.frontier.v1beta1.UpdatePermissionResponse.permission:type_name -> raystack.frontier.v1beta1.Permission + 63, // 15: raystack.frontier.v1beta1.ListPreferencesResponse.preferences:type_name -> raystack.frontier.v1beta1.Preference + 64, // 16: raystack.frontier.v1beta1.CreatePreferencesRequest.preferences:type_name -> raystack.frontier.v1beta1.PreferenceRequestBody + 63, // 17: raystack.frontier.v1beta1.CreatePreferencesResponse.preference:type_name -> raystack.frontier.v1beta1.Preference + 53, // 18: raystack.frontier.v1beta1.ListPlatformUsersResponse.users:type_name -> raystack.frontier.v1beta1.User + 65, // 19: raystack.frontier.v1beta1.ListPlatformUsersResponse.serviceusers:type_name -> raystack.frontier.v1beta1.ServiceUser + 66, // 20: raystack.frontier.v1beta1.DelegatedCheckoutRequest.subscription_body:type_name -> raystack.frontier.v1beta1.CheckoutSubscriptionBody + 67, // 21: raystack.frontier.v1beta1.DelegatedCheckoutRequest.product_body:type_name -> raystack.frontier.v1beta1.CheckoutProductBody + 68, // 22: raystack.frontier.v1beta1.DelegatedCheckoutResponse.subscription:type_name -> raystack.frontier.v1beta1.Subscription + 69, // 23: raystack.frontier.v1beta1.DelegatedCheckoutResponse.product:type_name -> raystack.frontier.v1beta1.Product + 70, // 24: raystack.frontier.v1beta1.ListAllInvoicesResponse.invoices:type_name -> raystack.frontier.v1beta1.Invoice + 71, // 25: raystack.frontier.v1beta1.ListAllBillingAccountsResponse.billing_accounts:type_name -> raystack.frontier.v1beta1.BillingAccount + 52, // 26: raystack.frontier.v1beta1.WebhookRequestBody.headers:type_name -> raystack.frontier.v1beta1.WebhookRequestBody.HeadersEntry + 61, // 27: raystack.frontier.v1beta1.WebhookRequestBody.metadata:type_name -> google.protobuf.Struct + 43, // 28: raystack.frontier.v1beta1.CreateWebhookRequest.body:type_name -> raystack.frontier.v1beta1.WebhookRequestBody + 72, // 29: raystack.frontier.v1beta1.CreateWebhookResponse.webhook:type_name -> raystack.frontier.v1beta1.Webhook + 43, // 30: raystack.frontier.v1beta1.UpdateWebhookRequest.body:type_name -> raystack.frontier.v1beta1.WebhookRequestBody + 72, // 31: raystack.frontier.v1beta1.UpdateWebhookResponse.webhook:type_name -> raystack.frontier.v1beta1.Webhook + 72, // 32: raystack.frontier.v1beta1.ListWebhooksResponse.webhooks:type_name -> raystack.frontier.v1beta1.Webhook + 0, // 33: raystack.frontier.v1beta1.AdminService.ListAllUsers:input_type -> raystack.frontier.v1beta1.ListAllUsersRequest + 2, // 34: raystack.frontier.v1beta1.AdminService.ListGroups:input_type -> raystack.frontier.v1beta1.ListGroupsRequest + 4, // 35: raystack.frontier.v1beta1.AdminService.ListAllOrganizations:input_type -> raystack.frontier.v1beta1.ListAllOrganizationsRequest + 6, // 36: raystack.frontier.v1beta1.AdminService.ListProjects:input_type -> raystack.frontier.v1beta1.ListProjectsRequest + 8, // 37: raystack.frontier.v1beta1.AdminService.ListRelations:input_type -> raystack.frontier.v1beta1.ListRelationsRequest + 10, // 38: raystack.frontier.v1beta1.AdminService.ListResources:input_type -> raystack.frontier.v1beta1.ListResourcesRequest + 12, // 39: raystack.frontier.v1beta1.AdminService.CreateRole:input_type -> raystack.frontier.v1beta1.CreateRoleRequest + 14, // 40: raystack.frontier.v1beta1.AdminService.UpdateRole:input_type -> raystack.frontier.v1beta1.UpdateRoleRequest + 16, // 41: raystack.frontier.v1beta1.AdminService.DeleteRole:input_type -> raystack.frontier.v1beta1.DeleteRoleRequest + 19, // 42: raystack.frontier.v1beta1.AdminService.CreatePermission:input_type -> raystack.frontier.v1beta1.CreatePermissionRequest + 21, // 43: raystack.frontier.v1beta1.AdminService.UpdatePermission:input_type -> raystack.frontier.v1beta1.UpdatePermissionRequest + 23, // 44: raystack.frontier.v1beta1.AdminService.DeletePermission:input_type -> raystack.frontier.v1beta1.DeletePermissionRequest + 25, // 45: raystack.frontier.v1beta1.AdminService.ListPreferences:input_type -> raystack.frontier.v1beta1.ListPreferencesRequest + 27, // 46: raystack.frontier.v1beta1.AdminService.CreatePreferences:input_type -> raystack.frontier.v1beta1.CreatePreferencesRequest + 29, // 47: raystack.frontier.v1beta1.AdminService.CheckFederatedResourcePermission:input_type -> raystack.frontier.v1beta1.CheckFederatedResourcePermissionRequest + 31, // 48: raystack.frontier.v1beta1.AdminService.AddPlatformUser:input_type -> raystack.frontier.v1beta1.AddPlatformUserRequest + 33, // 49: raystack.frontier.v1beta1.AdminService.ListPlatformUsers:input_type -> raystack.frontier.v1beta1.ListPlatformUsersRequest + 35, // 50: raystack.frontier.v1beta1.AdminService.DelegatedCheckout:input_type -> raystack.frontier.v1beta1.DelegatedCheckoutRequest + 37, // 51: raystack.frontier.v1beta1.AdminService.ListAllInvoices:input_type -> raystack.frontier.v1beta1.ListAllInvoicesRequest + 39, // 52: raystack.frontier.v1beta1.AdminService.ListAllBillingAccounts:input_type -> raystack.frontier.v1beta1.ListAllBillingAccountsRequest + 41, // 53: raystack.frontier.v1beta1.AdminService.RevertBillingUsage:input_type -> raystack.frontier.v1beta1.RevertBillingUsageRequest + 44, // 54: raystack.frontier.v1beta1.AdminService.CreateWebhook:input_type -> raystack.frontier.v1beta1.CreateWebhookRequest + 46, // 55: raystack.frontier.v1beta1.AdminService.UpdateWebhook:input_type -> raystack.frontier.v1beta1.UpdateWebhookRequest + 48, // 56: raystack.frontier.v1beta1.AdminService.DeleteWebhook:input_type -> raystack.frontier.v1beta1.DeleteWebhookRequest + 50, // 57: raystack.frontier.v1beta1.AdminService.ListWebhooks:input_type -> raystack.frontier.v1beta1.ListWebhooksRequest + 1, // 58: raystack.frontier.v1beta1.AdminService.ListAllUsers:output_type -> raystack.frontier.v1beta1.ListAllUsersResponse + 3, // 59: raystack.frontier.v1beta1.AdminService.ListGroups:output_type -> raystack.frontier.v1beta1.ListGroupsResponse + 5, // 60: raystack.frontier.v1beta1.AdminService.ListAllOrganizations:output_type -> raystack.frontier.v1beta1.ListAllOrganizationsResponse + 7, // 61: raystack.frontier.v1beta1.AdminService.ListProjects:output_type -> raystack.frontier.v1beta1.ListProjectsResponse + 9, // 62: raystack.frontier.v1beta1.AdminService.ListRelations:output_type -> raystack.frontier.v1beta1.ListRelationsResponse + 11, // 63: raystack.frontier.v1beta1.AdminService.ListResources:output_type -> raystack.frontier.v1beta1.ListResourcesResponse + 13, // 64: raystack.frontier.v1beta1.AdminService.CreateRole:output_type -> raystack.frontier.v1beta1.CreateRoleResponse + 15, // 65: raystack.frontier.v1beta1.AdminService.UpdateRole:output_type -> raystack.frontier.v1beta1.UpdateRoleResponse + 17, // 66: raystack.frontier.v1beta1.AdminService.DeleteRole:output_type -> raystack.frontier.v1beta1.DeleteRoleResponse + 20, // 67: raystack.frontier.v1beta1.AdminService.CreatePermission:output_type -> raystack.frontier.v1beta1.CreatePermissionResponse + 22, // 68: raystack.frontier.v1beta1.AdminService.UpdatePermission:output_type -> raystack.frontier.v1beta1.UpdatePermissionResponse + 24, // 69: raystack.frontier.v1beta1.AdminService.DeletePermission:output_type -> raystack.frontier.v1beta1.DeletePermissionResponse + 26, // 70: raystack.frontier.v1beta1.AdminService.ListPreferences:output_type -> raystack.frontier.v1beta1.ListPreferencesResponse + 28, // 71: raystack.frontier.v1beta1.AdminService.CreatePreferences:output_type -> raystack.frontier.v1beta1.CreatePreferencesResponse + 30, // 72: raystack.frontier.v1beta1.AdminService.CheckFederatedResourcePermission:output_type -> raystack.frontier.v1beta1.CheckFederatedResourcePermissionResponse + 32, // 73: raystack.frontier.v1beta1.AdminService.AddPlatformUser:output_type -> raystack.frontier.v1beta1.AddPlatformUserResponse + 34, // 74: raystack.frontier.v1beta1.AdminService.ListPlatformUsers:output_type -> raystack.frontier.v1beta1.ListPlatformUsersResponse + 36, // 75: raystack.frontier.v1beta1.AdminService.DelegatedCheckout:output_type -> raystack.frontier.v1beta1.DelegatedCheckoutResponse + 38, // 76: raystack.frontier.v1beta1.AdminService.ListAllInvoices:output_type -> raystack.frontier.v1beta1.ListAllInvoicesResponse + 40, // 77: raystack.frontier.v1beta1.AdminService.ListAllBillingAccounts:output_type -> raystack.frontier.v1beta1.ListAllBillingAccountsResponse + 42, // 78: raystack.frontier.v1beta1.AdminService.RevertBillingUsage:output_type -> raystack.frontier.v1beta1.RevertBillingUsageResponse + 45, // 79: raystack.frontier.v1beta1.AdminService.CreateWebhook:output_type -> raystack.frontier.v1beta1.CreateWebhookResponse + 47, // 80: raystack.frontier.v1beta1.AdminService.UpdateWebhook:output_type -> raystack.frontier.v1beta1.UpdateWebhookResponse + 49, // 81: raystack.frontier.v1beta1.AdminService.DeleteWebhook:output_type -> raystack.frontier.v1beta1.DeleteWebhookResponse + 51, // 82: raystack.frontier.v1beta1.AdminService.ListWebhooks:output_type -> raystack.frontier.v1beta1.ListWebhooksResponse + 58, // [58:83] is the sub-list for method output_type + 33, // [33:58] is the sub-list for method input_type + 33, // [33:33] is the sub-list for extension type_name + 33, // [33:33] is the sub-list for extension extendee + 0, // [0:33] is the sub-list for field type_name } func init() { file_raystack_frontier_v1beta1_admin_proto_init() } @@ -3882,6 +4478,114 @@ func file_raystack_frontier_v1beta1_admin_proto_init() { return nil } } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WebhookRequestBody); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateWebhookRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateWebhookResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateWebhookRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateWebhookResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteWebhookRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteWebhookResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListWebhooksRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_admin_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListWebhooksResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -3889,7 +4593,7 @@ func file_raystack_frontier_v1beta1_admin_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_raystack_frontier_v1beta1_admin_proto_rawDesc, NumEnums: 0, - NumMessages: 43, + NumMessages: 53, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/v1beta1/admin.pb.gw.go b/proto/v1beta1/admin.pb.gw.go index ba0d3de9e..79223249e 100644 --- a/proto/v1beta1/admin.pb.gw.go +++ b/proto/v1beta1/admin.pb.gw.go @@ -995,6 +995,178 @@ func local_request_AdminService_RevertBillingUsage_1(ctx context.Context, marsha } +func request_AdminService_CreateWebhook_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateWebhookRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateWebhook(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AdminService_CreateWebhook_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateWebhookRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateWebhook(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AdminService_UpdateWebhook_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateWebhookRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.UpdateWebhook(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AdminService_UpdateWebhook_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateWebhookRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.UpdateWebhook(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AdminService_DeleteWebhook_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteWebhookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.DeleteWebhook(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AdminService_DeleteWebhook_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteWebhookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.DeleteWebhook(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AdminService_ListWebhooks_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListWebhooksRequest + var metadata runtime.ServerMetadata + + msg, err := client.ListWebhooks(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AdminService_ListWebhooks_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListWebhooksRequest + var metadata runtime.ServerMetadata + + msg, err := server.ListWebhooks(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterAdminServiceHandlerServer registers the http handlers for service AdminService to "mux". // UnaryRPC :call AdminServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -1551,6 +1723,106 @@ func RegisterAdminServiceHandlerServer(ctx context.Context, mux *runtime.ServeMu }) + mux.Handle("POST", pattern_AdminService_CreateWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.frontier.v1beta1.AdminService/CreateWebhook", runtime.WithHTTPPathPattern("/v1beta1/admin/webhooks")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AdminService_CreateWebhook_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_CreateWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PUT", pattern_AdminService_UpdateWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.frontier.v1beta1.AdminService/UpdateWebhook", runtime.WithHTTPPathPattern("/v1beta1/admin/webhooks/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AdminService_UpdateWebhook_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_UpdateWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_AdminService_DeleteWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.frontier.v1beta1.AdminService/DeleteWebhook", runtime.WithHTTPPathPattern("/v1beta1/admin/webhooks/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AdminService_DeleteWebhook_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_DeleteWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AdminService_ListWebhooks_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.frontier.v1beta1.AdminService/ListWebhooks", runtime.WithHTTPPathPattern("/v1beta1/admin/webhooks")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AdminService_ListWebhooks_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_ListWebhooks_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2076,6 +2348,94 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu }) + mux.Handle("POST", pattern_AdminService_CreateWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.frontier.v1beta1.AdminService/CreateWebhook", runtime.WithHTTPPathPattern("/v1beta1/admin/webhooks")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AdminService_CreateWebhook_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_CreateWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PUT", pattern_AdminService_UpdateWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.frontier.v1beta1.AdminService/UpdateWebhook", runtime.WithHTTPPathPattern("/v1beta1/admin/webhooks/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AdminService_UpdateWebhook_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_UpdateWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_AdminService_DeleteWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.frontier.v1beta1.AdminService/DeleteWebhook", runtime.WithHTTPPathPattern("/v1beta1/admin/webhooks/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AdminService_DeleteWebhook_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_DeleteWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AdminService_ListWebhooks_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.frontier.v1beta1.AdminService/ListWebhooks", runtime.WithHTTPPathPattern("/v1beta1/admin/webhooks")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AdminService_ListWebhooks_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AdminService_ListWebhooks_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2123,6 +2483,14 @@ var ( pattern_AdminService_RevertBillingUsage_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"v1beta1", "admin", "organizations", "org_id", "billing", "billing_id", "usage", "usage_id", "revert"}, "")) pattern_AdminService_RevertBillingUsage_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1beta1", "organizations", "billing", "usages", "revert"}, "")) + + pattern_AdminService_CreateWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1beta1", "admin", "webhooks"}, "")) + + pattern_AdminService_UpdateWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1beta1", "admin", "webhooks", "id"}, "")) + + pattern_AdminService_DeleteWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1beta1", "admin", "webhooks", "id"}, "")) + + pattern_AdminService_ListWebhooks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1beta1", "admin", "webhooks"}, "")) ) var ( @@ -2169,4 +2537,12 @@ var ( forward_AdminService_RevertBillingUsage_0 = runtime.ForwardResponseMessage forward_AdminService_RevertBillingUsage_1 = runtime.ForwardResponseMessage + + forward_AdminService_CreateWebhook_0 = runtime.ForwardResponseMessage + + forward_AdminService_UpdateWebhook_0 = runtime.ForwardResponseMessage + + forward_AdminService_DeleteWebhook_0 = runtime.ForwardResponseMessage + + forward_AdminService_ListWebhooks_0 = runtime.ForwardResponseMessage ) diff --git a/proto/v1beta1/admin.pb.validate.go b/proto/v1beta1/admin.pb.validate.go index 6831a6bcd..b950e417b 100644 --- a/proto/v1beta1/admin.pb.validate.go +++ b/proto/v1beta1/admin.pb.validate.go @@ -5455,3 +5455,1185 @@ var _ interface { Cause() error ErrorName() string } = RevertBillingUsageResponseValidationError{} + +// Validate checks the field values on WebhookRequestBody with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *WebhookRequestBody) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on WebhookRequestBody with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// WebhookRequestBodyMultiError, or nil if none found. +func (m *WebhookRequestBody) ValidateAll() error { + return m.validate(true) +} + +func (m *WebhookRequestBody) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if uri, err := url.Parse(m.GetUrl()); err != nil { + err = WebhookRequestBodyValidationError{ + field: "Url", + reason: "value must be a valid URI", + cause: err, + } + if !all { + return err + } + errors = append(errors, err) + } else if !uri.IsAbs() { + err := WebhookRequestBodyValidationError{ + field: "Url", + reason: "value must be absolute", + } + if !all { + return err + } + errors = append(errors, err) + } + + // no validation rules for Description + + // no validation rules for Headers + + if m.GetState() != "" { + + if _, ok := _WebhookRequestBody_State_InLookup[m.GetState()]; !ok { + err := WebhookRequestBodyValidationError{ + field: "State", + reason: "value must be in list [enabled disabled]", + } + if !all { + return err + } + errors = append(errors, err) + } + + } + + if all { + switch v := interface{}(m.GetMetadata()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, WebhookRequestBodyValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, WebhookRequestBodyValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetMetadata()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return WebhookRequestBodyValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return WebhookRequestBodyMultiError(errors) + } + + return nil +} + +// WebhookRequestBodyMultiError is an error wrapping multiple validation errors +// returned by WebhookRequestBody.ValidateAll() if the designated constraints +// aren't met. +type WebhookRequestBodyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m WebhookRequestBodyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m WebhookRequestBodyMultiError) AllErrors() []error { return m } + +// WebhookRequestBodyValidationError is the validation error returned by +// WebhookRequestBody.Validate if the designated constraints aren't met. +type WebhookRequestBodyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e WebhookRequestBodyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e WebhookRequestBodyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e WebhookRequestBodyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e WebhookRequestBodyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e WebhookRequestBodyValidationError) ErrorName() string { + return "WebhookRequestBodyValidationError" +} + +// Error satisfies the builtin error interface +func (e WebhookRequestBodyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sWebhookRequestBody.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = WebhookRequestBodyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = WebhookRequestBodyValidationError{} + +var _WebhookRequestBody_State_InLookup = map[string]struct{}{ + "enabled": {}, + "disabled": {}, +} + +// Validate checks the field values on CreateWebhookRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateWebhookRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateWebhookRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateWebhookRequestMultiError, or nil if none found. +func (m *CreateWebhookRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateWebhookRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetBody()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, CreateWebhookRequestValidationError{ + field: "Body", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, CreateWebhookRequestValidationError{ + field: "Body", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetBody()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return CreateWebhookRequestValidationError{ + field: "Body", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return CreateWebhookRequestMultiError(errors) + } + + return nil +} + +// CreateWebhookRequestMultiError is an error wrapping multiple validation +// errors returned by CreateWebhookRequest.ValidateAll() if the designated +// constraints aren't met. +type CreateWebhookRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateWebhookRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateWebhookRequestMultiError) AllErrors() []error { return m } + +// CreateWebhookRequestValidationError is the validation error returned by +// CreateWebhookRequest.Validate if the designated constraints aren't met. +type CreateWebhookRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateWebhookRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateWebhookRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateWebhookRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateWebhookRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateWebhookRequestValidationError) ErrorName() string { + return "CreateWebhookRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateWebhookRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateWebhookRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateWebhookRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateWebhookRequestValidationError{} + +// Validate checks the field values on CreateWebhookResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateWebhookResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateWebhookResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateWebhookResponseMultiError, or nil if none found. +func (m *CreateWebhookResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateWebhookResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetWebhook()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, CreateWebhookResponseValidationError{ + field: "Webhook", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, CreateWebhookResponseValidationError{ + field: "Webhook", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetWebhook()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return CreateWebhookResponseValidationError{ + field: "Webhook", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return CreateWebhookResponseMultiError(errors) + } + + return nil +} + +// CreateWebhookResponseMultiError is an error wrapping multiple validation +// errors returned by CreateWebhookResponse.ValidateAll() if the designated +// constraints aren't met. +type CreateWebhookResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateWebhookResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateWebhookResponseMultiError) AllErrors() []error { return m } + +// CreateWebhookResponseValidationError is the validation error returned by +// CreateWebhookResponse.Validate if the designated constraints aren't met. +type CreateWebhookResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateWebhookResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateWebhookResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateWebhookResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateWebhookResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateWebhookResponseValidationError) ErrorName() string { + return "CreateWebhookResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateWebhookResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateWebhookResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateWebhookResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateWebhookResponseValidationError{} + +// Validate checks the field values on UpdateWebhookRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *UpdateWebhookRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateWebhookRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UpdateWebhookRequestMultiError, or nil if none found. +func (m *UpdateWebhookRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateWebhookRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if err := m._validateUuid(m.GetId()); err != nil { + err = UpdateWebhookRequestValidationError{ + field: "Id", + reason: "value must be a valid UUID", + cause: err, + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetBody()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, UpdateWebhookRequestValidationError{ + field: "Body", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, UpdateWebhookRequestValidationError{ + field: "Body", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetBody()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return UpdateWebhookRequestValidationError{ + field: "Body", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return UpdateWebhookRequestMultiError(errors) + } + + return nil +} + +func (m *UpdateWebhookRequest) _validateUuid(uuid string) error { + if matched := _admin_uuidPattern.MatchString(uuid); !matched { + return errors.New("invalid uuid format") + } + + return nil +} + +// UpdateWebhookRequestMultiError is an error wrapping multiple validation +// errors returned by UpdateWebhookRequest.ValidateAll() if the designated +// constraints aren't met. +type UpdateWebhookRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateWebhookRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateWebhookRequestMultiError) AllErrors() []error { return m } + +// UpdateWebhookRequestValidationError is the validation error returned by +// UpdateWebhookRequest.Validate if the designated constraints aren't met. +type UpdateWebhookRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateWebhookRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateWebhookRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateWebhookRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateWebhookRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateWebhookRequestValidationError) ErrorName() string { + return "UpdateWebhookRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateWebhookRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateWebhookRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateWebhookRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateWebhookRequestValidationError{} + +// Validate checks the field values on UpdateWebhookResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *UpdateWebhookResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateWebhookResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UpdateWebhookResponseMultiError, or nil if none found. +func (m *UpdateWebhookResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateWebhookResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetWebhook()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, UpdateWebhookResponseValidationError{ + field: "Webhook", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, UpdateWebhookResponseValidationError{ + field: "Webhook", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetWebhook()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return UpdateWebhookResponseValidationError{ + field: "Webhook", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return UpdateWebhookResponseMultiError(errors) + } + + return nil +} + +// UpdateWebhookResponseMultiError is an error wrapping multiple validation +// errors returned by UpdateWebhookResponse.ValidateAll() if the designated +// constraints aren't met. +type UpdateWebhookResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateWebhookResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateWebhookResponseMultiError) AllErrors() []error { return m } + +// UpdateWebhookResponseValidationError is the validation error returned by +// UpdateWebhookResponse.Validate if the designated constraints aren't met. +type UpdateWebhookResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateWebhookResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateWebhookResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateWebhookResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateWebhookResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateWebhookResponseValidationError) ErrorName() string { + return "UpdateWebhookResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateWebhookResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateWebhookResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateWebhookResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateWebhookResponseValidationError{} + +// Validate checks the field values on DeleteWebhookRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *DeleteWebhookRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteWebhookRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteWebhookRequestMultiError, or nil if none found. +func (m *DeleteWebhookRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteWebhookRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if err := m._validateUuid(m.GetId()); err != nil { + err = DeleteWebhookRequestValidationError{ + field: "Id", + reason: "value must be a valid UUID", + cause: err, + } + if !all { + return err + } + errors = append(errors, err) + } + + if len(errors) > 0 { + return DeleteWebhookRequestMultiError(errors) + } + + return nil +} + +func (m *DeleteWebhookRequest) _validateUuid(uuid string) error { + if matched := _admin_uuidPattern.MatchString(uuid); !matched { + return errors.New("invalid uuid format") + } + + return nil +} + +// DeleteWebhookRequestMultiError is an error wrapping multiple validation +// errors returned by DeleteWebhookRequest.ValidateAll() if the designated +// constraints aren't met. +type DeleteWebhookRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteWebhookRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteWebhookRequestMultiError) AllErrors() []error { return m } + +// DeleteWebhookRequestValidationError is the validation error returned by +// DeleteWebhookRequest.Validate if the designated constraints aren't met. +type DeleteWebhookRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteWebhookRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteWebhookRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteWebhookRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteWebhookRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteWebhookRequestValidationError) ErrorName() string { + return "DeleteWebhookRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteWebhookRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteWebhookRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteWebhookRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteWebhookRequestValidationError{} + +// Validate checks the field values on DeleteWebhookResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *DeleteWebhookResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteWebhookResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteWebhookResponseMultiError, or nil if none found. +func (m *DeleteWebhookResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteWebhookResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return DeleteWebhookResponseMultiError(errors) + } + + return nil +} + +// DeleteWebhookResponseMultiError is an error wrapping multiple validation +// errors returned by DeleteWebhookResponse.ValidateAll() if the designated +// constraints aren't met. +type DeleteWebhookResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteWebhookResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteWebhookResponseMultiError) AllErrors() []error { return m } + +// DeleteWebhookResponseValidationError is the validation error returned by +// DeleteWebhookResponse.Validate if the designated constraints aren't met. +type DeleteWebhookResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteWebhookResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteWebhookResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteWebhookResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteWebhookResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteWebhookResponseValidationError) ErrorName() string { + return "DeleteWebhookResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteWebhookResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteWebhookResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteWebhookResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteWebhookResponseValidationError{} + +// Validate checks the field values on ListWebhooksRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListWebhooksRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListWebhooksRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListWebhooksRequestMultiError, or nil if none found. +func (m *ListWebhooksRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *ListWebhooksRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return ListWebhooksRequestMultiError(errors) + } + + return nil +} + +// ListWebhooksRequestMultiError is an error wrapping multiple validation +// errors returned by ListWebhooksRequest.ValidateAll() if the designated +// constraints aren't met. +type ListWebhooksRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListWebhooksRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListWebhooksRequestMultiError) AllErrors() []error { return m } + +// ListWebhooksRequestValidationError is the validation error returned by +// ListWebhooksRequest.Validate if the designated constraints aren't met. +type ListWebhooksRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListWebhooksRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListWebhooksRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListWebhooksRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListWebhooksRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListWebhooksRequestValidationError) ErrorName() string { + return "ListWebhooksRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e ListWebhooksRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListWebhooksRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListWebhooksRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListWebhooksRequestValidationError{} + +// Validate checks the field values on ListWebhooksResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListWebhooksResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListWebhooksResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListWebhooksResponseMultiError, or nil if none found. +func (m *ListWebhooksResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *ListWebhooksResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + for idx, item := range m.GetWebhooks() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ListWebhooksResponseValidationError{ + field: fmt.Sprintf("Webhooks[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ListWebhooksResponseValidationError{ + field: fmt.Sprintf("Webhooks[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ListWebhooksResponseValidationError{ + field: fmt.Sprintf("Webhooks[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ListWebhooksResponseMultiError(errors) + } + + return nil +} + +// ListWebhooksResponseMultiError is an error wrapping multiple validation +// errors returned by ListWebhooksResponse.ValidateAll() if the designated +// constraints aren't met. +type ListWebhooksResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListWebhooksResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListWebhooksResponseMultiError) AllErrors() []error { return m } + +// ListWebhooksResponseValidationError is the validation error returned by +// ListWebhooksResponse.Validate if the designated constraints aren't met. +type ListWebhooksResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListWebhooksResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListWebhooksResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListWebhooksResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListWebhooksResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListWebhooksResponseValidationError) ErrorName() string { + return "ListWebhooksResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e ListWebhooksResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListWebhooksResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListWebhooksResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListWebhooksResponseValidationError{} diff --git a/proto/v1beta1/admin_grpc.pb.go b/proto/v1beta1/admin_grpc.pb.go index 1ab40fa11..3fdd36f07 100644 --- a/proto/v1beta1/admin_grpc.pb.go +++ b/proto/v1beta1/admin_grpc.pb.go @@ -40,6 +40,10 @@ const ( AdminService_ListAllInvoices_FullMethodName = "/raystack.frontier.v1beta1.AdminService/ListAllInvoices" AdminService_ListAllBillingAccounts_FullMethodName = "/raystack.frontier.v1beta1.AdminService/ListAllBillingAccounts" AdminService_RevertBillingUsage_FullMethodName = "/raystack.frontier.v1beta1.AdminService/RevertBillingUsage" + AdminService_CreateWebhook_FullMethodName = "/raystack.frontier.v1beta1.AdminService/CreateWebhook" + AdminService_UpdateWebhook_FullMethodName = "/raystack.frontier.v1beta1.AdminService/UpdateWebhook" + AdminService_DeleteWebhook_FullMethodName = "/raystack.frontier.v1beta1.AdminService/DeleteWebhook" + AdminService_ListWebhooks_FullMethodName = "/raystack.frontier.v1beta1.AdminService/ListWebhooks" ) // AdminServiceClient is the client API for AdminService service. @@ -80,6 +84,11 @@ type AdminServiceClient interface { ListAllBillingAccounts(ctx context.Context, in *ListAllBillingAccountsRequest, opts ...grpc.CallOption) (*ListAllBillingAccountsResponse, error) // Usage RevertBillingUsage(ctx context.Context, in *RevertBillingUsageRequest, opts ...grpc.CallOption) (*RevertBillingUsageResponse, error) + // Webhooks + CreateWebhook(ctx context.Context, in *CreateWebhookRequest, opts ...grpc.CallOption) (*CreateWebhookResponse, error) + UpdateWebhook(ctx context.Context, in *UpdateWebhookRequest, opts ...grpc.CallOption) (*UpdateWebhookResponse, error) + DeleteWebhook(ctx context.Context, in *DeleteWebhookRequest, opts ...grpc.CallOption) (*DeleteWebhookResponse, error) + ListWebhooks(ctx context.Context, in *ListWebhooksRequest, opts ...grpc.CallOption) (*ListWebhooksResponse, error) } type adminServiceClient struct { @@ -279,6 +288,42 @@ func (c *adminServiceClient) RevertBillingUsage(ctx context.Context, in *RevertB return out, nil } +func (c *adminServiceClient) CreateWebhook(ctx context.Context, in *CreateWebhookRequest, opts ...grpc.CallOption) (*CreateWebhookResponse, error) { + out := new(CreateWebhookResponse) + err := c.cc.Invoke(ctx, AdminService_CreateWebhook_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminServiceClient) UpdateWebhook(ctx context.Context, in *UpdateWebhookRequest, opts ...grpc.CallOption) (*UpdateWebhookResponse, error) { + out := new(UpdateWebhookResponse) + err := c.cc.Invoke(ctx, AdminService_UpdateWebhook_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminServiceClient) DeleteWebhook(ctx context.Context, in *DeleteWebhookRequest, opts ...grpc.CallOption) (*DeleteWebhookResponse, error) { + out := new(DeleteWebhookResponse) + err := c.cc.Invoke(ctx, AdminService_DeleteWebhook_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminServiceClient) ListWebhooks(ctx context.Context, in *ListWebhooksRequest, opts ...grpc.CallOption) (*ListWebhooksResponse, error) { + out := new(ListWebhooksResponse) + err := c.cc.Invoke(ctx, AdminService_ListWebhooks_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // AdminServiceServer is the server API for AdminService service. // All implementations must embed UnimplementedAdminServiceServer // for forward compatibility @@ -317,6 +362,11 @@ type AdminServiceServer interface { ListAllBillingAccounts(context.Context, *ListAllBillingAccountsRequest) (*ListAllBillingAccountsResponse, error) // Usage RevertBillingUsage(context.Context, *RevertBillingUsageRequest) (*RevertBillingUsageResponse, error) + // Webhooks + CreateWebhook(context.Context, *CreateWebhookRequest) (*CreateWebhookResponse, error) + UpdateWebhook(context.Context, *UpdateWebhookRequest) (*UpdateWebhookResponse, error) + DeleteWebhook(context.Context, *DeleteWebhookRequest) (*DeleteWebhookResponse, error) + ListWebhooks(context.Context, *ListWebhooksRequest) (*ListWebhooksResponse, error) mustEmbedUnimplementedAdminServiceServer() } @@ -387,6 +437,18 @@ func (UnimplementedAdminServiceServer) ListAllBillingAccounts(context.Context, * func (UnimplementedAdminServiceServer) RevertBillingUsage(context.Context, *RevertBillingUsageRequest) (*RevertBillingUsageResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RevertBillingUsage not implemented") } +func (UnimplementedAdminServiceServer) CreateWebhook(context.Context, *CreateWebhookRequest) (*CreateWebhookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateWebhook not implemented") +} +func (UnimplementedAdminServiceServer) UpdateWebhook(context.Context, *UpdateWebhookRequest) (*UpdateWebhookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateWebhook not implemented") +} +func (UnimplementedAdminServiceServer) DeleteWebhook(context.Context, *DeleteWebhookRequest) (*DeleteWebhookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteWebhook not implemented") +} +func (UnimplementedAdminServiceServer) ListWebhooks(context.Context, *ListWebhooksRequest) (*ListWebhooksResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListWebhooks not implemented") +} func (UnimplementedAdminServiceServer) mustEmbedUnimplementedAdminServiceServer() {} // UnsafeAdminServiceServer may be embedded to opt out of forward compatibility for this service. @@ -778,6 +840,78 @@ func _AdminService_RevertBillingUsage_Handler(srv interface{}, ctx context.Conte return interceptor(ctx, in, info, handler) } +func _AdminService_CreateWebhook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateWebhookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServiceServer).CreateWebhook(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminService_CreateWebhook_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServiceServer).CreateWebhook(ctx, req.(*CreateWebhookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AdminService_UpdateWebhook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateWebhookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServiceServer).UpdateWebhook(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminService_UpdateWebhook_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServiceServer).UpdateWebhook(ctx, req.(*UpdateWebhookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AdminService_DeleteWebhook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteWebhookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServiceServer).DeleteWebhook(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminService_DeleteWebhook_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServiceServer).DeleteWebhook(ctx, req.(*DeleteWebhookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AdminService_ListWebhooks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListWebhooksRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServiceServer).ListWebhooks(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AdminService_ListWebhooks_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServiceServer).ListWebhooks(ctx, req.(*ListWebhooksRequest)) + } + return interceptor(ctx, in, info, handler) +} + // AdminService_ServiceDesc is the grpc.ServiceDesc for AdminService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -869,6 +1003,22 @@ var AdminService_ServiceDesc = grpc.ServiceDesc{ MethodName: "RevertBillingUsage", Handler: _AdminService_RevertBillingUsage_Handler, }, + { + MethodName: "CreateWebhook", + Handler: _AdminService_CreateWebhook_Handler, + }, + { + MethodName: "UpdateWebhook", + Handler: _AdminService_UpdateWebhook_Handler, + }, + { + MethodName: "DeleteWebhook", + Handler: _AdminService_DeleteWebhook_Handler, + }, + { + MethodName: "ListWebhooks", + Handler: _AdminService_ListWebhooks_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "raystack/frontier/v1beta1/admin.proto", diff --git a/proto/v1beta1/models.pb.go b/proto/v1beta1/models.pb.go index 1e63b3bf2..156bacb66 100644 --- a/proto/v1beta1/models.pb.go +++ b/proto/v1beta1/models.pb.go @@ -3954,6 +3954,207 @@ func (x *PaymentMethod) GetCreatedAt() *timestamppb.Timestamp { return nil } +type Webhook struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"` + SubscribedEvents []string `protobuf:"bytes,4,rep,name=subscribed_events,json=subscribedEvents,proto3" json:"subscribed_events,omitempty"` + // headers to be sent with the webhook + Headers map[string]string `protobuf:"bytes,5,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // secret to sign the payload, there could be multiple enabled secrets for a webhook + // but only one will be used to sign the payload, this is useful for rotating secrets + Secrets []*Webhook_Secret `protobuf:"bytes,6,rep,name=secrets,proto3" json:"secrets,omitempty"` + State string `protobuf:"bytes,7,opt,name=state,proto3" json:"state,omitempty"` + Metadata *structpb.Struct `protobuf:"bytes,20,opt,name=metadata,proto3" json:"metadata,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,21,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,22,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` +} + +func (x *Webhook) Reset() { + *x = Webhook{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Webhook) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Webhook) ProtoMessage() {} + +func (x *Webhook) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Webhook.ProtoReflect.Descriptor instead. +func (*Webhook) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{35} +} + +func (x *Webhook) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Webhook) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Webhook) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *Webhook) GetSubscribedEvents() []string { + if x != nil { + return x.SubscribedEvents + } + return nil +} + +func (x *Webhook) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + +func (x *Webhook) GetSecrets() []*Webhook_Secret { + if x != nil { + return x.Secrets + } + return nil +} + +func (x *Webhook) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *Webhook) GetMetadata() *structpb.Struct { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *Webhook) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Webhook) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +type WebhookEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` + Data *structpb.Struct `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + Metadata *structpb.Struct `protobuf:"bytes,20,opt,name=metadata,proto3" json:"metadata,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,21,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *WebhookEvent) Reset() { + *x = WebhookEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WebhookEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WebhookEvent) ProtoMessage() {} + +func (x *WebhookEvent) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WebhookEvent.ProtoReflect.Descriptor instead. +func (*WebhookEvent) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{36} +} + +func (x *WebhookEvent) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *WebhookEvent) GetAction() string { + if x != nil { + return x.Action + } + return "" +} + +func (x *WebhookEvent) GetData() *structpb.Struct { + if x != nil { + return x.Data + } + return nil +} + +func (x *WebhookEvent) GetMetadata() *structpb.Struct { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *WebhookEvent) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + type RoleRequestBody struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3969,7 +4170,7 @@ type RoleRequestBody struct { func (x *RoleRequestBody) Reset() { *x = RoleRequestBody{} if protoimpl.UnsafeEnabled { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[35] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3982,7 +4183,7 @@ func (x *RoleRequestBody) String() string { func (*RoleRequestBody) ProtoMessage() {} func (x *RoleRequestBody) ProtoReflect() protoreflect.Message { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[35] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3995,7 +4196,7 @@ func (x *RoleRequestBody) ProtoReflect() protoreflect.Message { // Deprecated: Use RoleRequestBody.ProtoReflect.Descriptor instead. func (*RoleRequestBody) Descriptor() ([]byte, []int) { - return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{35} + return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{37} } func (x *RoleRequestBody) GetName() string { @@ -4045,7 +4246,7 @@ type PreferenceRequestBody struct { func (x *PreferenceRequestBody) Reset() { *x = PreferenceRequestBody{} if protoimpl.UnsafeEnabled { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[36] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4058,7 +4259,7 @@ func (x *PreferenceRequestBody) String() string { func (*PreferenceRequestBody) ProtoMessage() {} func (x *PreferenceRequestBody) ProtoReflect() protoreflect.Message { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[36] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4071,7 +4272,7 @@ func (x *PreferenceRequestBody) ProtoReflect() protoreflect.Message { // Deprecated: Use PreferenceRequestBody.ProtoReflect.Descriptor instead. func (*PreferenceRequestBody) Descriptor() ([]byte, []int) { - return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{36} + return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{38} } func (x *PreferenceRequestBody) GetName() string { @@ -4105,7 +4306,7 @@ type CheckoutSubscriptionBody struct { func (x *CheckoutSubscriptionBody) Reset() { *x = CheckoutSubscriptionBody{} if protoimpl.UnsafeEnabled { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[37] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4118,7 +4319,7 @@ func (x *CheckoutSubscriptionBody) String() string { func (*CheckoutSubscriptionBody) ProtoMessage() {} func (x *CheckoutSubscriptionBody) ProtoReflect() protoreflect.Message { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[37] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4131,7 +4332,7 @@ func (x *CheckoutSubscriptionBody) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckoutSubscriptionBody.ProtoReflect.Descriptor instead. func (*CheckoutSubscriptionBody) Descriptor() ([]byte, []int) { - return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{37} + return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{39} } func (x *CheckoutSubscriptionBody) GetPlan() string { @@ -4174,7 +4375,7 @@ type CheckoutProductBody struct { func (x *CheckoutProductBody) Reset() { *x = CheckoutProductBody{} if protoimpl.UnsafeEnabled { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[38] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4187,7 +4388,7 @@ func (x *CheckoutProductBody) String() string { func (*CheckoutProductBody) ProtoMessage() {} func (x *CheckoutProductBody) ProtoReflect() protoreflect.Message { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[38] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4200,7 +4401,7 @@ func (x *CheckoutProductBody) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckoutProductBody.ProtoReflect.Descriptor instead. func (*CheckoutProductBody) Descriptor() ([]byte, []int) { - return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{38} + return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{40} } func (x *CheckoutProductBody) GetProduct() string { @@ -4229,7 +4430,7 @@ type CheckoutSetupBody struct { func (x *CheckoutSetupBody) Reset() { *x = CheckoutSetupBody{} if protoimpl.UnsafeEnabled { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[39] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4242,7 +4443,7 @@ func (x *CheckoutSetupBody) String() string { func (*CheckoutSetupBody) ProtoMessage() {} func (x *CheckoutSetupBody) ProtoReflect() protoreflect.Message { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[39] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4255,7 +4456,7 @@ func (x *CheckoutSetupBody) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckoutSetupBody.ProtoReflect.Descriptor instead. func (*CheckoutSetupBody) Descriptor() ([]byte, []int) { - return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{39} + return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{41} } func (x *CheckoutSetupBody) GetPaymentMethod() bool { @@ -4288,7 +4489,7 @@ type BillingAccount_Address struct { func (x *BillingAccount_Address) Reset() { *x = BillingAccount_Address{} if protoimpl.UnsafeEnabled { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[41] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4301,7 +4502,7 @@ func (x *BillingAccount_Address) String() string { func (*BillingAccount_Address) ProtoMessage() {} func (x *BillingAccount_Address) ProtoReflect() protoreflect.Message { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[41] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4374,7 +4575,7 @@ type BillingAccount_Tax struct { func (x *BillingAccount_Tax) Reset() { *x = BillingAccount_Tax{} if protoimpl.UnsafeEnabled { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[42] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4387,7 +4588,7 @@ func (x *BillingAccount_Tax) String() string { func (*BillingAccount_Tax) ProtoMessage() {} func (x *BillingAccount_Tax) ProtoReflect() protoreflect.Message { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[42] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4430,7 +4631,7 @@ type BillingAccount_Balance struct { func (x *BillingAccount_Balance) Reset() { *x = BillingAccount_Balance{} if protoimpl.UnsafeEnabled { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[43] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4443,7 +4644,7 @@ func (x *BillingAccount_Balance) String() string { func (*BillingAccount_Balance) ProtoMessage() {} func (x *BillingAccount_Balance) ProtoReflect() protoreflect.Message { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[43] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4492,7 +4693,7 @@ type Subscription_Phase struct { func (x *Subscription_Phase) Reset() { *x = Subscription_Phase{} if protoimpl.UnsafeEnabled { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[44] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4505,7 +4706,7 @@ func (x *Subscription_Phase) String() string { func (*Subscription_Phase) ProtoMessage() {} func (x *Subscription_Phase) ProtoReflect() protoreflect.Message { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[44] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4549,7 +4750,7 @@ type Product_BehaviorConfig struct { func (x *Product_BehaviorConfig) Reset() { *x = Product_BehaviorConfig{} if protoimpl.UnsafeEnabled { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[45] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4562,7 +4763,7 @@ func (x *Product_BehaviorConfig) String() string { func (*Product_BehaviorConfig) ProtoMessage() {} func (x *Product_BehaviorConfig) ProtoReflect() protoreflect.Message { - mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[45] + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4606,6 +4807,61 @@ func (x *Product_BehaviorConfig) GetMaxQuantity() int64 { return 0 } +type Webhook_Secret struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Webhook_Secret) Reset() { + *x = Webhook_Secret{} + if protoimpl.UnsafeEnabled { + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Webhook_Secret) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Webhook_Secret) ProtoMessage() {} + +func (x *Webhook_Secret) ProtoReflect() protoreflect.Message { + mi := &file_raystack_frontier_v1beta1_models_proto_msgTypes[48] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Webhook_Secret.ProtoReflect.Descriptor instead. +func (*Webhook_Secret) Descriptor() ([]byte, []int) { + return file_raystack_frontier_v1beta1_models_proto_rawDescGZIP(), []int{35, 0} +} + +func (x *Webhook_Secret) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Webhook_Secret) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + var File_raystack_frontier_v1beta1_models_proto protoreflect.FileDescriptor var file_raystack_frontier_v1beta1_models_proto_rawDesc = []byte{ @@ -5726,6 +5982,59 @@ var file_raystack_frontier_v1beta1_models_proto_rawDesc = []byte{ 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xb7, 0x04, 0x0a, 0x07, 0x57, 0x65, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x12, 0x43, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x66, 0x72, + 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x07, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x1a, 0x2e, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x93, 0x02, 0x0a, 0x0c, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x79, + 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x15, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x3e, + 0x92, 0x41, 0x3b, 0x32, 0x1d, 0x54, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x77, 0x61, 0x73, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x2e, 0x4a, 0x1a, 0x22, 0x32, 0x30, 0x32, 0x33, 0x2d, 0x30, 0x36, 0x2d, 0x30, 0x37, 0x54, + 0x30, 0x35, 0x3a, 0x33, 0x39, 0x3a, 0x35, 0x36, 0x2e, 0x39, 0x36, 0x31, 0x5a, 0x22, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0xdb, 0x01, 0x0a, 0x0f, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xfa, 0x42, 0x16, @@ -5791,7 +6100,7 @@ func file_raystack_frontier_v1beta1_models_proto_rawDescGZIP() []byte { return file_raystack_frontier_v1beta1_models_proto_rawDescData } -var file_raystack_frontier_v1beta1_models_proto_msgTypes = make([]protoimpl.MessageInfo, 46) +var file_raystack_frontier_v1beta1_models_proto_msgTypes = make([]protoimpl.MessageInfo, 50) var file_raystack_frontier_v1beta1_models_proto_goTypes = []interface{}{ (*User)(nil), // 0: raystack.frontier.v1beta1.User (*ServiceUser)(nil), // 1: raystack.frontier.v1beta1.ServiceUser @@ -5828,133 +6137,145 @@ var file_raystack_frontier_v1beta1_models_proto_goTypes = []interface{}{ (*Usage)(nil), // 32: raystack.frontier.v1beta1.Usage (*Invoice)(nil), // 33: raystack.frontier.v1beta1.Invoice (*PaymentMethod)(nil), // 34: raystack.frontier.v1beta1.PaymentMethod - (*RoleRequestBody)(nil), // 35: raystack.frontier.v1beta1.RoleRequestBody - (*PreferenceRequestBody)(nil), // 36: raystack.frontier.v1beta1.PreferenceRequestBody - (*CheckoutSubscriptionBody)(nil), // 37: raystack.frontier.v1beta1.CheckoutSubscriptionBody - (*CheckoutProductBody)(nil), // 38: raystack.frontier.v1beta1.CheckoutProductBody - (*CheckoutSetupBody)(nil), // 39: raystack.frontier.v1beta1.CheckoutSetupBody - nil, // 40: raystack.frontier.v1beta1.AuditLog.ContextEntry - (*BillingAccount_Address)(nil), // 41: raystack.frontier.v1beta1.BillingAccount.Address - (*BillingAccount_Tax)(nil), // 42: raystack.frontier.v1beta1.BillingAccount.Tax - (*BillingAccount_Balance)(nil), // 43: raystack.frontier.v1beta1.BillingAccount.Balance - (*Subscription_Phase)(nil), // 44: raystack.frontier.v1beta1.Subscription.Phase - (*Product_BehaviorConfig)(nil), // 45: raystack.frontier.v1beta1.Product.BehaviorConfig - (*structpb.Struct)(nil), // 46: google.protobuf.Struct - (*timestamppb.Timestamp)(nil), // 47: google.protobuf.Timestamp + (*Webhook)(nil), // 35: raystack.frontier.v1beta1.Webhook + (*WebhookEvent)(nil), // 36: raystack.frontier.v1beta1.WebhookEvent + (*RoleRequestBody)(nil), // 37: raystack.frontier.v1beta1.RoleRequestBody + (*PreferenceRequestBody)(nil), // 38: raystack.frontier.v1beta1.PreferenceRequestBody + (*CheckoutSubscriptionBody)(nil), // 39: raystack.frontier.v1beta1.CheckoutSubscriptionBody + (*CheckoutProductBody)(nil), // 40: raystack.frontier.v1beta1.CheckoutProductBody + (*CheckoutSetupBody)(nil), // 41: raystack.frontier.v1beta1.CheckoutSetupBody + nil, // 42: raystack.frontier.v1beta1.AuditLog.ContextEntry + (*BillingAccount_Address)(nil), // 43: raystack.frontier.v1beta1.BillingAccount.Address + (*BillingAccount_Tax)(nil), // 44: raystack.frontier.v1beta1.BillingAccount.Tax + (*BillingAccount_Balance)(nil), // 45: raystack.frontier.v1beta1.BillingAccount.Balance + (*Subscription_Phase)(nil), // 46: raystack.frontier.v1beta1.Subscription.Phase + (*Product_BehaviorConfig)(nil), // 47: raystack.frontier.v1beta1.Product.BehaviorConfig + (*Webhook_Secret)(nil), // 48: raystack.frontier.v1beta1.Webhook.Secret + nil, // 49: raystack.frontier.v1beta1.Webhook.HeadersEntry + (*structpb.Struct)(nil), // 50: google.protobuf.Struct + (*timestamppb.Timestamp)(nil), // 51: google.protobuf.Timestamp } var file_raystack_frontier_v1beta1_models_proto_depIdxs = []int32{ - 46, // 0: raystack.frontier.v1beta1.User.metadata:type_name -> google.protobuf.Struct - 47, // 1: raystack.frontier.v1beta1.User.created_at:type_name -> google.protobuf.Timestamp - 47, // 2: raystack.frontier.v1beta1.User.updated_at:type_name -> google.protobuf.Timestamp - 46, // 3: raystack.frontier.v1beta1.ServiceUser.metadata:type_name -> google.protobuf.Struct - 47, // 4: raystack.frontier.v1beta1.ServiceUser.created_at:type_name -> google.protobuf.Timestamp - 47, // 5: raystack.frontier.v1beta1.ServiceUser.updated_at:type_name -> google.protobuf.Timestamp - 46, // 6: raystack.frontier.v1beta1.Group.metadata:type_name -> google.protobuf.Struct - 47, // 7: raystack.frontier.v1beta1.Group.created_at:type_name -> google.protobuf.Timestamp - 47, // 8: raystack.frontier.v1beta1.Group.updated_at:type_name -> google.protobuf.Timestamp + 50, // 0: raystack.frontier.v1beta1.User.metadata:type_name -> google.protobuf.Struct + 51, // 1: raystack.frontier.v1beta1.User.created_at:type_name -> google.protobuf.Timestamp + 51, // 2: raystack.frontier.v1beta1.User.updated_at:type_name -> google.protobuf.Timestamp + 50, // 3: raystack.frontier.v1beta1.ServiceUser.metadata:type_name -> google.protobuf.Struct + 51, // 4: raystack.frontier.v1beta1.ServiceUser.created_at:type_name -> google.protobuf.Timestamp + 51, // 5: raystack.frontier.v1beta1.ServiceUser.updated_at:type_name -> google.protobuf.Timestamp + 50, // 6: raystack.frontier.v1beta1.Group.metadata:type_name -> google.protobuf.Struct + 51, // 7: raystack.frontier.v1beta1.Group.created_at:type_name -> google.protobuf.Timestamp + 51, // 8: raystack.frontier.v1beta1.Group.updated_at:type_name -> google.protobuf.Timestamp 0, // 9: raystack.frontier.v1beta1.Group.users:type_name -> raystack.frontier.v1beta1.User - 46, // 10: raystack.frontier.v1beta1.Role.metadata:type_name -> google.protobuf.Struct - 47, // 11: raystack.frontier.v1beta1.Role.created_at:type_name -> google.protobuf.Timestamp - 47, // 12: raystack.frontier.v1beta1.Role.updated_at:type_name -> google.protobuf.Timestamp - 46, // 13: raystack.frontier.v1beta1.Organization.metadata:type_name -> google.protobuf.Struct - 47, // 14: raystack.frontier.v1beta1.Organization.created_at:type_name -> google.protobuf.Timestamp - 47, // 15: raystack.frontier.v1beta1.Organization.updated_at:type_name -> google.protobuf.Timestamp - 46, // 16: raystack.frontier.v1beta1.Project.metadata:type_name -> google.protobuf.Struct - 47, // 17: raystack.frontier.v1beta1.Project.created_at:type_name -> google.protobuf.Timestamp - 47, // 18: raystack.frontier.v1beta1.Project.updated_at:type_name -> google.protobuf.Timestamp - 47, // 19: raystack.frontier.v1beta1.Domain.created_at:type_name -> google.protobuf.Timestamp - 47, // 20: raystack.frontier.v1beta1.Domain.updated_at:type_name -> google.protobuf.Timestamp - 47, // 21: raystack.frontier.v1beta1.Policy.created_at:type_name -> google.protobuf.Timestamp - 47, // 22: raystack.frontier.v1beta1.Policy.updated_at:type_name -> google.protobuf.Timestamp - 46, // 23: raystack.frontier.v1beta1.Policy.metadata:type_name -> google.protobuf.Struct - 47, // 24: raystack.frontier.v1beta1.Relation.created_at:type_name -> google.protobuf.Timestamp - 47, // 25: raystack.frontier.v1beta1.Relation.updated_at:type_name -> google.protobuf.Timestamp - 47, // 26: raystack.frontier.v1beta1.Permission.created_at:type_name -> google.protobuf.Timestamp - 47, // 27: raystack.frontier.v1beta1.Permission.updated_at:type_name -> google.protobuf.Timestamp - 46, // 28: raystack.frontier.v1beta1.Permission.metadata:type_name -> google.protobuf.Struct - 46, // 29: raystack.frontier.v1beta1.Namespace.metadata:type_name -> google.protobuf.Struct - 47, // 30: raystack.frontier.v1beta1.Namespace.created_at:type_name -> google.protobuf.Timestamp - 47, // 31: raystack.frontier.v1beta1.Namespace.updated_at:type_name -> google.protobuf.Timestamp - 47, // 32: raystack.frontier.v1beta1.Resource.created_at:type_name -> google.protobuf.Timestamp - 47, // 33: raystack.frontier.v1beta1.Resource.updated_at:type_name -> google.protobuf.Timestamp - 46, // 34: raystack.frontier.v1beta1.Resource.metadata:type_name -> google.protobuf.Struct - 47, // 35: raystack.frontier.v1beta1.MetaSchema.created_at:type_name -> google.protobuf.Timestamp - 47, // 36: raystack.frontier.v1beta1.MetaSchema.updated_at:type_name -> google.protobuf.Timestamp - 46, // 37: raystack.frontier.v1beta1.Invitation.metadata:type_name -> google.protobuf.Struct - 47, // 38: raystack.frontier.v1beta1.Invitation.created_at:type_name -> google.protobuf.Timestamp - 47, // 39: raystack.frontier.v1beta1.Invitation.expires_at:type_name -> google.protobuf.Timestamp - 47, // 40: raystack.frontier.v1beta1.ServiceUserJWK.created_at:type_name -> google.protobuf.Timestamp - 47, // 41: raystack.frontier.v1beta1.SecretCredential.created_at:type_name -> google.protobuf.Timestamp - 47, // 42: raystack.frontier.v1beta1.ServiceUserToken.created_at:type_name -> google.protobuf.Timestamp + 50, // 10: raystack.frontier.v1beta1.Role.metadata:type_name -> google.protobuf.Struct + 51, // 11: raystack.frontier.v1beta1.Role.created_at:type_name -> google.protobuf.Timestamp + 51, // 12: raystack.frontier.v1beta1.Role.updated_at:type_name -> google.protobuf.Timestamp + 50, // 13: raystack.frontier.v1beta1.Organization.metadata:type_name -> google.protobuf.Struct + 51, // 14: raystack.frontier.v1beta1.Organization.created_at:type_name -> google.protobuf.Timestamp + 51, // 15: raystack.frontier.v1beta1.Organization.updated_at:type_name -> google.protobuf.Timestamp + 50, // 16: raystack.frontier.v1beta1.Project.metadata:type_name -> google.protobuf.Struct + 51, // 17: raystack.frontier.v1beta1.Project.created_at:type_name -> google.protobuf.Timestamp + 51, // 18: raystack.frontier.v1beta1.Project.updated_at:type_name -> google.protobuf.Timestamp + 51, // 19: raystack.frontier.v1beta1.Domain.created_at:type_name -> google.protobuf.Timestamp + 51, // 20: raystack.frontier.v1beta1.Domain.updated_at:type_name -> google.protobuf.Timestamp + 51, // 21: raystack.frontier.v1beta1.Policy.created_at:type_name -> google.protobuf.Timestamp + 51, // 22: raystack.frontier.v1beta1.Policy.updated_at:type_name -> google.protobuf.Timestamp + 50, // 23: raystack.frontier.v1beta1.Policy.metadata:type_name -> google.protobuf.Struct + 51, // 24: raystack.frontier.v1beta1.Relation.created_at:type_name -> google.protobuf.Timestamp + 51, // 25: raystack.frontier.v1beta1.Relation.updated_at:type_name -> google.protobuf.Timestamp + 51, // 26: raystack.frontier.v1beta1.Permission.created_at:type_name -> google.protobuf.Timestamp + 51, // 27: raystack.frontier.v1beta1.Permission.updated_at:type_name -> google.protobuf.Timestamp + 50, // 28: raystack.frontier.v1beta1.Permission.metadata:type_name -> google.protobuf.Struct + 50, // 29: raystack.frontier.v1beta1.Namespace.metadata:type_name -> google.protobuf.Struct + 51, // 30: raystack.frontier.v1beta1.Namespace.created_at:type_name -> google.protobuf.Timestamp + 51, // 31: raystack.frontier.v1beta1.Namespace.updated_at:type_name -> google.protobuf.Timestamp + 51, // 32: raystack.frontier.v1beta1.Resource.created_at:type_name -> google.protobuf.Timestamp + 51, // 33: raystack.frontier.v1beta1.Resource.updated_at:type_name -> google.protobuf.Timestamp + 50, // 34: raystack.frontier.v1beta1.Resource.metadata:type_name -> google.protobuf.Struct + 51, // 35: raystack.frontier.v1beta1.MetaSchema.created_at:type_name -> google.protobuf.Timestamp + 51, // 36: raystack.frontier.v1beta1.MetaSchema.updated_at:type_name -> google.protobuf.Timestamp + 50, // 37: raystack.frontier.v1beta1.Invitation.metadata:type_name -> google.protobuf.Struct + 51, // 38: raystack.frontier.v1beta1.Invitation.created_at:type_name -> google.protobuf.Timestamp + 51, // 39: raystack.frontier.v1beta1.Invitation.expires_at:type_name -> google.protobuf.Timestamp + 51, // 40: raystack.frontier.v1beta1.ServiceUserJWK.created_at:type_name -> google.protobuf.Timestamp + 51, // 41: raystack.frontier.v1beta1.SecretCredential.created_at:type_name -> google.protobuf.Timestamp + 51, // 42: raystack.frontier.v1beta1.ServiceUserToken.created_at:type_name -> google.protobuf.Timestamp 19, // 43: raystack.frontier.v1beta1.AuditLog.actor:type_name -> raystack.frontier.v1beta1.AuditLogActor 20, // 44: raystack.frontier.v1beta1.AuditLog.target:type_name -> raystack.frontier.v1beta1.AuditLogTarget - 40, // 45: raystack.frontier.v1beta1.AuditLog.context:type_name -> raystack.frontier.v1beta1.AuditLog.ContextEntry - 47, // 46: raystack.frontier.v1beta1.AuditLog.created_at:type_name -> google.protobuf.Timestamp - 47, // 47: raystack.frontier.v1beta1.Preference.created_at:type_name -> google.protobuf.Timestamp - 47, // 48: raystack.frontier.v1beta1.Preference.updated_at:type_name -> google.protobuf.Timestamp - 41, // 49: raystack.frontier.v1beta1.BillingAccount.address:type_name -> raystack.frontier.v1beta1.BillingAccount.Address - 42, // 50: raystack.frontier.v1beta1.BillingAccount.tax_data:type_name -> raystack.frontier.v1beta1.BillingAccount.Tax - 46, // 51: raystack.frontier.v1beta1.BillingAccount.metadata:type_name -> google.protobuf.Struct - 47, // 52: raystack.frontier.v1beta1.BillingAccount.created_at:type_name -> google.protobuf.Timestamp - 47, // 53: raystack.frontier.v1beta1.BillingAccount.updated_at:type_name -> google.protobuf.Timestamp + 42, // 45: raystack.frontier.v1beta1.AuditLog.context:type_name -> raystack.frontier.v1beta1.AuditLog.ContextEntry + 51, // 46: raystack.frontier.v1beta1.AuditLog.created_at:type_name -> google.protobuf.Timestamp + 51, // 47: raystack.frontier.v1beta1.Preference.created_at:type_name -> google.protobuf.Timestamp + 51, // 48: raystack.frontier.v1beta1.Preference.updated_at:type_name -> google.protobuf.Timestamp + 43, // 49: raystack.frontier.v1beta1.BillingAccount.address:type_name -> raystack.frontier.v1beta1.BillingAccount.Address + 44, // 50: raystack.frontier.v1beta1.BillingAccount.tax_data:type_name -> raystack.frontier.v1beta1.BillingAccount.Tax + 50, // 51: raystack.frontier.v1beta1.BillingAccount.metadata:type_name -> google.protobuf.Struct + 51, // 52: raystack.frontier.v1beta1.BillingAccount.created_at:type_name -> google.protobuf.Timestamp + 51, // 53: raystack.frontier.v1beta1.BillingAccount.updated_at:type_name -> google.protobuf.Timestamp 4, // 54: raystack.frontier.v1beta1.BillingAccount.organization:type_name -> raystack.frontier.v1beta1.Organization - 46, // 55: raystack.frontier.v1beta1.Subscription.metadata:type_name -> google.protobuf.Struct - 47, // 56: raystack.frontier.v1beta1.Subscription.created_at:type_name -> google.protobuf.Timestamp - 47, // 57: raystack.frontier.v1beta1.Subscription.updated_at:type_name -> google.protobuf.Timestamp - 47, // 58: raystack.frontier.v1beta1.Subscription.canceled_at:type_name -> google.protobuf.Timestamp - 47, // 59: raystack.frontier.v1beta1.Subscription.ended_at:type_name -> google.protobuf.Timestamp - 47, // 60: raystack.frontier.v1beta1.Subscription.trial_ends_at:type_name -> google.protobuf.Timestamp - 47, // 61: raystack.frontier.v1beta1.Subscription.current_period_start_at:type_name -> google.protobuf.Timestamp - 47, // 62: raystack.frontier.v1beta1.Subscription.current_period_end_at:type_name -> google.protobuf.Timestamp - 47, // 63: raystack.frontier.v1beta1.Subscription.billing_cycle_anchor_at:type_name -> google.protobuf.Timestamp - 44, // 64: raystack.frontier.v1beta1.Subscription.phases:type_name -> raystack.frontier.v1beta1.Subscription.Phase + 50, // 55: raystack.frontier.v1beta1.Subscription.metadata:type_name -> google.protobuf.Struct + 51, // 56: raystack.frontier.v1beta1.Subscription.created_at:type_name -> google.protobuf.Timestamp + 51, // 57: raystack.frontier.v1beta1.Subscription.updated_at:type_name -> google.protobuf.Timestamp + 51, // 58: raystack.frontier.v1beta1.Subscription.canceled_at:type_name -> google.protobuf.Timestamp + 51, // 59: raystack.frontier.v1beta1.Subscription.ended_at:type_name -> google.protobuf.Timestamp + 51, // 60: raystack.frontier.v1beta1.Subscription.trial_ends_at:type_name -> google.protobuf.Timestamp + 51, // 61: raystack.frontier.v1beta1.Subscription.current_period_start_at:type_name -> google.protobuf.Timestamp + 51, // 62: raystack.frontier.v1beta1.Subscription.current_period_end_at:type_name -> google.protobuf.Timestamp + 51, // 63: raystack.frontier.v1beta1.Subscription.billing_cycle_anchor_at:type_name -> google.protobuf.Timestamp + 46, // 64: raystack.frontier.v1beta1.Subscription.phases:type_name -> raystack.frontier.v1beta1.Subscription.Phase 24, // 65: raystack.frontier.v1beta1.Subscription.customer:type_name -> raystack.frontier.v1beta1.BillingAccount 27, // 66: raystack.frontier.v1beta1.Subscription.plan:type_name -> raystack.frontier.v1beta1.Plan - 46, // 67: raystack.frontier.v1beta1.CheckoutSession.metadata:type_name -> google.protobuf.Struct - 47, // 68: raystack.frontier.v1beta1.CheckoutSession.created_at:type_name -> google.protobuf.Timestamp - 47, // 69: raystack.frontier.v1beta1.CheckoutSession.updated_at:type_name -> google.protobuf.Timestamp - 47, // 70: raystack.frontier.v1beta1.CheckoutSession.expire_at:type_name -> google.protobuf.Timestamp + 50, // 67: raystack.frontier.v1beta1.CheckoutSession.metadata:type_name -> google.protobuf.Struct + 51, // 68: raystack.frontier.v1beta1.CheckoutSession.created_at:type_name -> google.protobuf.Timestamp + 51, // 69: raystack.frontier.v1beta1.CheckoutSession.updated_at:type_name -> google.protobuf.Timestamp + 51, // 70: raystack.frontier.v1beta1.CheckoutSession.expire_at:type_name -> google.protobuf.Timestamp 28, // 71: raystack.frontier.v1beta1.Plan.products:type_name -> raystack.frontier.v1beta1.Product - 46, // 72: raystack.frontier.v1beta1.Plan.metadata:type_name -> google.protobuf.Struct - 47, // 73: raystack.frontier.v1beta1.Plan.created_at:type_name -> google.protobuf.Timestamp - 47, // 74: raystack.frontier.v1beta1.Plan.updated_at:type_name -> google.protobuf.Timestamp + 50, // 72: raystack.frontier.v1beta1.Plan.metadata:type_name -> google.protobuf.Struct + 51, // 73: raystack.frontier.v1beta1.Plan.created_at:type_name -> google.protobuf.Timestamp + 51, // 74: raystack.frontier.v1beta1.Plan.updated_at:type_name -> google.protobuf.Timestamp 30, // 75: raystack.frontier.v1beta1.Product.prices:type_name -> raystack.frontier.v1beta1.Price 29, // 76: raystack.frontier.v1beta1.Product.features:type_name -> raystack.frontier.v1beta1.Feature - 45, // 77: raystack.frontier.v1beta1.Product.behavior_config:type_name -> raystack.frontier.v1beta1.Product.BehaviorConfig - 46, // 78: raystack.frontier.v1beta1.Product.metadata:type_name -> google.protobuf.Struct - 47, // 79: raystack.frontier.v1beta1.Product.created_at:type_name -> google.protobuf.Timestamp - 47, // 80: raystack.frontier.v1beta1.Product.updated_at:type_name -> google.protobuf.Timestamp - 46, // 81: raystack.frontier.v1beta1.Feature.metadata:type_name -> google.protobuf.Struct - 47, // 82: raystack.frontier.v1beta1.Feature.created_at:type_name -> google.protobuf.Timestamp - 47, // 83: raystack.frontier.v1beta1.Feature.updated_at:type_name -> google.protobuf.Timestamp - 46, // 84: raystack.frontier.v1beta1.Price.metadata:type_name -> google.protobuf.Struct - 47, // 85: raystack.frontier.v1beta1.Price.created_at:type_name -> google.protobuf.Timestamp - 47, // 86: raystack.frontier.v1beta1.Price.updated_at:type_name -> google.protobuf.Timestamp - 46, // 87: raystack.frontier.v1beta1.BillingTransaction.metadata:type_name -> google.protobuf.Struct - 47, // 88: raystack.frontier.v1beta1.BillingTransaction.created_at:type_name -> google.protobuf.Timestamp - 47, // 89: raystack.frontier.v1beta1.BillingTransaction.updated_at:type_name -> google.protobuf.Timestamp + 47, // 77: raystack.frontier.v1beta1.Product.behavior_config:type_name -> raystack.frontier.v1beta1.Product.BehaviorConfig + 50, // 78: raystack.frontier.v1beta1.Product.metadata:type_name -> google.protobuf.Struct + 51, // 79: raystack.frontier.v1beta1.Product.created_at:type_name -> google.protobuf.Timestamp + 51, // 80: raystack.frontier.v1beta1.Product.updated_at:type_name -> google.protobuf.Timestamp + 50, // 81: raystack.frontier.v1beta1.Feature.metadata:type_name -> google.protobuf.Struct + 51, // 82: raystack.frontier.v1beta1.Feature.created_at:type_name -> google.protobuf.Timestamp + 51, // 83: raystack.frontier.v1beta1.Feature.updated_at:type_name -> google.protobuf.Timestamp + 50, // 84: raystack.frontier.v1beta1.Price.metadata:type_name -> google.protobuf.Struct + 51, // 85: raystack.frontier.v1beta1.Price.created_at:type_name -> google.protobuf.Timestamp + 51, // 86: raystack.frontier.v1beta1.Price.updated_at:type_name -> google.protobuf.Timestamp + 50, // 87: raystack.frontier.v1beta1.BillingTransaction.metadata:type_name -> google.protobuf.Struct + 51, // 88: raystack.frontier.v1beta1.BillingTransaction.created_at:type_name -> google.protobuf.Timestamp + 51, // 89: raystack.frontier.v1beta1.BillingTransaction.updated_at:type_name -> google.protobuf.Timestamp 0, // 90: raystack.frontier.v1beta1.BillingTransaction.user:type_name -> raystack.frontier.v1beta1.User 24, // 91: raystack.frontier.v1beta1.BillingTransaction.customer:type_name -> raystack.frontier.v1beta1.BillingAccount - 46, // 92: raystack.frontier.v1beta1.Usage.metadata:type_name -> google.protobuf.Struct - 47, // 93: raystack.frontier.v1beta1.Usage.created_at:type_name -> google.protobuf.Timestamp - 47, // 94: raystack.frontier.v1beta1.Usage.updated_at:type_name -> google.protobuf.Timestamp - 47, // 95: raystack.frontier.v1beta1.Invoice.due_date:type_name -> google.protobuf.Timestamp - 47, // 96: raystack.frontier.v1beta1.Invoice.effective_at:type_name -> google.protobuf.Timestamp - 47, // 97: raystack.frontier.v1beta1.Invoice.period_start_at:type_name -> google.protobuf.Timestamp - 47, // 98: raystack.frontier.v1beta1.Invoice.period_end_at:type_name -> google.protobuf.Timestamp - 46, // 99: raystack.frontier.v1beta1.Invoice.metadata:type_name -> google.protobuf.Struct - 47, // 100: raystack.frontier.v1beta1.Invoice.created_at:type_name -> google.protobuf.Timestamp + 50, // 92: raystack.frontier.v1beta1.Usage.metadata:type_name -> google.protobuf.Struct + 51, // 93: raystack.frontier.v1beta1.Usage.created_at:type_name -> google.protobuf.Timestamp + 51, // 94: raystack.frontier.v1beta1.Usage.updated_at:type_name -> google.protobuf.Timestamp + 51, // 95: raystack.frontier.v1beta1.Invoice.due_date:type_name -> google.protobuf.Timestamp + 51, // 96: raystack.frontier.v1beta1.Invoice.effective_at:type_name -> google.protobuf.Timestamp + 51, // 97: raystack.frontier.v1beta1.Invoice.period_start_at:type_name -> google.protobuf.Timestamp + 51, // 98: raystack.frontier.v1beta1.Invoice.period_end_at:type_name -> google.protobuf.Timestamp + 50, // 99: raystack.frontier.v1beta1.Invoice.metadata:type_name -> google.protobuf.Struct + 51, // 100: raystack.frontier.v1beta1.Invoice.created_at:type_name -> google.protobuf.Timestamp 24, // 101: raystack.frontier.v1beta1.Invoice.customer:type_name -> raystack.frontier.v1beta1.BillingAccount - 46, // 102: raystack.frontier.v1beta1.PaymentMethod.metadata:type_name -> google.protobuf.Struct - 47, // 103: raystack.frontier.v1beta1.PaymentMethod.created_at:type_name -> google.protobuf.Timestamp - 46, // 104: raystack.frontier.v1beta1.RoleRequestBody.metadata:type_name -> google.protobuf.Struct - 47, // 105: raystack.frontier.v1beta1.BillingAccount.Balance.updated_at:type_name -> google.protobuf.Timestamp - 47, // 106: raystack.frontier.v1beta1.Subscription.Phase.effective_at:type_name -> google.protobuf.Timestamp - 107, // [107:107] is the sub-list for method output_type - 107, // [107:107] is the sub-list for method input_type - 107, // [107:107] is the sub-list for extension type_name - 107, // [107:107] is the sub-list for extension extendee - 0, // [0:107] is the sub-list for field type_name + 50, // 102: raystack.frontier.v1beta1.PaymentMethod.metadata:type_name -> google.protobuf.Struct + 51, // 103: raystack.frontier.v1beta1.PaymentMethod.created_at:type_name -> google.protobuf.Timestamp + 49, // 104: raystack.frontier.v1beta1.Webhook.headers:type_name -> raystack.frontier.v1beta1.Webhook.HeadersEntry + 48, // 105: raystack.frontier.v1beta1.Webhook.secrets:type_name -> raystack.frontier.v1beta1.Webhook.Secret + 50, // 106: raystack.frontier.v1beta1.Webhook.metadata:type_name -> google.protobuf.Struct + 51, // 107: raystack.frontier.v1beta1.Webhook.created_at:type_name -> google.protobuf.Timestamp + 51, // 108: raystack.frontier.v1beta1.Webhook.updated_at:type_name -> google.protobuf.Timestamp + 50, // 109: raystack.frontier.v1beta1.WebhookEvent.data:type_name -> google.protobuf.Struct + 50, // 110: raystack.frontier.v1beta1.WebhookEvent.metadata:type_name -> google.protobuf.Struct + 51, // 111: raystack.frontier.v1beta1.WebhookEvent.created_at:type_name -> google.protobuf.Timestamp + 50, // 112: raystack.frontier.v1beta1.RoleRequestBody.metadata:type_name -> google.protobuf.Struct + 51, // 113: raystack.frontier.v1beta1.BillingAccount.Balance.updated_at:type_name -> google.protobuf.Timestamp + 51, // 114: raystack.frontier.v1beta1.Subscription.Phase.effective_at:type_name -> google.protobuf.Timestamp + 115, // [115:115] is the sub-list for method output_type + 115, // [115:115] is the sub-list for method input_type + 115, // [115:115] is the sub-list for extension type_name + 115, // [115:115] is the sub-list for extension extendee + 0, // [0:115] is the sub-list for field type_name } func init() { file_raystack_frontier_v1beta1_models_proto_init() } @@ -6384,7 +6705,7 @@ func file_raystack_frontier_v1beta1_models_proto_init() { } } file_raystack_frontier_v1beta1_models_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoleRequestBody); i { + switch v := v.(*Webhook); i { case 0: return &v.state case 1: @@ -6396,7 +6717,7 @@ func file_raystack_frontier_v1beta1_models_proto_init() { } } file_raystack_frontier_v1beta1_models_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PreferenceRequestBody); i { + switch v := v.(*WebhookEvent); i { case 0: return &v.state case 1: @@ -6408,7 +6729,7 @@ func file_raystack_frontier_v1beta1_models_proto_init() { } } file_raystack_frontier_v1beta1_models_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckoutSubscriptionBody); i { + switch v := v.(*RoleRequestBody); i { case 0: return &v.state case 1: @@ -6420,7 +6741,7 @@ func file_raystack_frontier_v1beta1_models_proto_init() { } } file_raystack_frontier_v1beta1_models_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckoutProductBody); i { + switch v := v.(*PreferenceRequestBody); i { case 0: return &v.state case 1: @@ -6432,7 +6753,19 @@ func file_raystack_frontier_v1beta1_models_proto_init() { } } file_raystack_frontier_v1beta1_models_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckoutSetupBody); i { + switch v := v.(*CheckoutSubscriptionBody); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_models_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CheckoutProductBody); i { case 0: return &v.state case 1: @@ -6444,6 +6777,18 @@ func file_raystack_frontier_v1beta1_models_proto_init() { } } file_raystack_frontier_v1beta1_models_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CheckoutSetupBody); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_raystack_frontier_v1beta1_models_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BillingAccount_Address); i { case 0: return &v.state @@ -6455,7 +6800,7 @@ func file_raystack_frontier_v1beta1_models_proto_init() { return nil } } - file_raystack_frontier_v1beta1_models_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + file_raystack_frontier_v1beta1_models_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BillingAccount_Tax); i { case 0: return &v.state @@ -6467,7 +6812,7 @@ func file_raystack_frontier_v1beta1_models_proto_init() { return nil } } - file_raystack_frontier_v1beta1_models_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + file_raystack_frontier_v1beta1_models_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BillingAccount_Balance); i { case 0: return &v.state @@ -6479,7 +6824,7 @@ func file_raystack_frontier_v1beta1_models_proto_init() { return nil } } - file_raystack_frontier_v1beta1_models_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + file_raystack_frontier_v1beta1_models_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Subscription_Phase); i { case 0: return &v.state @@ -6491,7 +6836,7 @@ func file_raystack_frontier_v1beta1_models_proto_init() { return nil } } - file_raystack_frontier_v1beta1_models_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + file_raystack_frontier_v1beta1_models_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Product_BehaviorConfig); i { case 0: return &v.state @@ -6503,6 +6848,18 @@ func file_raystack_frontier_v1beta1_models_proto_init() { return nil } } + file_raystack_frontier_v1beta1_models_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Webhook_Secret); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_raystack_frontier_v1beta1_models_proto_msgTypes[22].OneofWrappers = []interface{}{ (*PreferenceTrait_Text)(nil), @@ -6519,7 +6876,7 @@ func file_raystack_frontier_v1beta1_models_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_raystack_frontier_v1beta1_models_proto_rawDesc, NumEnums: 0, - NumMessages: 46, + NumMessages: 50, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/v1beta1/models.pb.validate.go b/proto/v1beta1/models.pb.validate.go index f539ecd6d..ab01e4053 100644 --- a/proto/v1beta1/models.pb.validate.go +++ b/proto/v1beta1/models.pb.validate.go @@ -7518,6 +7518,425 @@ var _ interface { ErrorName() string } = PaymentMethodValidationError{} +// Validate checks the field values on Webhook with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Webhook) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Webhook with the rules defined in the +// proto definition for this message. If any rules are violated, the result is +// a list of violation errors wrapped in WebhookMultiError, or nil if none found. +func (m *Webhook) ValidateAll() error { + return m.validate(true) +} + +func (m *Webhook) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Id + + // no validation rules for Description + + // no validation rules for Url + + // no validation rules for Headers + + for idx, item := range m.GetSecrets() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, WebhookValidationError{ + field: fmt.Sprintf("Secrets[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, WebhookValidationError{ + field: fmt.Sprintf("Secrets[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return WebhookValidationError{ + field: fmt.Sprintf("Secrets[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + // no validation rules for State + + if all { + switch v := interface{}(m.GetMetadata()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, WebhookValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, WebhookValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetMetadata()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return WebhookValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetCreatedAt()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, WebhookValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, WebhookValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetCreatedAt()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return WebhookValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetUpdatedAt()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, WebhookValidationError{ + field: "UpdatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, WebhookValidationError{ + field: "UpdatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetUpdatedAt()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return WebhookValidationError{ + field: "UpdatedAt", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return WebhookMultiError(errors) + } + + return nil +} + +// WebhookMultiError is an error wrapping multiple validation errors returned +// by Webhook.ValidateAll() if the designated constraints aren't met. +type WebhookMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m WebhookMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m WebhookMultiError) AllErrors() []error { return m } + +// WebhookValidationError is the validation error returned by Webhook.Validate +// if the designated constraints aren't met. +type WebhookValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e WebhookValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e WebhookValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e WebhookValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e WebhookValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e WebhookValidationError) ErrorName() string { return "WebhookValidationError" } + +// Error satisfies the builtin error interface +func (e WebhookValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sWebhook.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = WebhookValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = WebhookValidationError{} + +// Validate checks the field values on WebhookEvent with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *WebhookEvent) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on WebhookEvent with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in WebhookEventMultiError, or +// nil if none found. +func (m *WebhookEvent) ValidateAll() error { + return m.validate(true) +} + +func (m *WebhookEvent) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Id + + // no validation rules for Action + + if all { + switch v := interface{}(m.GetData()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, WebhookEventValidationError{ + field: "Data", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, WebhookEventValidationError{ + field: "Data", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetData()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return WebhookEventValidationError{ + field: "Data", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetMetadata()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, WebhookEventValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, WebhookEventValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetMetadata()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return WebhookEventValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetCreatedAt()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, WebhookEventValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, WebhookEventValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetCreatedAt()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return WebhookEventValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return WebhookEventMultiError(errors) + } + + return nil +} + +// WebhookEventMultiError is an error wrapping multiple validation errors +// returned by WebhookEvent.ValidateAll() if the designated constraints aren't met. +type WebhookEventMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m WebhookEventMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m WebhookEventMultiError) AllErrors() []error { return m } + +// WebhookEventValidationError is the validation error returned by +// WebhookEvent.Validate if the designated constraints aren't met. +type WebhookEventValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e WebhookEventValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e WebhookEventValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e WebhookEventValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e WebhookEventValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e WebhookEventValidationError) ErrorName() string { return "WebhookEventValidationError" } + +// Error satisfies the builtin error interface +func (e WebhookEventValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sWebhookEvent.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = WebhookEventValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = WebhookEventValidationError{} + // Validate checks the field values on RoleRequestBody with the rules defined // in the proto definition for this message. If any rules are violated, the // first error encountered is returned, or nil if there are no violations. @@ -8758,3 +9177,107 @@ var _ interface { Cause() error ErrorName() string } = Product_BehaviorConfigValidationError{} + +// Validate checks the field values on Webhook_Secret with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Webhook_Secret) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Webhook_Secret with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in Webhook_SecretMultiError, +// or nil if none found. +func (m *Webhook_Secret) ValidateAll() error { + return m.validate(true) +} + +func (m *Webhook_Secret) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Id + + // no validation rules for Value + + if len(errors) > 0 { + return Webhook_SecretMultiError(errors) + } + + return nil +} + +// Webhook_SecretMultiError is an error wrapping multiple validation errors +// returned by Webhook_Secret.ValidateAll() if the designated constraints +// aren't met. +type Webhook_SecretMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m Webhook_SecretMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m Webhook_SecretMultiError) AllErrors() []error { return m } + +// Webhook_SecretValidationError is the validation error returned by +// Webhook_Secret.Validate if the designated constraints aren't met. +type Webhook_SecretValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e Webhook_SecretValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e Webhook_SecretValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e Webhook_SecretValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e Webhook_SecretValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e Webhook_SecretValidationError) ErrorName() string { return "Webhook_SecretValidationError" } + +// Error satisfies the builtin error interface +func (e Webhook_SecretValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sWebhook_Secret.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = Webhook_SecretValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = Webhook_SecretValidationError{} diff --git a/test/e2e/regression/api_test.go b/test/e2e/regression/api_test.go index fbe179f2b..680a15681 100644 --- a/test/e2e/regression/api_test.go +++ b/test/e2e/regression/api_test.go @@ -2,9 +2,17 @@ package e2e_test import ( "context" + "encoding/json" + "io" + "net/http" + "net/http/httptest" "os" "path" + "strings" "testing" + "time" + + "github.com/raystack/frontier/pkg/webhook" "github.com/raystack/frontier/core/organization" @@ -1932,6 +1940,95 @@ func (s *APIRegressionTestSuite) TestOrganizationDomainsAPI() { }) } +func (s *APIRegressionTestSuite) TestWebhookAPI() { + ctxOrgAdminAuth := metadata.NewOutgoingContext(context.Background(), metadata.New(map[string]string{ + testbench.IdentityHeader: testbench.OrgAdminEmail, + })) + s.Run("1. create and list webhooks successfully", func() { + createWebhookResp, err := s.testBench.AdminClient.CreateWebhook(ctxOrgAdminAuth, &frontierv1beta1.CreateWebhookRequest{ + Body: &frontierv1beta1.WebhookRequestBody{ + Description: "webhook 1", + Url: "https://webhook-1.raystack.io", + SubscribedEvents: []string{}, + Headers: map[string]string{ + "Authorization": "Bearer token", + }, + }, + }) + s.Assert().NoError(err) + s.Assert().NotNil(createWebhookResp) + s.Assert().NotNil(createWebhookResp.GetWebhook().GetSecrets()) + + listWebhookResp, err := s.testBench.AdminClient.ListWebhooks(ctxOrgAdminAuth, &frontierv1beta1.ListWebhooksRequest{}) + s.Assert().NoError(err) + s.Assert().NotNil(listWebhookResp) + s.Assert().Equal("webhook 1", listWebhookResp.GetWebhooks()[0].GetDescription()) + s.Assert().Equal("https://webhook-1.raystack.io", listWebhookResp.GetWebhooks()[0].GetUrl()) + s.Assert().Nil(listWebhookResp.GetWebhooks()[0].GetSecrets()) + }) + s.Run("2. registering a webhook should start receiving events", func() { + var rawBody []byte + var body frontierv1beta1.WebhookEvent + var authHeader string + var signatureHeader string + + // create a test http server and use the generated endpoint to pass as webhook url + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodPost { + var err error + rawBody, err = io.ReadAll(r.Body) + s.Assert().NoError(err) + + authHeader = r.Header.Get("Authorization") + signatureHeader = r.Header.Get("X-Signature") + + w.WriteHeader(http.StatusOK) + return + } + w.WriteHeader(http.StatusMethodNotAllowed) + })) + defer server.Close() + + createWebhookResp, err := s.testBench.AdminClient.CreateWebhook(ctxOrgAdminAuth, &frontierv1beta1.CreateWebhookRequest{ + Body: &frontierv1beta1.WebhookRequestBody{ + Description: "webhook 2", + Url: server.URL, + SubscribedEvents: []string{"app.organization.created"}, + Headers: map[string]string{ + "Authorization": "Bearer test", + }, + }, + }) + s.Assert().NoError(err) + s.Assert().NotNil(createWebhookResp) + + // create a new org + createOrgResp, err := s.testBench.Client.CreateOrganization(ctxOrgAdminAuth, &frontierv1beta1.CreateOrganizationRequest{ + Body: &frontierv1beta1.OrganizationRequestBody{ + Title: "org webhook 1", + Name: "org-webhook-1", + }, + }) + s.Assert().NoError(err) + s.Assert().NotNil(createOrgResp) + + // wait for webhook to receive the event + time.Sleep(2 * time.Second) + + err = json.Unmarshal(rawBody, &body) + s.Assert().NoError(err) + s.Assert().Equal("app.organization.created", body.GetAction()) + s.Assert().Equal("Bearer test", authHeader) + + signatureHash := strings.Split(signatureHeader, "=") + s.Assert().Len(signatureHash, 2) + + parsedEvent, err := webhook.ParseAndValidateEvent(rawBody, createWebhookResp.GetWebhook().GetSecrets()[0].GetValue(), signatureHash[1]) + s.Assert().NoError(err) + s.Assert().NotNil(parsedEvent) + }) +} + func TestEndToEndAPIRegressionTestSuite(t *testing.T) { suite.Run(t, new(APIRegressionTestSuite)) } diff --git a/test/e2e/testbench/testbench.go b/test/e2e/testbench/testbench.go index 221096f95..13308f020 100644 --- a/test/e2e/testbench/testbench.go +++ b/test/e2e/testbench/testbench.go @@ -96,6 +96,7 @@ func Init(appConfig *config.Frontier) (*TestBench, error) { FullyConsistent: true, } appConfig.App.Admin.Users = []string{OrgAdminEmail} + appConfig.App.Webhook.EncryptionKey = "kmm4ECoWU21K2ZoyTcYLd6w7DfhoUoap" if err = MigrateFrontier(logger, appConfig); err != nil { return nil, err