From 1e609fd76674976d364db0e83c1f9ea4376a4a7b Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sat, 30 May 2026 16:06:54 +0530 Subject: [PATCH 1/2] feat(api): multi-protocol public API surface (GraphQL + gRPC + REST + MCP) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds gRPC + grpc-gateway REST + MCP surfaces for the public GraphQL ops (no `_` prefix), driven from a single proto source of truth. GraphQL stays unchanged; admin ops stay GraphQL-only. Consolidates the previously-stacked PRs #614 → #615 → #616 → #617 → #618 → #619 into a single change against main. PROTO (proto/) - buf v2 module rooted at buf.build/authorizerdev/authorizer - Single AuthorizerService with 19 RPCs whose names match GraphQL ops 1:1: Signup, Login, Logout, MagicLinkLogin, VerifyEmail, ResendVerifyEmail, VerifyOtp, ResendOtp, ForgotPassword, ResetPassword, Profile, UpdateProfile, DeactivateAccount, Revoke, Session, ValidateJwtToken, ValidateSession, Meta, Permissions - common/v1: annotations (required_permissions, mcp_tool, audit_log, public), pagination, errors, shared AppData - Each RPC's response wrapped in a per-RPC message so buf STANDARD's RPC_REQUEST_RESPONSE_UNIQUE lint passes; shared inner types (AuthResponse, User, Meta) live in proto/authorizer/v1/types.proto - google.api.http annotations drive REST: GET /v1/{method} for trivially- empty queries (meta, profile, permissions, logout), POST /v1/{method} otherwise. Snake_case method paths mirror GraphQL identifiers. - buf STANDARD lint + format both enforced in CI; bufbuild/buf-action@v1 runs lint always, breaking-check on PRs, format -d --exit-code always TRANSPORT-AGNOSTIC SERVICE LAYER (internal/service/) - sideeffects.go: RequestMetadata + ResponseSideEffects + MetaFromGin / ApplyToGin / MetaFromGRPC / ApplyToGRPC bridges - provider.go: service.Provider interface - signup.go, meta.go: migrated from internal/graphql; resolvers become thin transport adapters - Supporting helpers: parsers.GetHostFromRequest/GetAppURLFromRequest, cookie.BuildSessionCookies/BuildMfaSessionCookies (existing gin wrappers now delegate to these so behaviour is byte-identical) gRPC SERVER (internal/grpcsrv/) - server.go: AuthorizerService registered, gRPC reflection (gated on --enable-grpc-reflection), gRPC health checking, graceful shutdown - interceptors: recovery (panic → codes.Internal), logging (per-code level), validate (protovalidate) - handlers/authorizer.go: Meta delegates to service.Meta; the other 18 methods inherit UnimplementedAuthorizerServiceServer and return codes.Unimplemented until their handler migrates from internal/graphql - transport/grpc_metadata.go: gRPC metadata ↔ RequestMetadata bridge (extracts cookies from grpcgateway-cookie, preserves multi-cookie Set-Cookie responses) REST GATEWAY (internal/gateway/) - mount.go: serves grpc-gateway via in-process bufconn dial — no extra TCP hop, no TLS plumbing - JSONPb marshaler: UseProtoNames=true so REST payloads match GraphQL's snake_case shape - Mounted at /v1/* under the existing gin router (shares CORS, security headers, rate limit, logger middleware automatically) - /openapi.json serves the merged swagger spec (embedded via go:embed from gen/openapi/openapi.go so it works regardless of cwd) MCP SERVER (internal/mcp/) - scanner.go: walks grpc.Server.GetServiceInfo() + protoregistry.GlobalFiles, reads the mcp_tool annotation on each method to build a tool registry - schema.go: derives JSON Schema from proto request descriptors, with cycle guard for self-recursive types (google.protobuf.Value) - server.go: registers tools dynamically on a github.com/modelcontextprotocol/ go-sdk Server; tool handlers unmarshal JSON args into a dynamicpb.Message, invoke the gRPC method via an in-process bufconn, marshal the response back to JSON. gRPC errors surface as CallToolResult{IsError:true} so the LLM gets actionable text - Today's MCP-exposed tools (from proto annotations): meta, profile, session, permissions. Credential-bearing methods stay unexposed - `authorizer mcp` subcommand (cmd/mcp.go) serves over stdio for `claude mcp add authorizer -- /path/to/authorizer mcp ...` CLI (cmd/root.go, cmd/mcp.go, internal/config/config.go) - --grpc-port (default 9091; collision-checked against --http-port and --metrics-port at startup), --enable-grpc-reflection (default true), --grpc-tls-cert / -key / -insecure (TLS plumbing placeholders; TLS implementation is a follow-up PR) - server.Run starts HTTP + metrics + gRPC + REST gateway listeners with shared graceful shutdown TESTS - internal/parsers/url_test.go GetHostFromRequest priority + spoof rejection - internal/cookie/cookie_test.go BuildSessionCookies/BuildMfaSessionCookies shape - internal/service/sideeffects_test.go MetaFromGin/ApplyToGin nil-safety + roundtrip - internal/grpcsrv/interceptors/ recovery / logging / validate - internal/grpcsrv/transport/ gRPC metadata bridge (cookies, fallbacks) - internal/mcp/schema_test.go flat scalars, nested message, cycle-safety regression - internal/integration_tests/grpc_meta_test.go AuthorizerService.Meta - internal/integration_tests/grpc_surface_test.go all 18 stubs return Unimplemented + gRPC health - internal/integration_tests/rest_meta_test.go GET /v1/meta through gateway - internal/integration_tests/rest_openapi_test.go /openapi.json serves embedded spec - internal/integration_tests/mcp_test.go tools/list + tools/call meta - internal/integration_tests/mcp_stubs_test.go stub returns CallToolResult{IsError:true} - Existing GraphQL integration suite still passes (65–70s, no behaviour drift) What's NOT in this PR (deferred) - --grpc-tls-cert / -key / -insecure are wired into config but not yet enforced; TLS implementation lands in a follow-up alongside metrics- listener TLS - 18 of the 19 gRPC methods (and their REST mirrors + MCP tools) are Unimplemented stubs; each becomes real as its op migrates from internal/graphql into internal/service in follow-up PRs. The annotation-driven MCP scanner + gateway routing means follow-ups don't need to touch the gRPC/REST/MCP scaffolding — only add the service-layer method and the handler delegation Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 22 + Makefile | 27 + cmd/mcp.go | 95 + cmd/root.go | 63 +- gen/go/authorizer/common/v1/annotations.pb.go | 332 ++ gen/go/authorizer/common/v1/errors.pb.go | 217 ++ gen/go/authorizer/common/v1/pagination.pb.go | 265 ++ gen/go/authorizer/common/v1/types.pb.go | 157 + gen/go/authorizer/v1/authorizer.pb.go | 2826 +++++++++++++++++ gen/go/authorizer/v1/authorizer.pb.gw.go | 1518 +++++++++ gen/go/authorizer/v1/authorizer_grpc.pb.go | 850 +++++ gen/go/authorizer/v1/types.pb.go | 913 ++++++ gen/openapi/authorizer.swagger.json | 1370 ++++++++ gen/openapi/openapi.go | 13 + go.mod | 36 +- go.sum | 51 + internal/config/config.go | 14 + internal/cookie/cookie.go | 42 +- internal/cookie/cookie_test.go | 91 + internal/cookie/mfa_session.go | 56 +- internal/gateway/mount.go | 84 + internal/graphql/meta.go | 70 +- internal/graphql/provider.go | 4 + internal/graphql/signup.go | 387 +-- internal/grpcsrv/handlers/authorizer.go | 62 + .../grpcsrv/interceptors/interceptors_test.go | 139 + internal/grpcsrv/interceptors/logging.go | 40 + internal/grpcsrv/interceptors/recovery.go | 38 + internal/grpcsrv/interceptors/validate.go | 32 + internal/grpcsrv/server.go | 107 + internal/grpcsrv/transport/grpc_metadata.go | 101 + .../grpcsrv/transport/grpc_metadata_test.go | 77 + internal/http_handlers/graphql.go | 1 + internal/http_handlers/provider.go | 4 + internal/integration_tests/grpc_meta_test.go | 58 + .../integration_tests/grpc_surface_test.go | 159 + internal/integration_tests/mcp_stubs_test.go | 64 + internal/integration_tests/mcp_test.go | 85 + internal/integration_tests/rest_meta_test.go | 71 + .../integration_tests/rest_openapi_test.go | 46 + internal/integration_tests/test_helper.go | 16 + internal/mcp/scanner.go | 113 + internal/mcp/schema.go | 87 + internal/mcp/schema_test.go | 72 + internal/mcp/server.go | 167 + internal/parsers/url.go | 31 +- internal/parsers/url_test.go | 69 + internal/server/http_routes.go | 24 + internal/server/server.go | 53 +- internal/service/meta.go | 35 + internal/service/provider.go | 66 + internal/service/sideeffects.go | 106 + internal/service/sideeffects_test.go | 104 + internal/service/signup.go | 411 +++ proto/authorizer/common/v1/annotations.proto | 53 + proto/authorizer/common/v1/errors.proto | 52 + proto/authorizer/common/v1/pagination.proto | 36 + proto/authorizer/common/v1/types.proto | 18 + proto/authorizer/v1/authorizer.proto | 429 +++ proto/authorizer/v1/types.proto | 93 + proto/buf.gen.yaml | 33 + proto/buf.lock | 9 + proto/buf.yaml | 16 + 63 files changed, 12187 insertions(+), 493 deletions(-) create mode 100644 cmd/mcp.go create mode 100644 gen/go/authorizer/common/v1/annotations.pb.go create mode 100644 gen/go/authorizer/common/v1/errors.pb.go create mode 100644 gen/go/authorizer/common/v1/pagination.pb.go create mode 100644 gen/go/authorizer/common/v1/types.pb.go create mode 100644 gen/go/authorizer/v1/authorizer.pb.go create mode 100644 gen/go/authorizer/v1/authorizer.pb.gw.go create mode 100644 gen/go/authorizer/v1/authorizer_grpc.pb.go create mode 100644 gen/go/authorizer/v1/types.pb.go create mode 100644 gen/openapi/authorizer.swagger.json create mode 100644 gen/openapi/openapi.go create mode 100644 internal/cookie/cookie_test.go create mode 100644 internal/gateway/mount.go create mode 100644 internal/grpcsrv/handlers/authorizer.go create mode 100644 internal/grpcsrv/interceptors/interceptors_test.go create mode 100644 internal/grpcsrv/interceptors/logging.go create mode 100644 internal/grpcsrv/interceptors/recovery.go create mode 100644 internal/grpcsrv/interceptors/validate.go create mode 100644 internal/grpcsrv/server.go create mode 100644 internal/grpcsrv/transport/grpc_metadata.go create mode 100644 internal/grpcsrv/transport/grpc_metadata_test.go create mode 100644 internal/integration_tests/grpc_meta_test.go create mode 100644 internal/integration_tests/grpc_surface_test.go create mode 100644 internal/integration_tests/mcp_stubs_test.go create mode 100644 internal/integration_tests/mcp_test.go create mode 100644 internal/integration_tests/rest_meta_test.go create mode 100644 internal/integration_tests/rest_openapi_test.go create mode 100644 internal/mcp/scanner.go create mode 100644 internal/mcp/schema.go create mode 100644 internal/mcp/schema_test.go create mode 100644 internal/mcp/server.go create mode 100644 internal/service/meta.go create mode 100644 internal/service/provider.go create mode 100644 internal/service/sideeffects.go create mode 100644 internal/service/sideeffects_test.go create mode 100644 internal/service/signup.go create mode 100644 proto/authorizer/common/v1/annotations.proto create mode 100644 proto/authorizer/common/v1/errors.proto create mode 100644 proto/authorizer/common/v1/pagination.proto create mode 100644 proto/authorizer/common/v1/types.proto create mode 100644 proto/authorizer/v1/authorizer.proto create mode 100644 proto/authorizer/v1/types.proto create mode 100644 proto/buf.gen.yaml create mode 100644 proto/buf.lock create mode 100644 proto/buf.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42832e70..82be1a69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,3 +27,25 @@ jobs: - name: Run tests run: make test + + proto: + name: Proto lint + breaking + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + # buf breaking needs main's history to diff against. + fetch-depth: 0 + + - uses: bufbuild/buf-action@v1 + with: + input: proto + lint: true + # `format: true` makes the action run `buf format -d --exit-code`, + # failing the job on any unformatted .proto. Catches drift before + # generated code can diverge. + format: true + # Only run breaking on PRs (push to main has nothing to diff against). + breaking: ${{ github.event_name == 'pull_request' }} + breaking_against: 'https://github.com/${{ github.repository }}.git#branch=main,subdir=proto' diff --git a/Makefile b/Makefile index 1d792ce6..4817380d 100644 --- a/Makefile +++ b/Makefile @@ -174,3 +174,30 @@ generate-graphql: generate-db-template: cp -rf internal/storage/db/provider_template internal/storage/db/${dbname} find internal/storage/db/${dbname} -type f -exec sed -i -e 's/provider_template/${dbname}/g' {} \; + +# ---------------------------------------------------------------------------- +# Protobuf (Phase 0+): public-API source of truth under ./proto. +# `buf` is installed on demand into $(GOBIN) if missing. +# ---------------------------------------------------------------------------- +BUF ?= $(shell command -v buf 2>/dev/null) +BUF_VERSION ?= v1.47.2 + +.PHONY: proto-tools proto-lint proto-breaking proto-gen + +proto-tools: + @if [ -z "$(BUF)" ]; then \ + echo "Installing buf $(BUF_VERSION) via go install"; \ + go install github.com/bufbuild/buf/cmd/buf@$(BUF_VERSION); \ + fi + +proto-lint: proto-tools + cd proto && buf lint + +# Compare the working tree's proto against origin/main; fails on breaking changes. +# Override BUF_BREAKING_AGAINST for local runs (e.g. "main" or a SHA). +BUF_BREAKING_AGAINST ?= .git#branch=origin/main,subdir=proto +proto-breaking: proto-tools + cd proto && buf breaking --against '../$(BUF_BREAKING_AGAINST)' + +proto-gen: proto-tools + cd proto && buf dep update && buf generate diff --git a/cmd/mcp.go b/cmd/mcp.go new file mode 100644 index 00000000..7fa2f87f --- /dev/null +++ b/cmd/mcp.go @@ -0,0 +1,95 @@ +package cmd + +import ( + "context" + "os" + "os/signal" + "syscall" + + "github.com/rs/zerolog" + "github.com/spf13/cobra" + + "github.com/authorizerdev/authorizer/internal/audit" + "github.com/authorizerdev/authorizer/internal/constants" + "github.com/authorizerdev/authorizer/internal/grpcsrv" + "github.com/authorizerdev/authorizer/internal/mcp" + "github.com/authorizerdev/authorizer/internal/service" +) + +// mcpCmd serves Authorizer's MCP surface over stdio. Designed to be wired +// into Claude Code or any other MCP host via: +// +// claude mcp add authorizer -- /path/to/authorizer mcp --client-id=... \ +// --database-type=sqlite --database-url=auth.db +// +// Which tools are exposed is declared at the proto layer via the +// `(authorizer.common.v1.mcp_tool).exposed` option; the MCP server discovers +// them at startup. Today: GetMeta. As more public ops migrate into +// internal/service and get the mcp_tool annotation, they appear automatically. +var mcpCmd = &cobra.Command{ + Use: "mcp", + Short: "Serve Authorizer's MCP tool surface over stdio", + Long: "Exposes a subset of Authorizer's gRPC methods (those marked " + + "(authorizer.common.v1.mcp_tool).exposed=true in proto) as MCP " + + "tools, suitable for use with Claude Code or any MCP-compatible host.", + Run: runMCP, +} + +func init() { + RootCmd.AddCommand(mcpCmd) +} + +func runMCP(_ *cobra.Command, _ []string) { + // MCP stdio mode: stderr-only logging so it doesn't interleave with the + // JSON-RPC framing on stdout. + log := zerolog.New(os.Stderr).With().Timestamp().Logger() + + // For the GetMeta-only vertical slice we don't need storage / token / + // memory store / events / email / sms. As more MCP-exposed tools come + // online (Phase 4+ migrations of ListMyPermissions, GetCurrentSession, + // GetUser(me)) wire them in following the same pattern as runRoot. + svc, err := service.New(&rootArgs.config, &service.Dependencies{ + Log: &log, + // nil-safe: methods that need these subsystems are not yet exposed + // as MCP tools. Each panics-on-nil call moved here would be caught + // by integration tests before reaching prod. + AuditProvider: audit.New(&audit.Dependencies{Log: &log}), + EmailProvider: nil, + EventsProvider: nil, + MemoryStoreProvider: nil, + SMSProvider: nil, + StorageProvider: nil, + TokenProvider: nil, + }) + if err != nil { + log.Fatal().Err(err).Msg("failed to create service provider") + } + + grpcSrv, err := grpcsrv.New(":0", &grpcsrv.Dependencies{ + Log: &log, + Config: &rootArgs.config, + ServiceProvider: svc, + }) + if err != nil { + log.Fatal().Err(err).Msg("failed to create grpc server") + } + + mcpSrv, err := mcp.New(&log, grpcSrv.GRPCServer(), "authorizer", constants.VERSION) + if err != nil { + log.Fatal().Err(err).Msg("failed to create mcp server") + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) + <-c + cancel() + }() + + if err := mcpSrv.RunStdio(ctx); err != nil { + log.Error().Err(err).Msg("mcp server exited") + os.Exit(1) + } +} diff --git a/cmd/root.go b/cmd/root.go index c331e09b..7c24be4c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -3,8 +3,10 @@ package cmd import ( "context" "fmt" + "net" "os" "os/signal" + "strconv" "strings" "time" @@ -25,8 +27,10 @@ import ( "github.com/authorizerdev/authorizer/internal/memory_store" "github.com/authorizerdev/authorizer/internal/metrics" "github.com/authorizerdev/authorizer/internal/oauth" + "github.com/authorizerdev/authorizer/internal/grpcsrv" "github.com/authorizerdev/authorizer/internal/rate_limit" "github.com/authorizerdev/authorizer/internal/server" + "github.com/authorizerdev/authorizer/internal/service" "github.com/authorizerdev/authorizer/internal/sms" "github.com/authorizerdev/authorizer/internal/storage" "github.com/authorizerdev/authorizer/internal/token" @@ -102,6 +106,14 @@ func init() { f.IntVar(&rootArgs.config.GraphQLMaxAliases, "graphql-max-aliases", 30, "Maximum total number of aliased fields per GraphQL operation") f.Int64Var(&rootArgs.config.GraphQLMaxBodyBytes, "graphql-max-body-bytes", 1<<20, "Maximum allowed GraphQL request body size in bytes (default 1MB)") + // gRPC server flags. Port 9091 avoids collision with the metrics + // listener which defaults to 8081 (and with the HTTP listener on 8080). + f.IntVar(&rootArgs.config.GRPCPort, "grpc-port", 9091, "Port the gRPC server listens on") + f.BoolVar(&rootArgs.config.EnableGRPCReflection, "enable-grpc-reflection", true, "Enable the gRPC server-reflection service") + f.StringVar(&rootArgs.config.GRPCTLSCert, "grpc-tls-cert", "", "Path to the TLS certificate for the gRPC server") + f.StringVar(&rootArgs.config.GRPCTLSKey, "grpc-tls-key", "", "Path to the TLS private key for the gRPC server") + f.BoolVar(&rootArgs.config.GRPCInsecure, "grpc-insecure", false, "Allow the gRPC server to run without TLS (dev only)") + // Organization flags f.StringVar(&rootArgs.config.OrganizationLogo, "organization-logo", defaultOrganizationLogo, "Logo of the organization") f.StringVar(&rootArgs.config.OrganizationName, "organization-name", defaultOrganizationName, "Name of the organization") @@ -333,9 +345,20 @@ func applyFlagDefaults() { // Run the service func runRoot(c *cobra.Command, args []string) { applyFlagDefaults() - if rootArgs.server.HTTPPort == rootArgs.server.MetricsPort { - fmt.Fprintf(os.Stderr, "invalid server ports: --http-port and --metrics-port must differ (metrics are always served on a dedicated listener)\n") - os.Exit(1) + // All three listeners (HTTP, metrics, gRPC) bind concurrently; any + // collision is unrecoverable at runtime, so we fail fast at startup. + ports := map[string]int{ + "--http-port": rootArgs.server.HTTPPort, + "--metrics-port": rootArgs.server.MetricsPort, + "--grpc-port": rootArgs.config.GRPCPort, + } + for nameA, a := range ports { + for nameB, b := range ports { + if nameA < nameB && a == b { + fmt.Fprintf(os.Stderr, "invalid server ports: %s (%d) and %s (%d) must differ — each listener binds independently\n", nameA, a, nameB, b) + os.Exit(1) + } + } } // Refuse to start without an admin secret. The previous default of @@ -530,6 +553,23 @@ func runRoot(c *cobra.Command, args []string) { StorageProvider: storageProvider, }) + // Transport-agnostic service layer that hosts public-API operations + // (currently SignUp; more migrate over in subsequent phases). GraphQL, + // gRPC, and REST surfaces all delegate to this. + serviceProvider, err := service.New(&rootArgs.config, &service.Dependencies{ + Log: &log, + AuditProvider: auditProvider, + EmailProvider: emailProvider, + EventsProvider: eventsProvider, + MemoryStoreProvider: memoryStoreProvider, + SMSProvider: smsProvider, + StorageProvider: storageProvider, + TokenProvider: tokenProvider, + }) + if err != nil { + log.Fatal().Err(err).Msg("failed to create service provider") + } + httpProvider, err := http_handlers.New(&rootArgs.config, &http_handlers.Dependencies{ Log: &log, AuditProvider: auditProvider, @@ -543,15 +583,32 @@ func runRoot(c *cobra.Command, args []string) { OAuthProvider: oauthProvider, RateLimitProvider: rateLimitProvider, AuthorizationProvider: authorizationProvider, + ServiceProvider: serviceProvider, }) if err != nil { log.Fatal().Err(err).Msg("failed to create http provider") } + + // gRPC server — listens on --grpc-port. The REST gateway built by + // server.Run wraps this same gRPC server in-process so /v1/* REST + // calls translate to local gRPC method invocations (no network hop). + grpcAddr := net.JoinHostPort(rootArgs.server.Host, strconv.Itoa(rootArgs.config.GRPCPort)) + grpcSrv, err := grpcsrv.New(grpcAddr, &grpcsrv.Dependencies{ + Log: &log, + Config: &rootArgs.config, + ServiceProvider: serviceProvider, + }) + if err != nil { + log.Fatal().Err(err).Msg("failed to create grpc server") + } + rootArgs.server.GRPCPort = rootArgs.config.GRPCPort + // Prepare server deps := &server.Dependencies{ Log: &log, AppConfig: &rootArgs.config, HTTPProvider: httpProvider, + GRPCServer: grpcSrv, } // Create the server svr, err := server.New(&rootArgs.server, deps) diff --git a/gen/go/authorizer/common/v1/annotations.pb.go b/gen/go/authorizer/common/v1/annotations.pb.go new file mode 100644 index 00000000..8357924f --- /dev/null +++ b/gen/go/authorizer/common/v1/annotations.pb.go @@ -0,0 +1,332 @@ +// Custom proto options that decorate Authorizer service methods with +// authorization, audit, MCP-exposure, and visibility metadata. +// +// All options live on MethodOptions and are read at runtime by the gRPC +// server (auth/permission/audit interceptors) and by the MCP server, and +// at codegen time by the OpenAPI generator. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.2 +// protoc (unknown) +// source: authorizer/common/v1/annotations.proto + +package commonv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// PermissionRequirement names one (resource, scope) pair the caller must hold +// to invoke the RPC. Multiple values on a method are AND-combined (the caller +// must hold *all* of them); to express OR semantics, list the alternatives in +// a single PermissionRequirement with a wildcard scope and let the policy +// engine evaluate. +type PermissionRequirement struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Resource name as registered in the authz subsystem (e.g. "user", + // "webhook"). Required. + Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` + // Scope name (e.g. "read", "write", "delete"). Required. + Scope string `protobuf:"bytes,2,opt,name=scope,proto3" json:"scope,omitempty"` +} + +func (x *PermissionRequirement) Reset() { + *x = PermissionRequirement{} + mi := &file_authorizer_common_v1_annotations_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PermissionRequirement) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PermissionRequirement) ProtoMessage() {} + +func (x *PermissionRequirement) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_common_v1_annotations_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PermissionRequirement.ProtoReflect.Descriptor instead. +func (*PermissionRequirement) Descriptor() ([]byte, []int) { + return file_authorizer_common_v1_annotations_proto_rawDescGZIP(), []int{0} +} + +func (x *PermissionRequirement) GetResource() string { + if x != nil { + return x.Resource + } + return "" +} + +func (x *PermissionRequirement) GetScope() string { + if x != nil { + return x.Scope + } + return "" +} + +// McpTool marks an RPC as exposed via the Authorizer MCP server. +// Defaults to "not exposed" when the option is absent. +type McpTool struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Whether the RPC is reachable as an MCP tool. Default false. + Exposed bool `protobuf:"varint,1,opt,name=exposed,proto3" json:"exposed,omitempty"` + // Optional override for the tool name surfaced to MCP clients. When unset, + // the snake_case form of the RPC method name is used. + ToolName string `protobuf:"bytes,2,opt,name=tool_name,json=toolName,proto3" json:"tool_name,omitempty"` + // Hint to the MCP host that the tool mutates state in a way that warrants + // explicit user confirmation (e.g. delete operations). + Destructive bool `protobuf:"varint,3,opt,name=destructive,proto3" json:"destructive,omitempty"` +} + +func (x *McpTool) Reset() { + *x = McpTool{} + mi := &file_authorizer_common_v1_annotations_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *McpTool) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*McpTool) ProtoMessage() {} + +func (x *McpTool) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_common_v1_annotations_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use McpTool.ProtoReflect.Descriptor instead. +func (*McpTool) Descriptor() ([]byte, []int) { + return file_authorizer_common_v1_annotations_proto_rawDescGZIP(), []int{1} +} + +func (x *McpTool) GetExposed() bool { + if x != nil { + return x.Exposed + } + return false +} + +func (x *McpTool) GetToolName() string { + if x != nil { + return x.ToolName + } + return "" +} + +func (x *McpTool) GetDestructive() bool { + if x != nil { + return x.Destructive + } + return false +} + +var file_authorizer_common_v1_annotations_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: ([]*PermissionRequirement)(nil), + Field: 50001, + Name: "authorizer.common.v1.required_permissions", + Tag: "bytes,50001,rep,name=required_permissions", + Filename: "authorizer/common/v1/annotations.proto", + }, + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*McpTool)(nil), + Field: 50002, + Name: "authorizer.common.v1.mcp_tool", + Tag: "bytes,50002,opt,name=mcp_tool", + Filename: "authorizer/common/v1/annotations.proto", + }, + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50003, + Name: "authorizer.common.v1.audit_log", + Tag: "varint,50003,opt,name=audit_log", + Filename: "authorizer/common/v1/annotations.proto", + }, + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50004, + Name: "authorizer.common.v1.public", + Tag: "varint,50004,opt,name=public", + Filename: "authorizer/common/v1/annotations.proto", + }, +} + +// Extension fields to descriptorpb.MethodOptions. +var ( + // All permissions the caller must hold (AND). Empty means "no authz check + // beyond the auth interceptor". + // + // repeated authorizer.common.v1.PermissionRequirement required_permissions = 50001; + E_RequiredPermissions = &file_authorizer_common_v1_annotations_proto_extTypes[0] + // MCP-tool exposure metadata; absent means "not exposed". + // + // optional authorizer.common.v1.McpTool mcp_tool = 50002; + E_McpTool = &file_authorizer_common_v1_annotations_proto_extTypes[1] + // When true, the audit interceptor records an entry for the invocation. + // + // optional bool audit_log = 50003; + E_AuditLog = &file_authorizer_common_v1_annotations_proto_extTypes[2] + // When true, the auth interceptor allows unauthenticated callers. Use for + // login, signup, magic-link request, password-reset request, etc. + // + // optional bool public = 50004; + E_Public = &file_authorizer_common_v1_annotations_proto_extTypes[3] +) + +var File_authorizer_common_v1_annotations_proto protoreflect.FileDescriptor + +var file_authorizer_common_v1_annotations_proto_rawDesc = []byte{ + 0x0a, 0x26, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x20, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x49, 0x0a, 0x15, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0x62, 0x0a, 0x07, 0x4d, + 0x63, 0x70, 0x54, 0x6f, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, + 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, + 0x80, 0x01, 0x0a, 0x14, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd1, 0x86, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2b, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x13, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x3a, 0x5a, 0x0a, 0x08, 0x6d, 0x63, 0x70, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0x1e, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd2, + 0x86, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x63, + 0x70, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x07, 0x6d, 0x63, 0x70, 0x54, 0x6f, 0x6f, 0x6c, 0x3a, 0x3d, + 0x0a, 0x09, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x12, 0x1e, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd3, 0x86, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x3a, 0x38, 0x0a, + 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd4, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x42, 0xe8, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x64, + 0x65, 0x76, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x67, 0x65, + 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x43, 0x58, 0xaa, 0x02, 0x14, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0xca, + 0x02, 0x14, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x5c, 0x43, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x5c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x3a, 0x3a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3a, 0x3a, + 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_authorizer_common_v1_annotations_proto_rawDescOnce sync.Once + file_authorizer_common_v1_annotations_proto_rawDescData = file_authorizer_common_v1_annotations_proto_rawDesc +) + +func file_authorizer_common_v1_annotations_proto_rawDescGZIP() []byte { + file_authorizer_common_v1_annotations_proto_rawDescOnce.Do(func() { + file_authorizer_common_v1_annotations_proto_rawDescData = protoimpl.X.CompressGZIP(file_authorizer_common_v1_annotations_proto_rawDescData) + }) + return file_authorizer_common_v1_annotations_proto_rawDescData +} + +var file_authorizer_common_v1_annotations_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_authorizer_common_v1_annotations_proto_goTypes = []any{ + (*PermissionRequirement)(nil), // 0: authorizer.common.v1.PermissionRequirement + (*McpTool)(nil), // 1: authorizer.common.v1.McpTool + (*descriptorpb.MethodOptions)(nil), // 2: google.protobuf.MethodOptions +} +var file_authorizer_common_v1_annotations_proto_depIdxs = []int32{ + 2, // 0: authorizer.common.v1.required_permissions:extendee -> google.protobuf.MethodOptions + 2, // 1: authorizer.common.v1.mcp_tool:extendee -> google.protobuf.MethodOptions + 2, // 2: authorizer.common.v1.audit_log:extendee -> google.protobuf.MethodOptions + 2, // 3: authorizer.common.v1.public:extendee -> google.protobuf.MethodOptions + 0, // 4: authorizer.common.v1.required_permissions:type_name -> authorizer.common.v1.PermissionRequirement + 1, // 5: authorizer.common.v1.mcp_tool:type_name -> authorizer.common.v1.McpTool + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 4, // [4:6] is the sub-list for extension type_name + 0, // [0:4] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_authorizer_common_v1_annotations_proto_init() } +func file_authorizer_common_v1_annotations_proto_init() { + if File_authorizer_common_v1_annotations_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_authorizer_common_v1_annotations_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 4, + NumServices: 0, + }, + GoTypes: file_authorizer_common_v1_annotations_proto_goTypes, + DependencyIndexes: file_authorizer_common_v1_annotations_proto_depIdxs, + MessageInfos: file_authorizer_common_v1_annotations_proto_msgTypes, + ExtensionInfos: file_authorizer_common_v1_annotations_proto_extTypes, + }.Build() + File_authorizer_common_v1_annotations_proto = out.File + file_authorizer_common_v1_annotations_proto_rawDesc = nil + file_authorizer_common_v1_annotations_proto_goTypes = nil + file_authorizer_common_v1_annotations_proto_depIdxs = nil +} diff --git a/gen/go/authorizer/common/v1/errors.pb.go b/gen/go/authorizer/common/v1/errors.pb.go new file mode 100644 index 00000000..5e9bb211 --- /dev/null +++ b/gen/go/authorizer/common/v1/errors.pb.go @@ -0,0 +1,217 @@ +// Domain-specific error reasons attached to google.rpc.Status via ErrorInfo. +// +// Wire shape: handlers return standard gRPC status codes (e.g. +// PERMISSION_DENIED, INVALID_ARGUMENT) and attach an ErrorInfo detail whose +// `reason` field is one of the enum values below. The gateway surfaces the +// same ErrorInfo in the REST response body. Clients should branch on the +// enum, not on the human-readable message. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.2 +// protoc (unknown) +// source: authorizer/common/v1/errors.proto + +package commonv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ErrorReason int32 + +const ( + ErrorReason_ERROR_REASON_UNSPECIFIED ErrorReason = 0 + // Authentication failed (bad credentials, expired token, missing cookie). + // Maps to gRPC UNAUTHENTICATED / HTTP 401. + ErrorReason_ERROR_REASON_INVALID_CREDENTIALS ErrorReason = 1 + // Caller is authenticated but lacks the required permission. + // Maps to PERMISSION_DENIED / HTTP 403. + ErrorReason_ERROR_REASON_PERMISSION_DENIED ErrorReason = 2 + // The targeted resource does not exist. NOT_FOUND / 404. + ErrorReason_ERROR_REASON_NOT_FOUND ErrorReason = 3 + // A unique constraint was violated (e.g. email already registered). + // ALREADY_EXISTS / 409. + ErrorReason_ERROR_REASON_ALREADY_EXISTS ErrorReason = 4 + // Request validation failed beyond what protovalidate caught + // (cross-field, business-rule). INVALID_ARGUMENT / 400. + ErrorReason_ERROR_REASON_INVALID_REQUEST ErrorReason = 5 + // A required identity-verification step has not been completed + // (email not verified, phone not verified, MFA required). FAILED_PRECONDITION / 412. + ErrorReason_ERROR_REASON_VERIFICATION_REQUIRED ErrorReason = 6 + // The current configuration disables the requested operation + // (sign-up disabled, magic-link login disabled, etc.). FAILED_PRECONDITION / 412. + ErrorReason_ERROR_REASON_OPERATION_DISABLED ErrorReason = 7 + // Caller exceeded the configured rate limit. RESOURCE_EXHAUSTED / 429. + ErrorReason_ERROR_REASON_RATE_LIMITED ErrorReason = 8 + // A verification token (email, password reset, magic link, OTP) is expired + // or has already been consumed. FAILED_PRECONDITION / 412. + ErrorReason_ERROR_REASON_TOKEN_EXPIRED ErrorReason = 9 + // The account is deactivated or its access has been revoked by an admin. + // FAILED_PRECONDITION / 412. + ErrorReason_ERROR_REASON_ACCOUNT_DEACTIVATED ErrorReason = 10 +) + +// Enum value maps for ErrorReason. +var ( + ErrorReason_name = map[int32]string{ + 0: "ERROR_REASON_UNSPECIFIED", + 1: "ERROR_REASON_INVALID_CREDENTIALS", + 2: "ERROR_REASON_PERMISSION_DENIED", + 3: "ERROR_REASON_NOT_FOUND", + 4: "ERROR_REASON_ALREADY_EXISTS", + 5: "ERROR_REASON_INVALID_REQUEST", + 6: "ERROR_REASON_VERIFICATION_REQUIRED", + 7: "ERROR_REASON_OPERATION_DISABLED", + 8: "ERROR_REASON_RATE_LIMITED", + 9: "ERROR_REASON_TOKEN_EXPIRED", + 10: "ERROR_REASON_ACCOUNT_DEACTIVATED", + } + ErrorReason_value = map[string]int32{ + "ERROR_REASON_UNSPECIFIED": 0, + "ERROR_REASON_INVALID_CREDENTIALS": 1, + "ERROR_REASON_PERMISSION_DENIED": 2, + "ERROR_REASON_NOT_FOUND": 3, + "ERROR_REASON_ALREADY_EXISTS": 4, + "ERROR_REASON_INVALID_REQUEST": 5, + "ERROR_REASON_VERIFICATION_REQUIRED": 6, + "ERROR_REASON_OPERATION_DISABLED": 7, + "ERROR_REASON_RATE_LIMITED": 8, + "ERROR_REASON_TOKEN_EXPIRED": 9, + "ERROR_REASON_ACCOUNT_DEACTIVATED": 10, + } +) + +func (x ErrorReason) Enum() *ErrorReason { + p := new(ErrorReason) + *p = x + return p +} + +func (x ErrorReason) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ErrorReason) Descriptor() protoreflect.EnumDescriptor { + return file_authorizer_common_v1_errors_proto_enumTypes[0].Descriptor() +} + +func (ErrorReason) Type() protoreflect.EnumType { + return &file_authorizer_common_v1_errors_proto_enumTypes[0] +} + +func (x ErrorReason) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ErrorReason.Descriptor instead. +func (ErrorReason) EnumDescriptor() ([]byte, []int) { + return file_authorizer_common_v1_errors_proto_rawDescGZIP(), []int{0} +} + +var File_authorizer_common_v1_errors_proto protoreflect.FileDescriptor + +var file_authorizer_common_v1_errors_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2a, 0x86, 0x03, 0x0a, 0x0b, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, + 0x43, 0x52, 0x45, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x41, 0x4c, 0x53, 0x10, 0x01, 0x12, 0x22, 0x0a, + 0x1e, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x50, 0x45, + 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, + 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, + 0x4e, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x03, 0x12, 0x1f, 0x0a, + 0x1b, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, + 0x52, 0x45, 0x41, 0x44, 0x59, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x04, 0x12, 0x20, + 0x0a, 0x1c, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x05, + 0x12, 0x26, 0x0a, 0x22, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, + 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, + 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x06, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x07, 0x12, 0x1d, 0x0a, + 0x19, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x52, 0x41, + 0x54, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x45, 0x44, 0x10, 0x08, 0x12, 0x1e, 0x0a, 0x1a, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x4f, 0x4b, + 0x45, 0x4e, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x09, 0x12, 0x24, 0x0a, 0x20, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x41, 0x43, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x44, + 0x10, 0x0a, 0x42, 0xe3, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, + 0x0b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x48, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x64, 0x65, 0x76, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x43, 0x58, 0xaa, 0x02, + 0x14, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x14, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x65, 0x72, 0x5c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x5c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x16, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x3a, 0x3a, 0x43, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_authorizer_common_v1_errors_proto_rawDescOnce sync.Once + file_authorizer_common_v1_errors_proto_rawDescData = file_authorizer_common_v1_errors_proto_rawDesc +) + +func file_authorizer_common_v1_errors_proto_rawDescGZIP() []byte { + file_authorizer_common_v1_errors_proto_rawDescOnce.Do(func() { + file_authorizer_common_v1_errors_proto_rawDescData = protoimpl.X.CompressGZIP(file_authorizer_common_v1_errors_proto_rawDescData) + }) + return file_authorizer_common_v1_errors_proto_rawDescData +} + +var file_authorizer_common_v1_errors_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_authorizer_common_v1_errors_proto_goTypes = []any{ + (ErrorReason)(0), // 0: authorizer.common.v1.ErrorReason +} +var file_authorizer_common_v1_errors_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_authorizer_common_v1_errors_proto_init() } +func file_authorizer_common_v1_errors_proto_init() { + if File_authorizer_common_v1_errors_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_authorizer_common_v1_errors_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_authorizer_common_v1_errors_proto_goTypes, + DependencyIndexes: file_authorizer_common_v1_errors_proto_depIdxs, + EnumInfos: file_authorizer_common_v1_errors_proto_enumTypes, + }.Build() + File_authorizer_common_v1_errors_proto = out.File + file_authorizer_common_v1_errors_proto_rawDesc = nil + file_authorizer_common_v1_errors_proto_goTypes = nil + file_authorizer_common_v1_errors_proto_depIdxs = nil +} diff --git a/gen/go/authorizer/common/v1/pagination.pb.go b/gen/go/authorizer/common/v1/pagination.pb.go new file mode 100644 index 00000000..1b85cb55 --- /dev/null +++ b/gen/go/authorizer/common/v1/pagination.pb.go @@ -0,0 +1,265 @@ +// Pagination types shared across List RPCs. +// +// The Authorizer GraphQL surface uses page+limit (offset-based) pagination. +// To keep the proto surface familiar for current users *and* compatible with +// AIP-158 (page_token-based) clients, both shapes are accepted on +// PaginationRequest; the server picks page_token when set, else falls back to +// page+limit. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.2 +// protoc (unknown) +// source: authorizer/common/v1/pagination.proto + +package commonv1 + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PaginationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 1-based page number. Ignored when page_token is set. Default 1. + Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + // Page size. Server enforces an upper bound (typically 100). Default 10. + Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + // Opaque cursor returned by the previous List call's `next_page_token`. + // Preferred for new clients (AIP-158). When set, `page` is ignored. + PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` +} + +func (x *PaginationRequest) Reset() { + *x = PaginationRequest{} + mi := &file_authorizer_common_v1_pagination_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PaginationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaginationRequest) ProtoMessage() {} + +func (x *PaginationRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_common_v1_pagination_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaginationRequest.ProtoReflect.Descriptor instead. +func (*PaginationRequest) Descriptor() ([]byte, []int) { + return file_authorizer_common_v1_pagination_proto_rawDescGZIP(), []int{0} +} + +func (x *PaginationRequest) GetPage() int64 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *PaginationRequest) GetLimit() int64 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *PaginationRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +type Pagination struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Limit int64 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` + Page int64 `protobuf:"varint,2,opt,name=page,proto3" json:"page,omitempty"` + Offset int64 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset,omitempty"` + Total int64 `protobuf:"varint,4,opt,name=total,proto3" json:"total,omitempty"` + // Opaque cursor for the next page; empty when no more pages. + NextPageToken string `protobuf:"bytes,5,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *Pagination) Reset() { + *x = Pagination{} + mi := &file_authorizer_common_v1_pagination_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Pagination) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Pagination) ProtoMessage() {} + +func (x *Pagination) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_common_v1_pagination_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Pagination.ProtoReflect.Descriptor instead. +func (*Pagination) Descriptor() ([]byte, []int) { + return file_authorizer_common_v1_pagination_proto_rawDescGZIP(), []int{1} +} + +func (x *Pagination) GetLimit() int64 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *Pagination) GetPage() int64 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *Pagination) GetOffset() int64 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *Pagination) GetTotal() int64 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *Pagination) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +var File_authorizer_common_v1_pagination_proto protoreflect.FileDescriptor + +var file_authorizer_common_v1_pagination_proto_rawDesc = []byte{ + 0x0a, 0x25, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x62, + 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x71, 0x0a, 0x11, 0x50, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1b, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07, 0xba, + 0x48, 0x04, 0x22, 0x02, 0x28, 0x00, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0a, 0xba, 0x48, 0x07, + 0x22, 0x05, 0x18, 0xe8, 0x07, 0x28, 0x00, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, + 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x8c, 0x01, + 0x0a, 0x0a, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, + 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, + 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0xe7, 0x01, 0x0a, + 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0f, 0x50, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x64, 0x65, 0x76, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, + 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x43, 0x58, 0xaa, 0x02, 0x14, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x56, 0x31, 0xca, 0x02, 0x14, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, + 0x5c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x5c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5c, 0x56, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x3a, 0x3a, 0x43, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_authorizer_common_v1_pagination_proto_rawDescOnce sync.Once + file_authorizer_common_v1_pagination_proto_rawDescData = file_authorizer_common_v1_pagination_proto_rawDesc +) + +func file_authorizer_common_v1_pagination_proto_rawDescGZIP() []byte { + file_authorizer_common_v1_pagination_proto_rawDescOnce.Do(func() { + file_authorizer_common_v1_pagination_proto_rawDescData = protoimpl.X.CompressGZIP(file_authorizer_common_v1_pagination_proto_rawDescData) + }) + return file_authorizer_common_v1_pagination_proto_rawDescData +} + +var file_authorizer_common_v1_pagination_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_authorizer_common_v1_pagination_proto_goTypes = []any{ + (*PaginationRequest)(nil), // 0: authorizer.common.v1.PaginationRequest + (*Pagination)(nil), // 1: authorizer.common.v1.Pagination +} +var file_authorizer_common_v1_pagination_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_authorizer_common_v1_pagination_proto_init() } +func file_authorizer_common_v1_pagination_proto_init() { + if File_authorizer_common_v1_pagination_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_authorizer_common_v1_pagination_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_authorizer_common_v1_pagination_proto_goTypes, + DependencyIndexes: file_authorizer_common_v1_pagination_proto_depIdxs, + MessageInfos: file_authorizer_common_v1_pagination_proto_msgTypes, + }.Build() + File_authorizer_common_v1_pagination_proto = out.File + file_authorizer_common_v1_pagination_proto_rawDesc = nil + file_authorizer_common_v1_pagination_proto_goTypes = nil + file_authorizer_common_v1_pagination_proto_depIdxs = nil +} diff --git a/gen/go/authorizer/common/v1/types.pb.go b/gen/go/authorizer/common/v1/types.pb.go new file mode 100644 index 00000000..d35e3e31 --- /dev/null +++ b/gen/go/authorizer/common/v1/types.pb.go @@ -0,0 +1,157 @@ +// Shared scalar-ish types used across Authorizer services. +// +// Kept intentionally tiny: only types that don't naturally belong to a single +// resource service live here. Add a new entry only when at least two services +// share it. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.2 +// protoc (unknown) +// source: authorizer/common/v1/types.proto + +package commonv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// AppData is a free-form key/value bag stored against a user. Mirrors the +// GraphQL `Map` scalar. Values are JSON-typed (string, number, bool, null, +// nested object, nested array) to match what the existing storage layer +// accepts. +type AppData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value *structpb.Struct `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *AppData) Reset() { + *x = AppData{} + mi := &file_authorizer_common_v1_types_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AppData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppData) ProtoMessage() {} + +func (x *AppData) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_common_v1_types_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppData.ProtoReflect.Descriptor instead. +func (*AppData) Descriptor() ([]byte, []int) { + return file_authorizer_common_v1_types_proto_rawDescGZIP(), []int{0} +} + +func (x *AppData) GetValue() *structpb.Struct { + if x != nil { + return x.Value + } + return nil +} + +var File_authorizer_common_v1_types_proto protoreflect.FileDescriptor + +var file_authorizer_common_v1_types_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x14, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x38, 0x0a, 0x07, 0x41, 0x70, 0x70, 0x44, 0x61, 0x74, + 0x61, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 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, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x42, 0xe2, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x65, 0x72, 0x64, 0x65, 0x76, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, + 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x43, 0x58, 0xaa, 0x02, 0x14, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x56, 0x31, 0xca, 0x02, 0x14, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x5c, + 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x5c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5c, 0x56, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x3a, 0x3a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_authorizer_common_v1_types_proto_rawDescOnce sync.Once + file_authorizer_common_v1_types_proto_rawDescData = file_authorizer_common_v1_types_proto_rawDesc +) + +func file_authorizer_common_v1_types_proto_rawDescGZIP() []byte { + file_authorizer_common_v1_types_proto_rawDescOnce.Do(func() { + file_authorizer_common_v1_types_proto_rawDescData = protoimpl.X.CompressGZIP(file_authorizer_common_v1_types_proto_rawDescData) + }) + return file_authorizer_common_v1_types_proto_rawDescData +} + +var file_authorizer_common_v1_types_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_authorizer_common_v1_types_proto_goTypes = []any{ + (*AppData)(nil), // 0: authorizer.common.v1.AppData + (*structpb.Struct)(nil), // 1: google.protobuf.Struct +} +var file_authorizer_common_v1_types_proto_depIdxs = []int32{ + 1, // 0: authorizer.common.v1.AppData.value:type_name -> google.protobuf.Struct + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_authorizer_common_v1_types_proto_init() } +func file_authorizer_common_v1_types_proto_init() { + if File_authorizer_common_v1_types_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_authorizer_common_v1_types_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_authorizer_common_v1_types_proto_goTypes, + DependencyIndexes: file_authorizer_common_v1_types_proto_depIdxs, + MessageInfos: file_authorizer_common_v1_types_proto_msgTypes, + }.Build() + File_authorizer_common_v1_types_proto = out.File + file_authorizer_common_v1_types_proto_rawDesc = nil + file_authorizer_common_v1_types_proto_goTypes = nil + file_authorizer_common_v1_types_proto_depIdxs = nil +} diff --git a/gen/go/authorizer/v1/authorizer.pb.go b/gen/go/authorizer/v1/authorizer.pb.go new file mode 100644 index 00000000..2819abef --- /dev/null +++ b/gen/go/authorizer/v1/authorizer.pb.go @@ -0,0 +1,2826 @@ +// AuthorizerService is the single gRPC service that exposes Authorizer's +// public API. Method names match the GraphQL operation names 1:1 +// (snake_case in GraphQL → PascalCase in proto): Signup, Login, +// MagicLinkLogin, VerifyEmail, ResendVerifyEmail, ForgotPassword, +// ResetPassword, VerifyOtp, ResendOtp, UpdateProfile, DeactivateAccount, +// Revoke, Meta, Session, Profile, ValidateJwtToken, ValidateSession, +// Permissions, Logout. +// +// Why one service: clients consume a single typed client per language, +// discovery is trivial, and the surface mirrors the GraphQL one users +// already know. The trade-off is that we lose resource-oriented evolution +// (no `List/Get/Create` symmetry per resource) — acceptable for an auth +// surface where most operations are stateless verbs anyway. +// +// REST mapping follows a simple rule: +// - GET /v1/{method} when the request body is empty (Meta, Profile, +// Permissions, Logout) +// - POST /v1/{method} otherwise + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.2 +// protoc (unknown) +// source: authorizer/v1/authorizer.proto + +package authorizerv1 + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + v1 "github.com/authorizerdev/authorizer/gen/go/authorizer/common/v1" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SignupRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + PhoneNumber string `protobuf:"bytes,2,opt,name=phone_number,json=phoneNumber,proto3" json:"phone_number,omitempty"` + Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` + ConfirmPassword string `protobuf:"bytes,4,opt,name=confirm_password,json=confirmPassword,proto3" json:"confirm_password,omitempty"` + GivenName string `protobuf:"bytes,5,opt,name=given_name,json=givenName,proto3" json:"given_name,omitempty"` + FamilyName string `protobuf:"bytes,6,opt,name=family_name,json=familyName,proto3" json:"family_name,omitempty"` + MiddleName string `protobuf:"bytes,7,opt,name=middle_name,json=middleName,proto3" json:"middle_name,omitempty"` + Nickname string `protobuf:"bytes,8,opt,name=nickname,proto3" json:"nickname,omitempty"` + Gender string `protobuf:"bytes,9,opt,name=gender,proto3" json:"gender,omitempty"` + Birthdate string `protobuf:"bytes,10,opt,name=birthdate,proto3" json:"birthdate,omitempty"` + Picture string `protobuf:"bytes,11,opt,name=picture,proto3" json:"picture,omitempty"` + Roles []string `protobuf:"bytes,12,rep,name=roles,proto3" json:"roles,omitempty"` + Scope []string `protobuf:"bytes,13,rep,name=scope,proto3" json:"scope,omitempty"` + RedirectUri string `protobuf:"bytes,14,opt,name=redirect_uri,json=redirectUri,proto3" json:"redirect_uri,omitempty"` + IsMultiFactorAuthEnabled bool `protobuf:"varint,15,opt,name=is_multi_factor_auth_enabled,json=isMultiFactorAuthEnabled,proto3" json:"is_multi_factor_auth_enabled,omitempty"` + State string `protobuf:"bytes,16,opt,name=state,proto3" json:"state,omitempty"` + AppData *v1.AppData `protobuf:"bytes,17,opt,name=app_data,json=appData,proto3" json:"app_data,omitempty"` +} + +func (x *SignupRequest) Reset() { + *x = SignupRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SignupRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignupRequest) ProtoMessage() {} + +func (x *SignupRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignupRequest.ProtoReflect.Descriptor instead. +func (*SignupRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{0} +} + +func (x *SignupRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *SignupRequest) GetPhoneNumber() string { + if x != nil { + return x.PhoneNumber + } + return "" +} + +func (x *SignupRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *SignupRequest) GetConfirmPassword() string { + if x != nil { + return x.ConfirmPassword + } + return "" +} + +func (x *SignupRequest) GetGivenName() string { + if x != nil { + return x.GivenName + } + return "" +} + +func (x *SignupRequest) GetFamilyName() string { + if x != nil { + return x.FamilyName + } + return "" +} + +func (x *SignupRequest) GetMiddleName() string { + if x != nil { + return x.MiddleName + } + return "" +} + +func (x *SignupRequest) GetNickname() string { + if x != nil { + return x.Nickname + } + return "" +} + +func (x *SignupRequest) GetGender() string { + if x != nil { + return x.Gender + } + return "" +} + +func (x *SignupRequest) GetBirthdate() string { + if x != nil { + return x.Birthdate + } + return "" +} + +func (x *SignupRequest) GetPicture() string { + if x != nil { + return x.Picture + } + return "" +} + +func (x *SignupRequest) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +func (x *SignupRequest) GetScope() []string { + if x != nil { + return x.Scope + } + return nil +} + +func (x *SignupRequest) GetRedirectUri() string { + if x != nil { + return x.RedirectUri + } + return "" +} + +func (x *SignupRequest) GetIsMultiFactorAuthEnabled() bool { + if x != nil { + return x.IsMultiFactorAuthEnabled + } + return false +} + +func (x *SignupRequest) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *SignupRequest) GetAppData() *v1.AppData { + if x != nil { + return x.AppData + } + return nil +} + +type SignupResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Auth *AuthResponse `protobuf:"bytes,1,opt,name=auth,proto3" json:"auth,omitempty"` +} + +func (x *SignupResponse) Reset() { + *x = SignupResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SignupResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignupResponse) ProtoMessage() {} + +func (x *SignupResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignupResponse.ProtoReflect.Descriptor instead. +func (*SignupResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{1} +} + +func (x *SignupResponse) GetAuth() *AuthResponse { + if x != nil { + return x.Auth + } + return nil +} + +type LoginRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + PhoneNumber string `protobuf:"bytes,2,opt,name=phone_number,json=phoneNumber,proto3" json:"phone_number,omitempty"` + Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` + Roles []string `protobuf:"bytes,4,rep,name=roles,proto3" json:"roles,omitempty"` + Scope []string `protobuf:"bytes,5,rep,name=scope,proto3" json:"scope,omitempty"` + State string `protobuf:"bytes,6,opt,name=state,proto3" json:"state,omitempty"` +} + +func (x *LoginRequest) Reset() { + *x = LoginRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LoginRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LoginRequest) ProtoMessage() {} + +func (x *LoginRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LoginRequest.ProtoReflect.Descriptor instead. +func (*LoginRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{2} +} + +func (x *LoginRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *LoginRequest) GetPhoneNumber() string { + if x != nil { + return x.PhoneNumber + } + return "" +} + +func (x *LoginRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *LoginRequest) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +func (x *LoginRequest) GetScope() []string { + if x != nil { + return x.Scope + } + return nil +} + +func (x *LoginRequest) GetState() string { + if x != nil { + return x.State + } + return "" +} + +type LoginResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Auth *AuthResponse `protobuf:"bytes,1,opt,name=auth,proto3" json:"auth,omitempty"` +} + +func (x *LoginResponse) Reset() { + *x = LoginResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LoginResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LoginResponse) ProtoMessage() {} + +func (x *LoginResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LoginResponse.ProtoReflect.Descriptor instead. +func (*LoginResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{3} +} + +func (x *LoginResponse) GetAuth() *AuthResponse { + if x != nil { + return x.Auth + } + return nil +} + +type LogoutRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *LogoutRequest) Reset() { + *x = LogoutRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LogoutRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogoutRequest) ProtoMessage() {} + +func (x *LogoutRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogoutRequest.ProtoReflect.Descriptor instead. +func (*LogoutRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{4} +} + +type LogoutResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *LogoutResponse) Reset() { + *x = LogoutResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LogoutResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogoutResponse) ProtoMessage() {} + +func (x *LogoutResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogoutResponse.ProtoReflect.Descriptor instead. +func (*LogoutResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{5} +} + +func (x *LogoutResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type MagicLinkLoginRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + Roles []string `protobuf:"bytes,2,rep,name=roles,proto3" json:"roles,omitempty"` + Scope []string `protobuf:"bytes,3,rep,name=scope,proto3" json:"scope,omitempty"` + State string `protobuf:"bytes,4,opt,name=state,proto3" json:"state,omitempty"` + RedirectUri string `protobuf:"bytes,5,opt,name=redirect_uri,json=redirectUri,proto3" json:"redirect_uri,omitempty"` +} + +func (x *MagicLinkLoginRequest) Reset() { + *x = MagicLinkLoginRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MagicLinkLoginRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MagicLinkLoginRequest) ProtoMessage() {} + +func (x *MagicLinkLoginRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MagicLinkLoginRequest.ProtoReflect.Descriptor instead. +func (*MagicLinkLoginRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{6} +} + +func (x *MagicLinkLoginRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *MagicLinkLoginRequest) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +func (x *MagicLinkLoginRequest) GetScope() []string { + if x != nil { + return x.Scope + } + return nil +} + +func (x *MagicLinkLoginRequest) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *MagicLinkLoginRequest) GetRedirectUri() string { + if x != nil { + return x.RedirectUri + } + return "" +} + +type MagicLinkLoginResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *MagicLinkLoginResponse) Reset() { + *x = MagicLinkLoginResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MagicLinkLoginResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MagicLinkLoginResponse) ProtoMessage() {} + +func (x *MagicLinkLoginResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MagicLinkLoginResponse.ProtoReflect.Descriptor instead. +func (*MagicLinkLoginResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{7} +} + +func (x *MagicLinkLoginResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type VerifyEmailRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + State string `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` +} + +func (x *VerifyEmailRequest) Reset() { + *x = VerifyEmailRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VerifyEmailRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyEmailRequest) ProtoMessage() {} + +func (x *VerifyEmailRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyEmailRequest.ProtoReflect.Descriptor instead. +func (*VerifyEmailRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{8} +} + +func (x *VerifyEmailRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *VerifyEmailRequest) GetState() string { + if x != nil { + return x.State + } + return "" +} + +type VerifyEmailResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Auth *AuthResponse `protobuf:"bytes,1,opt,name=auth,proto3" json:"auth,omitempty"` +} + +func (x *VerifyEmailResponse) Reset() { + *x = VerifyEmailResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VerifyEmailResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyEmailResponse) ProtoMessage() {} + +func (x *VerifyEmailResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyEmailResponse.ProtoReflect.Descriptor instead. +func (*VerifyEmailResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{9} +} + +func (x *VerifyEmailResponse) GetAuth() *AuthResponse { + if x != nil { + return x.Auth + } + return nil +} + +type ResendVerifyEmailRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + Identifier string `protobuf:"bytes,2,opt,name=identifier,proto3" json:"identifier,omitempty"` + State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` +} + +func (x *ResendVerifyEmailRequest) Reset() { + *x = ResendVerifyEmailRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResendVerifyEmailRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResendVerifyEmailRequest) ProtoMessage() {} + +func (x *ResendVerifyEmailRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResendVerifyEmailRequest.ProtoReflect.Descriptor instead. +func (*ResendVerifyEmailRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{10} +} + +func (x *ResendVerifyEmailRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *ResendVerifyEmailRequest) GetIdentifier() string { + if x != nil { + return x.Identifier + } + return "" +} + +func (x *ResendVerifyEmailRequest) GetState() string { + if x != nil { + return x.State + } + return "" +} + +type ResendVerifyEmailResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *ResendVerifyEmailResponse) Reset() { + *x = ResendVerifyEmailResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResendVerifyEmailResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResendVerifyEmailResponse) ProtoMessage() {} + +func (x *ResendVerifyEmailResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResendVerifyEmailResponse.ProtoReflect.Descriptor instead. +func (*ResendVerifyEmailResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{11} +} + +func (x *ResendVerifyEmailResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type VerifyOtpRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Exactly one of email / phone_number is required. + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + PhoneNumber string `protobuf:"bytes,2,opt,name=phone_number,json=phoneNumber,proto3" json:"phone_number,omitempty"` + Otp string `protobuf:"bytes,3,opt,name=otp,proto3" json:"otp,omitempty"` + IsTotp bool `protobuf:"varint,4,opt,name=is_totp,json=isTotp,proto3" json:"is_totp,omitempty"` + State string `protobuf:"bytes,5,opt,name=state,proto3" json:"state,omitempty"` +} + +func (x *VerifyOtpRequest) Reset() { + *x = VerifyOtpRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VerifyOtpRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyOtpRequest) ProtoMessage() {} + +func (x *VerifyOtpRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyOtpRequest.ProtoReflect.Descriptor instead. +func (*VerifyOtpRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{12} +} + +func (x *VerifyOtpRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *VerifyOtpRequest) GetPhoneNumber() string { + if x != nil { + return x.PhoneNumber + } + return "" +} + +func (x *VerifyOtpRequest) GetOtp() string { + if x != nil { + return x.Otp + } + return "" +} + +func (x *VerifyOtpRequest) GetIsTotp() bool { + if x != nil { + return x.IsTotp + } + return false +} + +func (x *VerifyOtpRequest) GetState() string { + if x != nil { + return x.State + } + return "" +} + +type VerifyOtpResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Auth *AuthResponse `protobuf:"bytes,1,opt,name=auth,proto3" json:"auth,omitempty"` +} + +func (x *VerifyOtpResponse) Reset() { + *x = VerifyOtpResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VerifyOtpResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyOtpResponse) ProtoMessage() {} + +func (x *VerifyOtpResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VerifyOtpResponse.ProtoReflect.Descriptor instead. +func (*VerifyOtpResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{13} +} + +func (x *VerifyOtpResponse) GetAuth() *AuthResponse { + if x != nil { + return x.Auth + } + return nil +} + +type ResendOtpRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + PhoneNumber string `protobuf:"bytes,2,opt,name=phone_number,json=phoneNumber,proto3" json:"phone_number,omitempty"` + State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` +} + +func (x *ResendOtpRequest) Reset() { + *x = ResendOtpRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResendOtpRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResendOtpRequest) ProtoMessage() {} + +func (x *ResendOtpRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResendOtpRequest.ProtoReflect.Descriptor instead. +func (*ResendOtpRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{14} +} + +func (x *ResendOtpRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *ResendOtpRequest) GetPhoneNumber() string { + if x != nil { + return x.PhoneNumber + } + return "" +} + +func (x *ResendOtpRequest) GetState() string { + if x != nil { + return x.State + } + return "" +} + +type ResendOtpResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *ResendOtpResponse) Reset() { + *x = ResendOtpResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResendOtpResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResendOtpResponse) ProtoMessage() {} + +func (x *ResendOtpResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResendOtpResponse.ProtoReflect.Descriptor instead. +func (*ResendOtpResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{15} +} + +func (x *ResendOtpResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type ForgotPasswordRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + PhoneNumber string `protobuf:"bytes,2,opt,name=phone_number,json=phoneNumber,proto3" json:"phone_number,omitempty"` + State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` + RedirectUri string `protobuf:"bytes,4,opt,name=redirect_uri,json=redirectUri,proto3" json:"redirect_uri,omitempty"` +} + +func (x *ForgotPasswordRequest) Reset() { + *x = ForgotPasswordRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ForgotPasswordRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ForgotPasswordRequest) ProtoMessage() {} + +func (x *ForgotPasswordRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ForgotPasswordRequest.ProtoReflect.Descriptor instead. +func (*ForgotPasswordRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{16} +} + +func (x *ForgotPasswordRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *ForgotPasswordRequest) GetPhoneNumber() string { + if x != nil { + return x.PhoneNumber + } + return "" +} + +func (x *ForgotPasswordRequest) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *ForgotPasswordRequest) GetRedirectUri() string { + if x != nil { + return x.RedirectUri + } + return "" +} + +type ForgotPasswordResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + // For SMS-driven flows the UI may need to render an OTP entry screen. + ShouldShowMobileOtpScreen bool `protobuf:"varint,2,opt,name=should_show_mobile_otp_screen,json=shouldShowMobileOtpScreen,proto3" json:"should_show_mobile_otp_screen,omitempty"` +} + +func (x *ForgotPasswordResponse) Reset() { + *x = ForgotPasswordResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ForgotPasswordResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ForgotPasswordResponse) ProtoMessage() {} + +func (x *ForgotPasswordResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ForgotPasswordResponse.ProtoReflect.Descriptor instead. +func (*ForgotPasswordResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{17} +} + +func (x *ForgotPasswordResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ForgotPasswordResponse) GetShouldShowMobileOtpScreen() bool { + if x != nil { + return x.ShouldShowMobileOtpScreen + } + return false +} + +type ResetPasswordRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // For email flows: the token from the reset email. For SMS flows: the OTP. + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + Otp string `protobuf:"bytes,2,opt,name=otp,proto3" json:"otp,omitempty"` + PhoneNumber string `protobuf:"bytes,3,opt,name=phone_number,json=phoneNumber,proto3" json:"phone_number,omitempty"` + Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` + ConfirmPassword string `protobuf:"bytes,5,opt,name=confirm_password,json=confirmPassword,proto3" json:"confirm_password,omitempty"` +} + +func (x *ResetPasswordRequest) Reset() { + *x = ResetPasswordRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResetPasswordRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetPasswordRequest) ProtoMessage() {} + +func (x *ResetPasswordRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResetPasswordRequest.ProtoReflect.Descriptor instead. +func (*ResetPasswordRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{18} +} + +func (x *ResetPasswordRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *ResetPasswordRequest) GetOtp() string { + if x != nil { + return x.Otp + } + return "" +} + +func (x *ResetPasswordRequest) GetPhoneNumber() string { + if x != nil { + return x.PhoneNumber + } + return "" +} + +func (x *ResetPasswordRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *ResetPasswordRequest) GetConfirmPassword() string { + if x != nil { + return x.ConfirmPassword + } + return "" +} + +type ResetPasswordResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *ResetPasswordResponse) Reset() { + *x = ResetPasswordResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResetPasswordResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetPasswordResponse) ProtoMessage() {} + +func (x *ResetPasswordResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResetPasswordResponse.ProtoReflect.Descriptor instead. +func (*ResetPasswordResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{19} +} + +func (x *ResetPasswordResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type ProfileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ProfileRequest) Reset() { + *x = ProfileRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProfileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProfileRequest) ProtoMessage() {} + +func (x *ProfileRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProfileRequest.ProtoReflect.Descriptor instead. +func (*ProfileRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{20} +} + +type ProfileResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *ProfileResponse) Reset() { + *x = ProfileResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProfileResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProfileResponse) ProtoMessage() {} + +func (x *ProfileResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProfileResponse.ProtoReflect.Descriptor instead. +func (*ProfileResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{21} +} + +func (x *ProfileResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +type UpdateProfileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OldPassword string `protobuf:"bytes,1,opt,name=old_password,json=oldPassword,proto3" json:"old_password,omitempty"` + NewPassword string `protobuf:"bytes,2,opt,name=new_password,json=newPassword,proto3" json:"new_password,omitempty"` + ConfirmNewPassword string `protobuf:"bytes,3,opt,name=confirm_new_password,json=confirmNewPassword,proto3" json:"confirm_new_password,omitempty"` + Email string `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"` + GivenName string `protobuf:"bytes,5,opt,name=given_name,json=givenName,proto3" json:"given_name,omitempty"` + FamilyName string `protobuf:"bytes,6,opt,name=family_name,json=familyName,proto3" json:"family_name,omitempty"` + MiddleName string `protobuf:"bytes,7,opt,name=middle_name,json=middleName,proto3" json:"middle_name,omitempty"` + Nickname string `protobuf:"bytes,8,opt,name=nickname,proto3" json:"nickname,omitempty"` + Gender string `protobuf:"bytes,9,opt,name=gender,proto3" json:"gender,omitempty"` + Birthdate string `protobuf:"bytes,10,opt,name=birthdate,proto3" json:"birthdate,omitempty"` + PhoneNumber string `protobuf:"bytes,11,opt,name=phone_number,json=phoneNumber,proto3" json:"phone_number,omitempty"` + Picture string `protobuf:"bytes,12,opt,name=picture,proto3" json:"picture,omitempty"` + IsMultiFactorAuthEnabled bool `protobuf:"varint,13,opt,name=is_multi_factor_auth_enabled,json=isMultiFactorAuthEnabled,proto3" json:"is_multi_factor_auth_enabled,omitempty"` + AppData *v1.AppData `protobuf:"bytes,14,opt,name=app_data,json=appData,proto3" json:"app_data,omitempty"` +} + +func (x *UpdateProfileRequest) Reset() { + *x = UpdateProfileRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateProfileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateProfileRequest) ProtoMessage() {} + +func (x *UpdateProfileRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateProfileRequest.ProtoReflect.Descriptor instead. +func (*UpdateProfileRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{22} +} + +func (x *UpdateProfileRequest) GetOldPassword() string { + if x != nil { + return x.OldPassword + } + return "" +} + +func (x *UpdateProfileRequest) GetNewPassword() string { + if x != nil { + return x.NewPassword + } + return "" +} + +func (x *UpdateProfileRequest) GetConfirmNewPassword() string { + if x != nil { + return x.ConfirmNewPassword + } + return "" +} + +func (x *UpdateProfileRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *UpdateProfileRequest) GetGivenName() string { + if x != nil { + return x.GivenName + } + return "" +} + +func (x *UpdateProfileRequest) GetFamilyName() string { + if x != nil { + return x.FamilyName + } + return "" +} + +func (x *UpdateProfileRequest) GetMiddleName() string { + if x != nil { + return x.MiddleName + } + return "" +} + +func (x *UpdateProfileRequest) GetNickname() string { + if x != nil { + return x.Nickname + } + return "" +} + +func (x *UpdateProfileRequest) GetGender() string { + if x != nil { + return x.Gender + } + return "" +} + +func (x *UpdateProfileRequest) GetBirthdate() string { + if x != nil { + return x.Birthdate + } + return "" +} + +func (x *UpdateProfileRequest) GetPhoneNumber() string { + if x != nil { + return x.PhoneNumber + } + return "" +} + +func (x *UpdateProfileRequest) GetPicture() string { + if x != nil { + return x.Picture + } + return "" +} + +func (x *UpdateProfileRequest) GetIsMultiFactorAuthEnabled() bool { + if x != nil { + return x.IsMultiFactorAuthEnabled + } + return false +} + +func (x *UpdateProfileRequest) GetAppData() *v1.AppData { + if x != nil { + return x.AppData + } + return nil +} + +type UpdateProfileResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *UpdateProfileResponse) Reset() { + *x = UpdateProfileResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateProfileResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateProfileResponse) ProtoMessage() {} + +func (x *UpdateProfileResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateProfileResponse.ProtoReflect.Descriptor instead. +func (*UpdateProfileResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{23} +} + +func (x *UpdateProfileResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type DeactivateAccountRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeactivateAccountRequest) Reset() { + *x = DeactivateAccountRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeactivateAccountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeactivateAccountRequest) ProtoMessage() {} + +func (x *DeactivateAccountRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeactivateAccountRequest.ProtoReflect.Descriptor instead. +func (*DeactivateAccountRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{24} +} + +type DeactivateAccountResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *DeactivateAccountResponse) Reset() { + *x = DeactivateAccountResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeactivateAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeactivateAccountResponse) ProtoMessage() {} + +func (x *DeactivateAccountResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[25] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeactivateAccountResponse.ProtoReflect.Descriptor instead. +func (*DeactivateAccountResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{25} +} + +func (x *DeactivateAccountResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type RevokeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RefreshToken string `protobuf:"bytes,1,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"` +} + +func (x *RevokeRequest) Reset() { + *x = RevokeRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RevokeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RevokeRequest) ProtoMessage() {} + +func (x *RevokeRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RevokeRequest.ProtoReflect.Descriptor instead. +func (*RevokeRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{26} +} + +func (x *RevokeRequest) GetRefreshToken() string { + if x != nil { + return x.RefreshToken + } + return "" +} + +type RevokeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *RevokeResponse) Reset() { + *x = RevokeResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RevokeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RevokeResponse) ProtoMessage() {} + +func (x *RevokeResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RevokeResponse.ProtoReflect.Descriptor instead. +func (*RevokeResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{27} +} + +func (x *RevokeResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type SessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Roles []string `protobuf:"bytes,1,rep,name=roles,proto3" json:"roles,omitempty"` + Scope []string `protobuf:"bytes,2,rep,name=scope,proto3" json:"scope,omitempty"` + State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"` + // Optional AND-combined permission filter; deny if any is missing. + RequiredPermissions []*PermissionInput `protobuf:"bytes,4,rep,name=required_permissions,json=requiredPermissions,proto3" json:"required_permissions,omitempty"` +} + +func (x *SessionRequest) Reset() { + *x = SessionRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionRequest) ProtoMessage() {} + +func (x *SessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionRequest.ProtoReflect.Descriptor instead. +func (*SessionRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{28} +} + +func (x *SessionRequest) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +func (x *SessionRequest) GetScope() []string { + if x != nil { + return x.Scope + } + return nil +} + +func (x *SessionRequest) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *SessionRequest) GetRequiredPermissions() []*PermissionInput { + if x != nil { + return x.RequiredPermissions + } + return nil +} + +type SessionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Auth *AuthResponse `protobuf:"bytes,1,opt,name=auth,proto3" json:"auth,omitempty"` +} + +func (x *SessionResponse) Reset() { + *x = SessionResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionResponse) ProtoMessage() {} + +func (x *SessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[29] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionResponse.ProtoReflect.Descriptor instead. +func (*SessionResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{29} +} + +func (x *SessionResponse) GetAuth() *AuthResponse { + if x != nil { + return x.Auth + } + return nil +} + +type ValidateJwtTokenRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TokenType string `protobuf:"bytes,1,opt,name=token_type,json=tokenType,proto3" json:"token_type,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + Roles []string `protobuf:"bytes,3,rep,name=roles,proto3" json:"roles,omitempty"` + RequiredPermissions []*PermissionInput `protobuf:"bytes,4,rep,name=required_permissions,json=requiredPermissions,proto3" json:"required_permissions,omitempty"` +} + +func (x *ValidateJwtTokenRequest) Reset() { + *x = ValidateJwtTokenRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ValidateJwtTokenRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateJwtTokenRequest) ProtoMessage() {} + +func (x *ValidateJwtTokenRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[30] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateJwtTokenRequest.ProtoReflect.Descriptor instead. +func (*ValidateJwtTokenRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{30} +} + +func (x *ValidateJwtTokenRequest) GetTokenType() string { + if x != nil { + return x.TokenType + } + return "" +} + +func (x *ValidateJwtTokenRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *ValidateJwtTokenRequest) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +func (x *ValidateJwtTokenRequest) GetRequiredPermissions() []*PermissionInput { + if x != nil { + return x.RequiredPermissions + } + return nil +} + +type ValidateJwtTokenResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"` + // Free-form JWT claims (matches GraphQL ValidateJWTTokenResponse.claims). + Claims *v1.AppData `protobuf:"bytes,2,opt,name=claims,proto3" json:"claims,omitempty"` +} + +func (x *ValidateJwtTokenResponse) Reset() { + *x = ValidateJwtTokenResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ValidateJwtTokenResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateJwtTokenResponse) ProtoMessage() {} + +func (x *ValidateJwtTokenResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[31] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateJwtTokenResponse.ProtoReflect.Descriptor instead. +func (*ValidateJwtTokenResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{31} +} + +func (x *ValidateJwtTokenResponse) GetIsValid() bool { + if x != nil { + return x.IsValid + } + return false +} + +func (x *ValidateJwtTokenResponse) GetClaims() *v1.AppData { + if x != nil { + return x.Claims + } + return nil +} + +type ValidateSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Cookie string `protobuf:"bytes,1,opt,name=cookie,proto3" json:"cookie,omitempty"` + Roles []string `protobuf:"bytes,2,rep,name=roles,proto3" json:"roles,omitempty"` + RequiredPermissions []*PermissionInput `protobuf:"bytes,3,rep,name=required_permissions,json=requiredPermissions,proto3" json:"required_permissions,omitempty"` +} + +func (x *ValidateSessionRequest) Reset() { + *x = ValidateSessionRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ValidateSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateSessionRequest) ProtoMessage() {} + +func (x *ValidateSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[32] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateSessionRequest.ProtoReflect.Descriptor instead. +func (*ValidateSessionRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{32} +} + +func (x *ValidateSessionRequest) GetCookie() string { + if x != nil { + return x.Cookie + } + return "" +} + +func (x *ValidateSessionRequest) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +func (x *ValidateSessionRequest) GetRequiredPermissions() []*PermissionInput { + if x != nil { + return x.RequiredPermissions + } + return nil +} + +type ValidateSessionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"` + User *User `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *ValidateSessionResponse) Reset() { + *x = ValidateSessionResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ValidateSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateSessionResponse) ProtoMessage() {} + +func (x *ValidateSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[33] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateSessionResponse.ProtoReflect.Descriptor instead. +func (*ValidateSessionResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{33} +} + +func (x *ValidateSessionResponse) GetIsValid() bool { + if x != nil { + return x.IsValid + } + return false +} + +func (x *ValidateSessionResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +type MetaRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MetaRequest) Reset() { + *x = MetaRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MetaRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetaRequest) ProtoMessage() {} + +func (x *MetaRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[34] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetaRequest.ProtoReflect.Descriptor instead. +func (*MetaRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{34} +} + +type MetaResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Meta *Meta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"` +} + +func (x *MetaResponse) Reset() { + *x = MetaResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MetaResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetaResponse) ProtoMessage() {} + +func (x *MetaResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[35] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetaResponse.ProtoReflect.Descriptor instead. +func (*MetaResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{35} +} + +func (x *MetaResponse) GetMeta() *Meta { + if x != nil { + return x.Meta + } + return nil +} + +type PermissionsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PermissionsRequest) Reset() { + *x = PermissionsRequest{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PermissionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PermissionsRequest) ProtoMessage() {} + +func (x *PermissionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[36] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PermissionsRequest.ProtoReflect.Descriptor instead. +func (*PermissionsRequest) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{36} +} + +type PermissionsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Permissions []*Permission `protobuf:"bytes,1,rep,name=permissions,proto3" json:"permissions,omitempty"` +} + +func (x *PermissionsResponse) Reset() { + *x = PermissionsResponse{} + mi := &file_authorizer_v1_authorizer_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PermissionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PermissionsResponse) ProtoMessage() {} + +func (x *PermissionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_authorizer_proto_msgTypes[37] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PermissionsResponse.ProtoReflect.Descriptor instead. +func (*PermissionsResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_authorizer_proto_rawDescGZIP(), []int{37} +} + +func (x *PermissionsResponse) GetPermissions() []*Permission { + if x != nil { + return x.Permissions + } + return nil +} + +var File_authorizer_v1_authorizer_proto protoreflect.FileDescriptor + +var file_authorizer_v1_authorizer_proto_rawDesc = []byte{ + 0x0a, 0x1e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, + 0x26, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xe6, 0x04, 0x0a, 0x0d, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1e, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0xc0, 0x02, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x12, 0x2a, 0x0a, 0x0c, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x18, 0x20, + 0x52, 0x0b, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, + 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0x80, 0x01, 0x52, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, + 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0x80, 0x01, 0x52, 0x0f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x72, 0x6d, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x67, 0x69, 0x76, 0x65, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, + 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, + 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x74, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, + 0x65, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x69, 0x12, 0x3e, 0x0a, 0x1c, 0x69, 0x73, 0x5f, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x75, 0x74, 0x68, + 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, + 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x75, 0x74, + 0x68, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x38, + 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, + 0x07, 0x61, 0x70, 0x70, 0x44, 0x61, 0x74, 0x61, 0x22, 0x41, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, + 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x61, 0x75, + 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0xc4, 0x01, 0x0a, 0x0c, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x05, + 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, + 0x72, 0x03, 0x18, 0xc0, 0x02, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2a, 0x0a, 0x0c, + 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x18, 0x20, 0x52, 0x0b, 0x70, 0x68, 0x6f, + 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, + 0x05, 0x10, 0x01, 0x18, 0x80, 0x01, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x22, 0x40, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x04, + 0x61, 0x75, 0x74, 0x68, 0x22, 0x0f, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2a, 0x0a, 0x0e, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0x9c, 0x01, 0x0a, 0x15, 0x4d, 0x61, 0x67, 0x69, 0x63, 0x4c, 0x69, 0x6e, 0x6b, 0x4c, + 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x05, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, + 0x03, 0x18, 0xc0, 0x02, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x72, + 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x69, + 0x22, 0x32, 0x0a, 0x16, 0x4d, 0x61, 0x67, 0x69, 0x63, 0x4c, 0x69, 0x6e, 0x6b, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x49, 0x0a, 0x12, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, + 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, + 0x10, 0x01, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, + 0x46, 0x0a, 0x13, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0x79, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x65, 0x6e, + 0x64, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0xc0, 0x02, 0x52, 0x05, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x12, 0x27, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, + 0x52, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x22, 0x35, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xaa, 0x01, 0x0a, 0x10, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x4f, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, + 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0x18, 0xc0, 0x02, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2a, + 0x0a, 0x0c, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x18, 0x20, 0x52, 0x0b, 0x70, + 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x03, 0x6f, 0x74, + 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xba, 0x48, 0x06, 0x72, 0x04, 0x10, 0x01, + 0x18, 0x10, 0x52, 0x03, 0x6f, 0x74, 0x70, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x74, 0x6f, + 0x74, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x54, 0x6f, 0x74, 0x70, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x44, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, + 0x4f, 0x74, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x61, + 0x75, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0x74, 0x0a, 0x10, + 0x52, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x4f, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1e, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0xc0, 0x02, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x12, 0x2a, 0x0a, 0x0c, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x18, 0x20, 0x52, + 0x0b, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x22, 0x2d, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x4f, 0x74, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0x9c, 0x01, 0x0a, 0x15, 0x46, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x05, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, + 0x03, 0x18, 0xc0, 0x02, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2a, 0x0a, 0x0c, 0x70, + 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x18, 0x20, 0x52, 0x0b, 0x70, 0x68, 0x6f, 0x6e, + 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x69, + 0x22, 0x74, 0x0a, 0x16, 0x46, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x73, + 0x68, 0x6f, 0x77, 0x5f, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x5f, 0x6f, 0x74, 0x70, 0x5f, 0x73, + 0x63, 0x72, 0x65, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x68, 0x6f, + 0x75, 0x6c, 0x64, 0x53, 0x68, 0x6f, 0x77, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x4f, 0x74, 0x70, + 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x22, 0xc9, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x65, 0x74, + 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x74, 0x70, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6f, 0x74, 0x70, 0x12, 0x2a, 0x0a, 0x0c, 0x70, 0x68, 0x6f, 0x6e, 0x65, + 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, + 0x48, 0x04, 0x72, 0x02, 0x18, 0x20, 0x52, 0x0b, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0x80, + 0x01, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x10, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0x80, + 0x01, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x22, 0x31, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x75, 0x73, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, + 0x73, 0x65, 0x72, 0x22, 0xb5, 0x04, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, + 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x6c, 0x64, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, + 0x2b, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0x80, 0x01, 0x52, + 0x0b, 0x6e, 0x65, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x3a, 0x0a, 0x14, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, + 0x03, 0x18, 0x80, 0x01, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x4e, 0x65, 0x77, + 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1e, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0xc0, + 0x02, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x76, 0x65, + 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, + 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x61, 0x6d, 0x69, 0x6c, + 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, + 0x6d, 0x69, 0x6c, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x69, 0x64, 0x64, + 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, + 0x69, 0x64, 0x64, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, + 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, + 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x1c, 0x0a, + 0x09, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x0c, 0x70, + 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x18, 0x20, 0x52, 0x0b, 0x70, 0x68, 0x6f, 0x6e, + 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, + 0x72, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x12, 0x3e, 0x0a, 0x1c, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x66, 0x61, + 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, + 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x75, 0x74, 0x68, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x12, 0x38, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x61, + 0x74, 0x61, 0x52, 0x07, 0x61, 0x70, 0x70, 0x44, 0x61, 0x74, 0x61, 0x22, 0x31, 0x0a, 0x15, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x1a, + 0x0a, 0x18, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x35, 0x0a, 0x19, 0x44, 0x65, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0x3d, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, + 0x10, 0x01, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x22, 0x2a, 0x0a, 0x0e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xa5, 0x01, 0x0a, + 0x0e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x51, 0x0a, 0x14, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, + 0x13, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x42, 0x0a, 0x0f, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0xc9, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x77, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x72, + 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, + 0x73, 0x12, 0x51, 0x0a, 0x14, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, + 0x13, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x6c, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x4a, 0x77, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x06, 0x63, + 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x06, 0x63, 0x6c, 0x61, 0x69, + 0x6d, 0x73, 0x22, 0xa2, 0x01, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, + 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, + 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, + 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x51, 0x0a, 0x14, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, + 0x75, 0x74, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5d, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x27, 0x0a, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x0d, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x37, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x14, + 0x0a, 0x12, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x52, 0x0a, 0x13, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x32, 0xec, 0x11, 0x0a, 0x11, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x68, + 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x1c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x92, 0xb5, 0x18, 0x00, 0x98, 0xb5, 0x18, 0x01, 0xa0, + 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x3a, 0x01, 0x2a, 0x22, 0x0a, 0x2f, 0x76, + 0x31, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x64, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, + 0x6e, 0x12, 0x1b, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x92, 0xb5, + 0x18, 0x00, 0x98, 0xb5, 0x18, 0x01, 0xa0, 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, + 0x3a, 0x01, 0x2a, 0x22, 0x09, 0x2f, 0x76, 0x31, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x5d, + 0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x1c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x98, 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x86, 0x01, + 0x0a, 0x0e, 0x4d, 0x61, 0x67, 0x69, 0x63, 0x4c, 0x69, 0x6e, 0x6b, 0x4c, 0x6f, 0x67, 0x69, 0x6e, + 0x12, 0x24, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x4d, 0x61, 0x67, 0x69, 0x63, 0x4c, 0x69, 0x6e, 0x6b, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x67, 0x69, 0x63, 0x4c, 0x69, 0x6e, 0x6b, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x98, + 0xb5, 0x18, 0x01, 0xa0, 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, + 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, + 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x79, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, + 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x21, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, + 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, + 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x98, 0xb5, + 0x18, 0x01, 0xa0, 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, + 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x12, 0x8e, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x27, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x28, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, + 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0xa0, 0xb5, 0x18, 0x01, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x3a, 0x01, 0x2a, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x72, + 0x65, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x12, 0x71, 0x0a, 0x09, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4f, 0x74, 0x70, 0x12, + 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4f, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4f, 0x74, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x21, 0x98, 0xb5, 0x18, 0x01, 0xa0, 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x22, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x5f, 0x6f, 0x74, 0x70, 0x12, 0x6d, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x4f, + 0x74, 0x70, 0x12, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x4f, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x4f, 0x74, 0x70, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0xa0, 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x13, 0x3a, 0x01, 0x2a, 0x22, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x64, + 0x5f, 0x6f, 0x74, 0x70, 0x12, 0x81, 0x01, 0x0a, 0x0e, 0x46, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x24, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, + 0x72, 0x67, 0x6f, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xa0, 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, + 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x5f, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x81, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, + 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x23, 0x2e, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, + 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x98, 0xb5, 0x18, 0x01, 0xa0, 0xb5, 0x18, 0x01, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, + 0x73, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x63, 0x0a, 0x07, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x92, 0xb5, 0x18, 0x02, 0x08, 0x01, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x7d, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x12, 0x23, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x98, + 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x76, + 0x31, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x12, 0x93, 0x01, 0x0a, 0x11, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x28, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x92, 0xb5, 0x18, 0x02, 0x18, + 0x01, 0x98, 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, 0x16, + 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x60, 0x0a, 0x06, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, + 0x12, 0x1c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, + 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x98, + 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x3a, 0x01, 0x2a, 0x22, 0x0a, 0x2f, 0x76, + 0x31, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x66, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x1c, 0x92, 0xb5, 0x18, 0x02, 0x08, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, + 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x8a, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x77, 0x74, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x26, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x77, + 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x77, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0xa0, 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x6a, 0x77, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x85, 0x01, + 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x25, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x23, 0xa0, 0xb5, 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, + 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x5b, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1a, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x92, 0xb5, 0x18, 0x02, 0x08, 0x01, 0xa0, 0xb5, + 0x18, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, + 0x74, 0x61, 0x12, 0x73, 0x0a, 0x0b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x21, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x92, 0xb5, 0x18, 0x02, 0x08, 0x01, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0xc0, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0f, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x64, 0x65, 0x76, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x0d, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_authorizer_v1_authorizer_proto_rawDescOnce sync.Once + file_authorizer_v1_authorizer_proto_rawDescData = file_authorizer_v1_authorizer_proto_rawDesc +) + +func file_authorizer_v1_authorizer_proto_rawDescGZIP() []byte { + file_authorizer_v1_authorizer_proto_rawDescOnce.Do(func() { + file_authorizer_v1_authorizer_proto_rawDescData = protoimpl.X.CompressGZIP(file_authorizer_v1_authorizer_proto_rawDescData) + }) + return file_authorizer_v1_authorizer_proto_rawDescData +} + +var file_authorizer_v1_authorizer_proto_msgTypes = make([]protoimpl.MessageInfo, 38) +var file_authorizer_v1_authorizer_proto_goTypes = []any{ + (*SignupRequest)(nil), // 0: authorizer.v1.SignupRequest + (*SignupResponse)(nil), // 1: authorizer.v1.SignupResponse + (*LoginRequest)(nil), // 2: authorizer.v1.LoginRequest + (*LoginResponse)(nil), // 3: authorizer.v1.LoginResponse + (*LogoutRequest)(nil), // 4: authorizer.v1.LogoutRequest + (*LogoutResponse)(nil), // 5: authorizer.v1.LogoutResponse + (*MagicLinkLoginRequest)(nil), // 6: authorizer.v1.MagicLinkLoginRequest + (*MagicLinkLoginResponse)(nil), // 7: authorizer.v1.MagicLinkLoginResponse + (*VerifyEmailRequest)(nil), // 8: authorizer.v1.VerifyEmailRequest + (*VerifyEmailResponse)(nil), // 9: authorizer.v1.VerifyEmailResponse + (*ResendVerifyEmailRequest)(nil), // 10: authorizer.v1.ResendVerifyEmailRequest + (*ResendVerifyEmailResponse)(nil), // 11: authorizer.v1.ResendVerifyEmailResponse + (*VerifyOtpRequest)(nil), // 12: authorizer.v1.VerifyOtpRequest + (*VerifyOtpResponse)(nil), // 13: authorizer.v1.VerifyOtpResponse + (*ResendOtpRequest)(nil), // 14: authorizer.v1.ResendOtpRequest + (*ResendOtpResponse)(nil), // 15: authorizer.v1.ResendOtpResponse + (*ForgotPasswordRequest)(nil), // 16: authorizer.v1.ForgotPasswordRequest + (*ForgotPasswordResponse)(nil), // 17: authorizer.v1.ForgotPasswordResponse + (*ResetPasswordRequest)(nil), // 18: authorizer.v1.ResetPasswordRequest + (*ResetPasswordResponse)(nil), // 19: authorizer.v1.ResetPasswordResponse + (*ProfileRequest)(nil), // 20: authorizer.v1.ProfileRequest + (*ProfileResponse)(nil), // 21: authorizer.v1.ProfileResponse + (*UpdateProfileRequest)(nil), // 22: authorizer.v1.UpdateProfileRequest + (*UpdateProfileResponse)(nil), // 23: authorizer.v1.UpdateProfileResponse + (*DeactivateAccountRequest)(nil), // 24: authorizer.v1.DeactivateAccountRequest + (*DeactivateAccountResponse)(nil), // 25: authorizer.v1.DeactivateAccountResponse + (*RevokeRequest)(nil), // 26: authorizer.v1.RevokeRequest + (*RevokeResponse)(nil), // 27: authorizer.v1.RevokeResponse + (*SessionRequest)(nil), // 28: authorizer.v1.SessionRequest + (*SessionResponse)(nil), // 29: authorizer.v1.SessionResponse + (*ValidateJwtTokenRequest)(nil), // 30: authorizer.v1.ValidateJwtTokenRequest + (*ValidateJwtTokenResponse)(nil), // 31: authorizer.v1.ValidateJwtTokenResponse + (*ValidateSessionRequest)(nil), // 32: authorizer.v1.ValidateSessionRequest + (*ValidateSessionResponse)(nil), // 33: authorizer.v1.ValidateSessionResponse + (*MetaRequest)(nil), // 34: authorizer.v1.MetaRequest + (*MetaResponse)(nil), // 35: authorizer.v1.MetaResponse + (*PermissionsRequest)(nil), // 36: authorizer.v1.PermissionsRequest + (*PermissionsResponse)(nil), // 37: authorizer.v1.PermissionsResponse + (*v1.AppData)(nil), // 38: authorizer.common.v1.AppData + (*AuthResponse)(nil), // 39: authorizer.v1.AuthResponse + (*User)(nil), // 40: authorizer.v1.User + (*PermissionInput)(nil), // 41: authorizer.v1.PermissionInput + (*Meta)(nil), // 42: authorizer.v1.Meta + (*Permission)(nil), // 43: authorizer.v1.Permission +} +var file_authorizer_v1_authorizer_proto_depIdxs = []int32{ + 38, // 0: authorizer.v1.SignupRequest.app_data:type_name -> authorizer.common.v1.AppData + 39, // 1: authorizer.v1.SignupResponse.auth:type_name -> authorizer.v1.AuthResponse + 39, // 2: authorizer.v1.LoginResponse.auth:type_name -> authorizer.v1.AuthResponse + 39, // 3: authorizer.v1.VerifyEmailResponse.auth:type_name -> authorizer.v1.AuthResponse + 39, // 4: authorizer.v1.VerifyOtpResponse.auth:type_name -> authorizer.v1.AuthResponse + 40, // 5: authorizer.v1.ProfileResponse.user:type_name -> authorizer.v1.User + 38, // 6: authorizer.v1.UpdateProfileRequest.app_data:type_name -> authorizer.common.v1.AppData + 41, // 7: authorizer.v1.SessionRequest.required_permissions:type_name -> authorizer.v1.PermissionInput + 39, // 8: authorizer.v1.SessionResponse.auth:type_name -> authorizer.v1.AuthResponse + 41, // 9: authorizer.v1.ValidateJwtTokenRequest.required_permissions:type_name -> authorizer.v1.PermissionInput + 38, // 10: authorizer.v1.ValidateJwtTokenResponse.claims:type_name -> authorizer.common.v1.AppData + 41, // 11: authorizer.v1.ValidateSessionRequest.required_permissions:type_name -> authorizer.v1.PermissionInput + 40, // 12: authorizer.v1.ValidateSessionResponse.user:type_name -> authorizer.v1.User + 42, // 13: authorizer.v1.MetaResponse.meta:type_name -> authorizer.v1.Meta + 43, // 14: authorizer.v1.PermissionsResponse.permissions:type_name -> authorizer.v1.Permission + 0, // 15: authorizer.v1.AuthorizerService.Signup:input_type -> authorizer.v1.SignupRequest + 2, // 16: authorizer.v1.AuthorizerService.Login:input_type -> authorizer.v1.LoginRequest + 4, // 17: authorizer.v1.AuthorizerService.Logout:input_type -> authorizer.v1.LogoutRequest + 6, // 18: authorizer.v1.AuthorizerService.MagicLinkLogin:input_type -> authorizer.v1.MagicLinkLoginRequest + 8, // 19: authorizer.v1.AuthorizerService.VerifyEmail:input_type -> authorizer.v1.VerifyEmailRequest + 10, // 20: authorizer.v1.AuthorizerService.ResendVerifyEmail:input_type -> authorizer.v1.ResendVerifyEmailRequest + 12, // 21: authorizer.v1.AuthorizerService.VerifyOtp:input_type -> authorizer.v1.VerifyOtpRequest + 14, // 22: authorizer.v1.AuthorizerService.ResendOtp:input_type -> authorizer.v1.ResendOtpRequest + 16, // 23: authorizer.v1.AuthorizerService.ForgotPassword:input_type -> authorizer.v1.ForgotPasswordRequest + 18, // 24: authorizer.v1.AuthorizerService.ResetPassword:input_type -> authorizer.v1.ResetPasswordRequest + 20, // 25: authorizer.v1.AuthorizerService.Profile:input_type -> authorizer.v1.ProfileRequest + 22, // 26: authorizer.v1.AuthorizerService.UpdateProfile:input_type -> authorizer.v1.UpdateProfileRequest + 24, // 27: authorizer.v1.AuthorizerService.DeactivateAccount:input_type -> authorizer.v1.DeactivateAccountRequest + 26, // 28: authorizer.v1.AuthorizerService.Revoke:input_type -> authorizer.v1.RevokeRequest + 28, // 29: authorizer.v1.AuthorizerService.Session:input_type -> authorizer.v1.SessionRequest + 30, // 30: authorizer.v1.AuthorizerService.ValidateJwtToken:input_type -> authorizer.v1.ValidateJwtTokenRequest + 32, // 31: authorizer.v1.AuthorizerService.ValidateSession:input_type -> authorizer.v1.ValidateSessionRequest + 34, // 32: authorizer.v1.AuthorizerService.Meta:input_type -> authorizer.v1.MetaRequest + 36, // 33: authorizer.v1.AuthorizerService.Permissions:input_type -> authorizer.v1.PermissionsRequest + 1, // 34: authorizer.v1.AuthorizerService.Signup:output_type -> authorizer.v1.SignupResponse + 3, // 35: authorizer.v1.AuthorizerService.Login:output_type -> authorizer.v1.LoginResponse + 5, // 36: authorizer.v1.AuthorizerService.Logout:output_type -> authorizer.v1.LogoutResponse + 7, // 37: authorizer.v1.AuthorizerService.MagicLinkLogin:output_type -> authorizer.v1.MagicLinkLoginResponse + 9, // 38: authorizer.v1.AuthorizerService.VerifyEmail:output_type -> authorizer.v1.VerifyEmailResponse + 11, // 39: authorizer.v1.AuthorizerService.ResendVerifyEmail:output_type -> authorizer.v1.ResendVerifyEmailResponse + 13, // 40: authorizer.v1.AuthorizerService.VerifyOtp:output_type -> authorizer.v1.VerifyOtpResponse + 15, // 41: authorizer.v1.AuthorizerService.ResendOtp:output_type -> authorizer.v1.ResendOtpResponse + 17, // 42: authorizer.v1.AuthorizerService.ForgotPassword:output_type -> authorizer.v1.ForgotPasswordResponse + 19, // 43: authorizer.v1.AuthorizerService.ResetPassword:output_type -> authorizer.v1.ResetPasswordResponse + 21, // 44: authorizer.v1.AuthorizerService.Profile:output_type -> authorizer.v1.ProfileResponse + 23, // 45: authorizer.v1.AuthorizerService.UpdateProfile:output_type -> authorizer.v1.UpdateProfileResponse + 25, // 46: authorizer.v1.AuthorizerService.DeactivateAccount:output_type -> authorizer.v1.DeactivateAccountResponse + 27, // 47: authorizer.v1.AuthorizerService.Revoke:output_type -> authorizer.v1.RevokeResponse + 29, // 48: authorizer.v1.AuthorizerService.Session:output_type -> authorizer.v1.SessionResponse + 31, // 49: authorizer.v1.AuthorizerService.ValidateJwtToken:output_type -> authorizer.v1.ValidateJwtTokenResponse + 33, // 50: authorizer.v1.AuthorizerService.ValidateSession:output_type -> authorizer.v1.ValidateSessionResponse + 35, // 51: authorizer.v1.AuthorizerService.Meta:output_type -> authorizer.v1.MetaResponse + 37, // 52: authorizer.v1.AuthorizerService.Permissions:output_type -> authorizer.v1.PermissionsResponse + 34, // [34:53] is the sub-list for method output_type + 15, // [15:34] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name +} + +func init() { file_authorizer_v1_authorizer_proto_init() } +func file_authorizer_v1_authorizer_proto_init() { + if File_authorizer_v1_authorizer_proto != nil { + return + } + file_authorizer_v1_types_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_authorizer_v1_authorizer_proto_rawDesc, + NumEnums: 0, + NumMessages: 38, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_authorizer_v1_authorizer_proto_goTypes, + DependencyIndexes: file_authorizer_v1_authorizer_proto_depIdxs, + MessageInfos: file_authorizer_v1_authorizer_proto_msgTypes, + }.Build() + File_authorizer_v1_authorizer_proto = out.File + file_authorizer_v1_authorizer_proto_rawDesc = nil + file_authorizer_v1_authorizer_proto_goTypes = nil + file_authorizer_v1_authorizer_proto_depIdxs = nil +} diff --git a/gen/go/authorizer/v1/authorizer.pb.gw.go b/gen/go/authorizer/v1/authorizer.pb.gw.go new file mode 100644 index 00000000..175e390c --- /dev/null +++ b/gen/go/authorizer/v1/authorizer.pb.gw.go @@ -0,0 +1,1518 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: authorizer/v1/authorizer.proto + +/* +Package authorizerv1 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package authorizerv1 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_AuthorizerService_Signup_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignupRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Signup(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_Signup_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignupRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Signup(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_Login_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LoginRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Login(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_Login_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LoginRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Login(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_Logout_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LogoutRequest + var metadata runtime.ServerMetadata + + msg, err := client.Logout(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_Logout_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LogoutRequest + var metadata runtime.ServerMetadata + + msg, err := server.Logout(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_MagicLinkLogin_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MagicLinkLoginRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.MagicLinkLogin(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_MagicLinkLogin_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MagicLinkLoginRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.MagicLinkLogin(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_VerifyEmail_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq VerifyEmailRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.VerifyEmail(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_VerifyEmail_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq VerifyEmailRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.VerifyEmail(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_ResendVerifyEmail_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ResendVerifyEmailRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ResendVerifyEmail(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_ResendVerifyEmail_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ResendVerifyEmailRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ResendVerifyEmail(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_VerifyOtp_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq VerifyOtpRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.VerifyOtp(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_VerifyOtp_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq VerifyOtpRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.VerifyOtp(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_ResendOtp_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ResendOtpRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ResendOtp(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_ResendOtp_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ResendOtpRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ResendOtp(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_ForgotPassword_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ForgotPasswordRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ForgotPassword(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_ForgotPassword_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ForgotPasswordRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ForgotPassword(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_ResetPassword_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ResetPasswordRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ResetPassword(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_ResetPassword_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ResetPasswordRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ResetPassword(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_Profile_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ProfileRequest + var metadata runtime.ServerMetadata + + msg, err := client.Profile(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_Profile_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ProfileRequest + var metadata runtime.ServerMetadata + + msg, err := server.Profile(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_UpdateProfile_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateProfileRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UpdateProfile(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_UpdateProfile_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateProfileRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UpdateProfile(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_DeactivateAccount_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeactivateAccountRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.DeactivateAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_DeactivateAccount_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeactivateAccountRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.DeactivateAccount(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_Revoke_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RevokeRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Revoke(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_Revoke_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RevokeRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Revoke(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_Session_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SessionRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Session(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_Session_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SessionRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Session(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_ValidateJwtToken_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ValidateJwtTokenRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ValidateJwtToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_ValidateJwtToken_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ValidateJwtTokenRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ValidateJwtToken(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_ValidateSession_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ValidateSessionRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ValidateSession(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_ValidateSession_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ValidateSessionRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ValidateSession(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_Meta_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MetaRequest + var metadata runtime.ServerMetadata + + msg, err := client.Meta(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_Meta_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq MetaRequest + var metadata runtime.ServerMetadata + + msg, err := server.Meta(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthorizerService_Permissions_0(ctx context.Context, marshaler runtime.Marshaler, client AuthorizerServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PermissionsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Permissions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthorizerService_Permissions_0(ctx context.Context, marshaler runtime.Marshaler, server AuthorizerServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PermissionsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Permissions(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterAuthorizerServiceHandlerServer registers the http handlers for service AuthorizerService to "mux". +// UnaryRPC :call AuthorizerServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAuthorizerServiceHandlerFromEndpoint instead. +// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call. +func RegisterAuthorizerServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthorizerServiceServer) error { + + mux.Handle("POST", pattern_AuthorizerService_Signup_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, "/authorizer.v1.AuthorizerService/Signup", runtime.WithHTTPPathPattern("/v1/signup")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_Signup_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_AuthorizerService_Signup_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_Login_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, "/authorizer.v1.AuthorizerService/Login", runtime.WithHTTPPathPattern("/v1/login")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_Login_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_AuthorizerService_Login_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AuthorizerService_Logout_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, "/authorizer.v1.AuthorizerService/Logout", runtime.WithHTTPPathPattern("/v1/logout")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_Logout_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_AuthorizerService_Logout_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_MagicLinkLogin_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, "/authorizer.v1.AuthorizerService/MagicLinkLogin", runtime.WithHTTPPathPattern("/v1/magic_link_login")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_MagicLinkLogin_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_AuthorizerService_MagicLinkLogin_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_VerifyEmail_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, "/authorizer.v1.AuthorizerService/VerifyEmail", runtime.WithHTTPPathPattern("/v1/verify_email")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_VerifyEmail_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_AuthorizerService_VerifyEmail_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ResendVerifyEmail_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, "/authorizer.v1.AuthorizerService/ResendVerifyEmail", runtime.WithHTTPPathPattern("/v1/resend_verify_email")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_ResendVerifyEmail_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_AuthorizerService_ResendVerifyEmail_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_VerifyOtp_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, "/authorizer.v1.AuthorizerService/VerifyOtp", runtime.WithHTTPPathPattern("/v1/verify_otp")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_VerifyOtp_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_AuthorizerService_VerifyOtp_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ResendOtp_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, "/authorizer.v1.AuthorizerService/ResendOtp", runtime.WithHTTPPathPattern("/v1/resend_otp")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_ResendOtp_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_AuthorizerService_ResendOtp_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ForgotPassword_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, "/authorizer.v1.AuthorizerService/ForgotPassword", runtime.WithHTTPPathPattern("/v1/forgot_password")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_ForgotPassword_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_AuthorizerService_ForgotPassword_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ResetPassword_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, "/authorizer.v1.AuthorizerService/ResetPassword", runtime.WithHTTPPathPattern("/v1/reset_password")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_ResetPassword_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_AuthorizerService_ResetPassword_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AuthorizerService_Profile_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, "/authorizer.v1.AuthorizerService/Profile", runtime.WithHTTPPathPattern("/v1/profile")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_Profile_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_AuthorizerService_Profile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_UpdateProfile_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, "/authorizer.v1.AuthorizerService/UpdateProfile", runtime.WithHTTPPathPattern("/v1/update_profile")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_UpdateProfile_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_AuthorizerService_UpdateProfile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_DeactivateAccount_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, "/authorizer.v1.AuthorizerService/DeactivateAccount", runtime.WithHTTPPathPattern("/v1/deactivate_account")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_DeactivateAccount_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_AuthorizerService_DeactivateAccount_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_Revoke_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, "/authorizer.v1.AuthorizerService/Revoke", runtime.WithHTTPPathPattern("/v1/revoke")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_Revoke_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_AuthorizerService_Revoke_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_Session_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, "/authorizer.v1.AuthorizerService/Session", runtime.WithHTTPPathPattern("/v1/session")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_Session_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_AuthorizerService_Session_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ValidateJwtToken_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, "/authorizer.v1.AuthorizerService/ValidateJwtToken", runtime.WithHTTPPathPattern("/v1/validate_jwt_token")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_ValidateJwtToken_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_AuthorizerService_ValidateJwtToken_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ValidateSession_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, "/authorizer.v1.AuthorizerService/ValidateSession", runtime.WithHTTPPathPattern("/v1/validate_session")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_ValidateSession_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_AuthorizerService_ValidateSession_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AuthorizerService_Meta_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, "/authorizer.v1.AuthorizerService/Meta", runtime.WithHTTPPathPattern("/v1/meta")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_Meta_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_AuthorizerService_Meta_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AuthorizerService_Permissions_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, "/authorizer.v1.AuthorizerService/Permissions", runtime.WithHTTPPathPattern("/v1/permissions")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthorizerService_Permissions_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_AuthorizerService_Permissions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterAuthorizerServiceHandlerFromEndpoint is same as RegisterAuthorizerServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterAuthorizerServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.NewClient(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterAuthorizerServiceHandler(ctx, mux, conn) +} + +// RegisterAuthorizerServiceHandler registers the http handlers for service AuthorizerService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterAuthorizerServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterAuthorizerServiceHandlerClient(ctx, mux, NewAuthorizerServiceClient(conn)) +} + +// RegisterAuthorizerServiceHandlerClient registers the http handlers for service AuthorizerService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AuthorizerServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthorizerServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "AuthorizerServiceClient" to call the correct interceptors. This client ignores the HTTP middlewares. +func RegisterAuthorizerServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthorizerServiceClient) error { + + mux.Handle("POST", pattern_AuthorizerService_Signup_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, "/authorizer.v1.AuthorizerService/Signup", runtime.WithHTTPPathPattern("/v1/signup")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_Signup_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_Signup_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_Login_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, "/authorizer.v1.AuthorizerService/Login", runtime.WithHTTPPathPattern("/v1/login")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_Login_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_Login_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AuthorizerService_Logout_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, "/authorizer.v1.AuthorizerService/Logout", runtime.WithHTTPPathPattern("/v1/logout")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_Logout_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_Logout_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_MagicLinkLogin_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, "/authorizer.v1.AuthorizerService/MagicLinkLogin", runtime.WithHTTPPathPattern("/v1/magic_link_login")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_MagicLinkLogin_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_MagicLinkLogin_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_VerifyEmail_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, "/authorizer.v1.AuthorizerService/VerifyEmail", runtime.WithHTTPPathPattern("/v1/verify_email")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_VerifyEmail_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_VerifyEmail_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ResendVerifyEmail_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, "/authorizer.v1.AuthorizerService/ResendVerifyEmail", runtime.WithHTTPPathPattern("/v1/resend_verify_email")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_ResendVerifyEmail_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_ResendVerifyEmail_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_VerifyOtp_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, "/authorizer.v1.AuthorizerService/VerifyOtp", runtime.WithHTTPPathPattern("/v1/verify_otp")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_VerifyOtp_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_VerifyOtp_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ResendOtp_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, "/authorizer.v1.AuthorizerService/ResendOtp", runtime.WithHTTPPathPattern("/v1/resend_otp")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_ResendOtp_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_ResendOtp_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ForgotPassword_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, "/authorizer.v1.AuthorizerService/ForgotPassword", runtime.WithHTTPPathPattern("/v1/forgot_password")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_ForgotPassword_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_ForgotPassword_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ResetPassword_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, "/authorizer.v1.AuthorizerService/ResetPassword", runtime.WithHTTPPathPattern("/v1/reset_password")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_ResetPassword_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_ResetPassword_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AuthorizerService_Profile_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, "/authorizer.v1.AuthorizerService/Profile", runtime.WithHTTPPathPattern("/v1/profile")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_Profile_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_Profile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_UpdateProfile_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, "/authorizer.v1.AuthorizerService/UpdateProfile", runtime.WithHTTPPathPattern("/v1/update_profile")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_UpdateProfile_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_UpdateProfile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_DeactivateAccount_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, "/authorizer.v1.AuthorizerService/DeactivateAccount", runtime.WithHTTPPathPattern("/v1/deactivate_account")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_DeactivateAccount_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_DeactivateAccount_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_Revoke_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, "/authorizer.v1.AuthorizerService/Revoke", runtime.WithHTTPPathPattern("/v1/revoke")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_Revoke_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_Revoke_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_Session_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, "/authorizer.v1.AuthorizerService/Session", runtime.WithHTTPPathPattern("/v1/session")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_Session_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_Session_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ValidateJwtToken_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, "/authorizer.v1.AuthorizerService/ValidateJwtToken", runtime.WithHTTPPathPattern("/v1/validate_jwt_token")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_ValidateJwtToken_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_ValidateJwtToken_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthorizerService_ValidateSession_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, "/authorizer.v1.AuthorizerService/ValidateSession", runtime.WithHTTPPathPattern("/v1/validate_session")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_ValidateSession_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_ValidateSession_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AuthorizerService_Meta_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, "/authorizer.v1.AuthorizerService/Meta", runtime.WithHTTPPathPattern("/v1/meta")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_Meta_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_Meta_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_AuthorizerService_Permissions_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, "/authorizer.v1.AuthorizerService/Permissions", runtime.WithHTTPPathPattern("/v1/permissions")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthorizerService_Permissions_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthorizerService_Permissions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_AuthorizerService_Signup_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "signup"}, "")) + + pattern_AuthorizerService_Login_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "login"}, "")) + + pattern_AuthorizerService_Logout_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "logout"}, "")) + + pattern_AuthorizerService_MagicLinkLogin_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "magic_link_login"}, "")) + + pattern_AuthorizerService_VerifyEmail_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "verify_email"}, "")) + + pattern_AuthorizerService_ResendVerifyEmail_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "resend_verify_email"}, "")) + + pattern_AuthorizerService_VerifyOtp_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "verify_otp"}, "")) + + pattern_AuthorizerService_ResendOtp_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "resend_otp"}, "")) + + pattern_AuthorizerService_ForgotPassword_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "forgot_password"}, "")) + + pattern_AuthorizerService_ResetPassword_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "reset_password"}, "")) + + pattern_AuthorizerService_Profile_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "profile"}, "")) + + pattern_AuthorizerService_UpdateProfile_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "update_profile"}, "")) + + pattern_AuthorizerService_DeactivateAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "deactivate_account"}, "")) + + pattern_AuthorizerService_Revoke_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "revoke"}, "")) + + pattern_AuthorizerService_Session_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "session"}, "")) + + pattern_AuthorizerService_ValidateJwtToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "validate_jwt_token"}, "")) + + pattern_AuthorizerService_ValidateSession_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "validate_session"}, "")) + + pattern_AuthorizerService_Meta_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "meta"}, "")) + + pattern_AuthorizerService_Permissions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "permissions"}, "")) +) + +var ( + forward_AuthorizerService_Signup_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_Login_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_Logout_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_MagicLinkLogin_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_VerifyEmail_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_ResendVerifyEmail_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_VerifyOtp_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_ResendOtp_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_ForgotPassword_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_ResetPassword_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_Profile_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_UpdateProfile_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_DeactivateAccount_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_Revoke_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_Session_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_ValidateJwtToken_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_ValidateSession_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_Meta_0 = runtime.ForwardResponseMessage + + forward_AuthorizerService_Permissions_0 = runtime.ForwardResponseMessage +) diff --git a/gen/go/authorizer/v1/authorizer_grpc.pb.go b/gen/go/authorizer/v1/authorizer_grpc.pb.go new file mode 100644 index 00000000..14bf3b49 --- /dev/null +++ b/gen/go/authorizer/v1/authorizer_grpc.pb.go @@ -0,0 +1,850 @@ +// AuthorizerService is the single gRPC service that exposes Authorizer's +// public API. Method names match the GraphQL operation names 1:1 +// (snake_case in GraphQL → PascalCase in proto): Signup, Login, +// MagicLinkLogin, VerifyEmail, ResendVerifyEmail, ForgotPassword, +// ResetPassword, VerifyOtp, ResendOtp, UpdateProfile, DeactivateAccount, +// Revoke, Meta, Session, Profile, ValidateJwtToken, ValidateSession, +// Permissions, Logout. +// +// Why one service: clients consume a single typed client per language, +// discovery is trivial, and the surface mirrors the GraphQL one users +// already know. The trade-off is that we lose resource-oriented evolution +// (no `List/Get/Create` symmetry per resource) — acceptable for an auth +// surface where most operations are stateless verbs anyway. +// +// REST mapping follows a simple rule: +// - GET /v1/{method} when the request body is empty (Meta, Profile, +// Permissions, Logout) +// - POST /v1/{method} otherwise + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc (unknown) +// source: authorizer/v1/authorizer.proto + +package authorizerv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + AuthorizerService_Signup_FullMethodName = "/authorizer.v1.AuthorizerService/Signup" + AuthorizerService_Login_FullMethodName = "/authorizer.v1.AuthorizerService/Login" + AuthorizerService_Logout_FullMethodName = "/authorizer.v1.AuthorizerService/Logout" + AuthorizerService_MagicLinkLogin_FullMethodName = "/authorizer.v1.AuthorizerService/MagicLinkLogin" + AuthorizerService_VerifyEmail_FullMethodName = "/authorizer.v1.AuthorizerService/VerifyEmail" + AuthorizerService_ResendVerifyEmail_FullMethodName = "/authorizer.v1.AuthorizerService/ResendVerifyEmail" + AuthorizerService_VerifyOtp_FullMethodName = "/authorizer.v1.AuthorizerService/VerifyOtp" + AuthorizerService_ResendOtp_FullMethodName = "/authorizer.v1.AuthorizerService/ResendOtp" + AuthorizerService_ForgotPassword_FullMethodName = "/authorizer.v1.AuthorizerService/ForgotPassword" + AuthorizerService_ResetPassword_FullMethodName = "/authorizer.v1.AuthorizerService/ResetPassword" + AuthorizerService_Profile_FullMethodName = "/authorizer.v1.AuthorizerService/Profile" + AuthorizerService_UpdateProfile_FullMethodName = "/authorizer.v1.AuthorizerService/UpdateProfile" + AuthorizerService_DeactivateAccount_FullMethodName = "/authorizer.v1.AuthorizerService/DeactivateAccount" + AuthorizerService_Revoke_FullMethodName = "/authorizer.v1.AuthorizerService/Revoke" + AuthorizerService_Session_FullMethodName = "/authorizer.v1.AuthorizerService/Session" + AuthorizerService_ValidateJwtToken_FullMethodName = "/authorizer.v1.AuthorizerService/ValidateJwtToken" + AuthorizerService_ValidateSession_FullMethodName = "/authorizer.v1.AuthorizerService/ValidateSession" + AuthorizerService_Meta_FullMethodName = "/authorizer.v1.AuthorizerService/Meta" + AuthorizerService_Permissions_FullMethodName = "/authorizer.v1.AuthorizerService/Permissions" +) + +// AuthorizerServiceClient is the client API for AuthorizerService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AuthorizerServiceClient interface { + // Signup registers a new user. Public; requires sign-up enabled in config. + // Returns AuthResponse with tokens + (browser callers) Set-Cookie headers. + Signup(ctx context.Context, in *SignupRequest, opts ...grpc.CallOption) (*SignupResponse, error) + // Login authenticates with email/phone + password. + Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) + // Logout ends the caller's current session. + Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*LogoutResponse, error) + // MagicLinkLogin dispatches a passwordless email link. The clicked link + // hits the existing /verify_email browser handler. + MagicLinkLogin(ctx context.Context, in *MagicLinkLoginRequest, opts ...grpc.CallOption) (*MagicLinkLoginResponse, error) + VerifyEmail(ctx context.Context, in *VerifyEmailRequest, opts ...grpc.CallOption) (*VerifyEmailResponse, error) + ResendVerifyEmail(ctx context.Context, in *ResendVerifyEmailRequest, opts ...grpc.CallOption) (*ResendVerifyEmailResponse, error) + VerifyOtp(ctx context.Context, in *VerifyOtpRequest, opts ...grpc.CallOption) (*VerifyOtpResponse, error) + ResendOtp(ctx context.Context, in *ResendOtpRequest, opts ...grpc.CallOption) (*ResendOtpResponse, error) + ForgotPassword(ctx context.Context, in *ForgotPasswordRequest, opts ...grpc.CallOption) (*ForgotPasswordResponse, error) + ResetPassword(ctx context.Context, in *ResetPasswordRequest, opts ...grpc.CallOption) (*ResetPasswordResponse, error) + // Profile returns the authenticated user. + Profile(ctx context.Context, in *ProfileRequest, opts ...grpc.CallOption) (*ProfileResponse, error) + UpdateProfile(ctx context.Context, in *UpdateProfileRequest, opts ...grpc.CallOption) (*UpdateProfileResponse, error) + // DeactivateAccount soft-deletes the caller's account and revokes all + // refresh tokens as a side effect. OAuth has no concept of account + // deactivation; this is the typed equivalent of SCIM PATCH active=false. + DeactivateAccount(ctx context.Context, in *DeactivateAccountRequest, opts ...grpc.CallOption) (*DeactivateAccountResponse, error) + // Revoke invalidates a refresh token. Typed mirror of RFC 7009. + Revoke(ctx context.Context, in *RevokeRequest, opts ...grpc.CallOption) (*RevokeResponse, error) + // Session returns the AuthResponse bound to the caller's cookie/bearer. + Session(ctx context.Context, in *SessionRequest, opts ...grpc.CallOption) (*SessionResponse, error) + ValidateJwtToken(ctx context.Context, in *ValidateJwtTokenRequest, opts ...grpc.CallOption) (*ValidateJwtTokenResponse, error) + ValidateSession(ctx context.Context, in *ValidateSessionRequest, opts ...grpc.CallOption) (*ValidateSessionResponse, error) + // Meta returns server feature flags. No auth required. + Meta(ctx context.Context, in *MetaRequest, opts ...grpc.CallOption) (*MetaResponse, error) + // Permissions returns the caller's effective (resource, scope) pairs. + Permissions(ctx context.Context, in *PermissionsRequest, opts ...grpc.CallOption) (*PermissionsResponse, error) +} + +type authorizerServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAuthorizerServiceClient(cc grpc.ClientConnInterface) AuthorizerServiceClient { + return &authorizerServiceClient{cc} +} + +func (c *authorizerServiceClient) Signup(ctx context.Context, in *SignupRequest, opts ...grpc.CallOption) (*SignupResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SignupResponse) + err := c.cc.Invoke(ctx, AuthorizerService_Signup_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(LoginResponse) + err := c.cc.Invoke(ctx, AuthorizerService_Login_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*LogoutResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(LogoutResponse) + err := c.cc.Invoke(ctx, AuthorizerService_Logout_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) MagicLinkLogin(ctx context.Context, in *MagicLinkLoginRequest, opts ...grpc.CallOption) (*MagicLinkLoginResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MagicLinkLoginResponse) + err := c.cc.Invoke(ctx, AuthorizerService_MagicLinkLogin_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) VerifyEmail(ctx context.Context, in *VerifyEmailRequest, opts ...grpc.CallOption) (*VerifyEmailResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(VerifyEmailResponse) + err := c.cc.Invoke(ctx, AuthorizerService_VerifyEmail_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) ResendVerifyEmail(ctx context.Context, in *ResendVerifyEmailRequest, opts ...grpc.CallOption) (*ResendVerifyEmailResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResendVerifyEmailResponse) + err := c.cc.Invoke(ctx, AuthorizerService_ResendVerifyEmail_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) VerifyOtp(ctx context.Context, in *VerifyOtpRequest, opts ...grpc.CallOption) (*VerifyOtpResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(VerifyOtpResponse) + err := c.cc.Invoke(ctx, AuthorizerService_VerifyOtp_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) ResendOtp(ctx context.Context, in *ResendOtpRequest, opts ...grpc.CallOption) (*ResendOtpResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResendOtpResponse) + err := c.cc.Invoke(ctx, AuthorizerService_ResendOtp_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) ForgotPassword(ctx context.Context, in *ForgotPasswordRequest, opts ...grpc.CallOption) (*ForgotPasswordResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ForgotPasswordResponse) + err := c.cc.Invoke(ctx, AuthorizerService_ForgotPassword_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) ResetPassword(ctx context.Context, in *ResetPasswordRequest, opts ...grpc.CallOption) (*ResetPasswordResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResetPasswordResponse) + err := c.cc.Invoke(ctx, AuthorizerService_ResetPassword_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) Profile(ctx context.Context, in *ProfileRequest, opts ...grpc.CallOption) (*ProfileResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ProfileResponse) + err := c.cc.Invoke(ctx, AuthorizerService_Profile_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) UpdateProfile(ctx context.Context, in *UpdateProfileRequest, opts ...grpc.CallOption) (*UpdateProfileResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UpdateProfileResponse) + err := c.cc.Invoke(ctx, AuthorizerService_UpdateProfile_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) DeactivateAccount(ctx context.Context, in *DeactivateAccountRequest, opts ...grpc.CallOption) (*DeactivateAccountResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DeactivateAccountResponse) + err := c.cc.Invoke(ctx, AuthorizerService_DeactivateAccount_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) Revoke(ctx context.Context, in *RevokeRequest, opts ...grpc.CallOption) (*RevokeResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RevokeResponse) + err := c.cc.Invoke(ctx, AuthorizerService_Revoke_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) Session(ctx context.Context, in *SessionRequest, opts ...grpc.CallOption) (*SessionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SessionResponse) + err := c.cc.Invoke(ctx, AuthorizerService_Session_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) ValidateJwtToken(ctx context.Context, in *ValidateJwtTokenRequest, opts ...grpc.CallOption) (*ValidateJwtTokenResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ValidateJwtTokenResponse) + err := c.cc.Invoke(ctx, AuthorizerService_ValidateJwtToken_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) ValidateSession(ctx context.Context, in *ValidateSessionRequest, opts ...grpc.CallOption) (*ValidateSessionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ValidateSessionResponse) + err := c.cc.Invoke(ctx, AuthorizerService_ValidateSession_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) Meta(ctx context.Context, in *MetaRequest, opts ...grpc.CallOption) (*MetaResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MetaResponse) + err := c.cc.Invoke(ctx, AuthorizerService_Meta_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authorizerServiceClient) Permissions(ctx context.Context, in *PermissionsRequest, opts ...grpc.CallOption) (*PermissionsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(PermissionsResponse) + err := c.cc.Invoke(ctx, AuthorizerService_Permissions_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AuthorizerServiceServer is the server API for AuthorizerService service. +// All implementations should embed UnimplementedAuthorizerServiceServer +// for forward compatibility. +type AuthorizerServiceServer interface { + // Signup registers a new user. Public; requires sign-up enabled in config. + // Returns AuthResponse with tokens + (browser callers) Set-Cookie headers. + Signup(context.Context, *SignupRequest) (*SignupResponse, error) + // Login authenticates with email/phone + password. + Login(context.Context, *LoginRequest) (*LoginResponse, error) + // Logout ends the caller's current session. + Logout(context.Context, *LogoutRequest) (*LogoutResponse, error) + // MagicLinkLogin dispatches a passwordless email link. The clicked link + // hits the existing /verify_email browser handler. + MagicLinkLogin(context.Context, *MagicLinkLoginRequest) (*MagicLinkLoginResponse, error) + VerifyEmail(context.Context, *VerifyEmailRequest) (*VerifyEmailResponse, error) + ResendVerifyEmail(context.Context, *ResendVerifyEmailRequest) (*ResendVerifyEmailResponse, error) + VerifyOtp(context.Context, *VerifyOtpRequest) (*VerifyOtpResponse, error) + ResendOtp(context.Context, *ResendOtpRequest) (*ResendOtpResponse, error) + ForgotPassword(context.Context, *ForgotPasswordRequest) (*ForgotPasswordResponse, error) + ResetPassword(context.Context, *ResetPasswordRequest) (*ResetPasswordResponse, error) + // Profile returns the authenticated user. + Profile(context.Context, *ProfileRequest) (*ProfileResponse, error) + UpdateProfile(context.Context, *UpdateProfileRequest) (*UpdateProfileResponse, error) + // DeactivateAccount soft-deletes the caller's account and revokes all + // refresh tokens as a side effect. OAuth has no concept of account + // deactivation; this is the typed equivalent of SCIM PATCH active=false. + DeactivateAccount(context.Context, *DeactivateAccountRequest) (*DeactivateAccountResponse, error) + // Revoke invalidates a refresh token. Typed mirror of RFC 7009. + Revoke(context.Context, *RevokeRequest) (*RevokeResponse, error) + // Session returns the AuthResponse bound to the caller's cookie/bearer. + Session(context.Context, *SessionRequest) (*SessionResponse, error) + ValidateJwtToken(context.Context, *ValidateJwtTokenRequest) (*ValidateJwtTokenResponse, error) + ValidateSession(context.Context, *ValidateSessionRequest) (*ValidateSessionResponse, error) + // Meta returns server feature flags. No auth required. + Meta(context.Context, *MetaRequest) (*MetaResponse, error) + // Permissions returns the caller's effective (resource, scope) pairs. + Permissions(context.Context, *PermissionsRequest) (*PermissionsResponse, error) +} + +// UnimplementedAuthorizerServiceServer should be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedAuthorizerServiceServer struct{} + +func (UnimplementedAuthorizerServiceServer) Signup(context.Context, *SignupRequest) (*SignupResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Signup not implemented") +} +func (UnimplementedAuthorizerServiceServer) Login(context.Context, *LoginRequest) (*LoginResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Login not implemented") +} +func (UnimplementedAuthorizerServiceServer) Logout(context.Context, *LogoutRequest) (*LogoutResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Logout not implemented") +} +func (UnimplementedAuthorizerServiceServer) MagicLinkLogin(context.Context, *MagicLinkLoginRequest) (*MagicLinkLoginResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MagicLinkLogin not implemented") +} +func (UnimplementedAuthorizerServiceServer) VerifyEmail(context.Context, *VerifyEmailRequest) (*VerifyEmailResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method VerifyEmail not implemented") +} +func (UnimplementedAuthorizerServiceServer) ResendVerifyEmail(context.Context, *ResendVerifyEmailRequest) (*ResendVerifyEmailResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResendVerifyEmail not implemented") +} +func (UnimplementedAuthorizerServiceServer) VerifyOtp(context.Context, *VerifyOtpRequest) (*VerifyOtpResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method VerifyOtp not implemented") +} +func (UnimplementedAuthorizerServiceServer) ResendOtp(context.Context, *ResendOtpRequest) (*ResendOtpResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResendOtp not implemented") +} +func (UnimplementedAuthorizerServiceServer) ForgotPassword(context.Context, *ForgotPasswordRequest) (*ForgotPasswordResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ForgotPassword not implemented") +} +func (UnimplementedAuthorizerServiceServer) ResetPassword(context.Context, *ResetPasswordRequest) (*ResetPasswordResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResetPassword not implemented") +} +func (UnimplementedAuthorizerServiceServer) Profile(context.Context, *ProfileRequest) (*ProfileResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Profile not implemented") +} +func (UnimplementedAuthorizerServiceServer) UpdateProfile(context.Context, *UpdateProfileRequest) (*UpdateProfileResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateProfile not implemented") +} +func (UnimplementedAuthorizerServiceServer) DeactivateAccount(context.Context, *DeactivateAccountRequest) (*DeactivateAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeactivateAccount not implemented") +} +func (UnimplementedAuthorizerServiceServer) Revoke(context.Context, *RevokeRequest) (*RevokeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Revoke not implemented") +} +func (UnimplementedAuthorizerServiceServer) Session(context.Context, *SessionRequest) (*SessionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Session not implemented") +} +func (UnimplementedAuthorizerServiceServer) ValidateJwtToken(context.Context, *ValidateJwtTokenRequest) (*ValidateJwtTokenResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ValidateJwtToken not implemented") +} +func (UnimplementedAuthorizerServiceServer) ValidateSession(context.Context, *ValidateSessionRequest) (*ValidateSessionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ValidateSession not implemented") +} +func (UnimplementedAuthorizerServiceServer) Meta(context.Context, *MetaRequest) (*MetaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Meta not implemented") +} +func (UnimplementedAuthorizerServiceServer) Permissions(context.Context, *PermissionsRequest) (*PermissionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Permissions not implemented") +} +func (UnimplementedAuthorizerServiceServer) testEmbeddedByValue() {} + +// UnsafeAuthorizerServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AuthorizerServiceServer will +// result in compilation errors. +type UnsafeAuthorizerServiceServer interface { + mustEmbedUnimplementedAuthorizerServiceServer() +} + +func RegisterAuthorizerServiceServer(s grpc.ServiceRegistrar, srv AuthorizerServiceServer) { + // If the following call pancis, it indicates UnimplementedAuthorizerServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&AuthorizerService_ServiceDesc, srv) +} + +func _AuthorizerService_Signup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SignupRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).Signup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_Signup_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).Signup(ctx, req.(*SignupRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LoginRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).Login(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_Login_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).Login(ctx, req.(*LoginRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_Logout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LogoutRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).Logout(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_Logout_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).Logout(ctx, req.(*LogoutRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_MagicLinkLogin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MagicLinkLoginRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).MagicLinkLogin(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_MagicLinkLogin_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).MagicLinkLogin(ctx, req.(*MagicLinkLoginRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_VerifyEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyEmailRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).VerifyEmail(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_VerifyEmail_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).VerifyEmail(ctx, req.(*VerifyEmailRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_ResendVerifyEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResendVerifyEmailRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).ResendVerifyEmail(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_ResendVerifyEmail_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).ResendVerifyEmail(ctx, req.(*ResendVerifyEmailRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_VerifyOtp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyOtpRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).VerifyOtp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_VerifyOtp_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).VerifyOtp(ctx, req.(*VerifyOtpRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_ResendOtp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResendOtpRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).ResendOtp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_ResendOtp_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).ResendOtp(ctx, req.(*ResendOtpRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_ForgotPassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ForgotPasswordRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).ForgotPassword(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_ForgotPassword_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).ForgotPassword(ctx, req.(*ForgotPasswordRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_ResetPassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResetPasswordRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).ResetPassword(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_ResetPassword_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).ResetPassword(ctx, req.(*ResetPasswordRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_Profile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ProfileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).Profile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_Profile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).Profile(ctx, req.(*ProfileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_UpdateProfile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateProfileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).UpdateProfile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_UpdateProfile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).UpdateProfile(ctx, req.(*UpdateProfileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_DeactivateAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeactivateAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).DeactivateAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_DeactivateAccount_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).DeactivateAccount(ctx, req.(*DeactivateAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_Revoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RevokeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).Revoke(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_Revoke_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).Revoke(ctx, req.(*RevokeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_Session_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).Session(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_Session_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).Session(ctx, req.(*SessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_ValidateJwtToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ValidateJwtTokenRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).ValidateJwtToken(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_ValidateJwtToken_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).ValidateJwtToken(ctx, req.(*ValidateJwtTokenRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_ValidateSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ValidateSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).ValidateSession(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_ValidateSession_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).ValidateSession(ctx, req.(*ValidateSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_Meta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MetaRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).Meta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_Meta_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).Meta(ctx, req.(*MetaRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthorizerService_Permissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PermissionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthorizerServiceServer).Permissions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthorizerService_Permissions_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthorizerServiceServer).Permissions(ctx, req.(*PermissionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// AuthorizerService_ServiceDesc is the grpc.ServiceDesc for AuthorizerService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AuthorizerService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "authorizer.v1.AuthorizerService", + HandlerType: (*AuthorizerServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Signup", + Handler: _AuthorizerService_Signup_Handler, + }, + { + MethodName: "Login", + Handler: _AuthorizerService_Login_Handler, + }, + { + MethodName: "Logout", + Handler: _AuthorizerService_Logout_Handler, + }, + { + MethodName: "MagicLinkLogin", + Handler: _AuthorizerService_MagicLinkLogin_Handler, + }, + { + MethodName: "VerifyEmail", + Handler: _AuthorizerService_VerifyEmail_Handler, + }, + { + MethodName: "ResendVerifyEmail", + Handler: _AuthorizerService_ResendVerifyEmail_Handler, + }, + { + MethodName: "VerifyOtp", + Handler: _AuthorizerService_VerifyOtp_Handler, + }, + { + MethodName: "ResendOtp", + Handler: _AuthorizerService_ResendOtp_Handler, + }, + { + MethodName: "ForgotPassword", + Handler: _AuthorizerService_ForgotPassword_Handler, + }, + { + MethodName: "ResetPassword", + Handler: _AuthorizerService_ResetPassword_Handler, + }, + { + MethodName: "Profile", + Handler: _AuthorizerService_Profile_Handler, + }, + { + MethodName: "UpdateProfile", + Handler: _AuthorizerService_UpdateProfile_Handler, + }, + { + MethodName: "DeactivateAccount", + Handler: _AuthorizerService_DeactivateAccount_Handler, + }, + { + MethodName: "Revoke", + Handler: _AuthorizerService_Revoke_Handler, + }, + { + MethodName: "Session", + Handler: _AuthorizerService_Session_Handler, + }, + { + MethodName: "ValidateJwtToken", + Handler: _AuthorizerService_ValidateJwtToken_Handler, + }, + { + MethodName: "ValidateSession", + Handler: _AuthorizerService_ValidateSession_Handler, + }, + { + MethodName: "Meta", + Handler: _AuthorizerService_Meta_Handler, + }, + { + MethodName: "Permissions", + Handler: _AuthorizerService_Permissions_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "authorizer/v1/authorizer.proto", +} diff --git a/gen/go/authorizer/v1/types.pb.go b/gen/go/authorizer/v1/types.pb.go new file mode 100644 index 00000000..0a935e3d --- /dev/null +++ b/gen/go/authorizer/v1/types.pb.go @@ -0,0 +1,913 @@ +// Shared message types used by the Authorizer service. Field naming mirrors +// the GraphQL schema 1:1 so REST/gRPC clients see the same shape. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.2 +// protoc (unknown) +// source: authorizer/v1/types.proto + +package authorizerv1 + +import ( + v1 "github.com/authorizerdev/authorizer/gen/go/authorizer/common/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// User mirrors the GraphQL User type. Returned by Profile and embedded in +// AuthResponse. +type User struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Either email or phone_number is always present. + Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + EmailVerified bool `protobuf:"varint,3,opt,name=email_verified,json=emailVerified,proto3" json:"email_verified,omitempty"` + SignupMethods string `protobuf:"bytes,4,opt,name=signup_methods,json=signupMethods,proto3" json:"signup_methods,omitempty"` + GivenName string `protobuf:"bytes,5,opt,name=given_name,json=givenName,proto3" json:"given_name,omitempty"` + FamilyName string `protobuf:"bytes,6,opt,name=family_name,json=familyName,proto3" json:"family_name,omitempty"` + MiddleName string `protobuf:"bytes,7,opt,name=middle_name,json=middleName,proto3" json:"middle_name,omitempty"` + Nickname string `protobuf:"bytes,8,opt,name=nickname,proto3" json:"nickname,omitempty"` + // Defaults to email when unset. + PreferredUsername string `protobuf:"bytes,9,opt,name=preferred_username,json=preferredUsername,proto3" json:"preferred_username,omitempty"` + Gender string `protobuf:"bytes,10,opt,name=gender,proto3" json:"gender,omitempty"` + Birthdate string `protobuf:"bytes,11,opt,name=birthdate,proto3" json:"birthdate,omitempty"` + PhoneNumber string `protobuf:"bytes,12,opt,name=phone_number,json=phoneNumber,proto3" json:"phone_number,omitempty"` + PhoneNumberVerified bool `protobuf:"varint,13,opt,name=phone_number_verified,json=phoneNumberVerified,proto3" json:"phone_number_verified,omitempty"` + Picture string `protobuf:"bytes,14,opt,name=picture,proto3" json:"picture,omitempty"` + Roles []string `protobuf:"bytes,15,rep,name=roles,proto3" json:"roles,omitempty"` + CreatedAt int64 `protobuf:"varint,16,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt int64 `protobuf:"varint,17,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + RevokedTimestamp int64 `protobuf:"varint,18,opt,name=revoked_timestamp,json=revokedTimestamp,proto3" json:"revoked_timestamp,omitempty"` + IsMultiFactorAuthEnabled bool `protobuf:"varint,19,opt,name=is_multi_factor_auth_enabled,json=isMultiFactorAuthEnabled,proto3" json:"is_multi_factor_auth_enabled,omitempty"` + // Free-form key/value bag — same as GraphQL `app_data: Map`. + AppData *v1.AppData `protobuf:"bytes,20,opt,name=app_data,json=appData,proto3" json:"app_data,omitempty"` +} + +func (x *User) Reset() { + *x = User{} + mi := &file_authorizer_v1_types_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User) ProtoMessage() {} + +func (x *User) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_types_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use User.ProtoReflect.Descriptor instead. +func (*User) Descriptor() ([]byte, []int) { + return file_authorizer_v1_types_proto_rawDescGZIP(), []int{0} +} + +func (x *User) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *User) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *User) GetEmailVerified() bool { + if x != nil { + return x.EmailVerified + } + return false +} + +func (x *User) GetSignupMethods() string { + if x != nil { + return x.SignupMethods + } + return "" +} + +func (x *User) GetGivenName() string { + if x != nil { + return x.GivenName + } + return "" +} + +func (x *User) GetFamilyName() string { + if x != nil { + return x.FamilyName + } + return "" +} + +func (x *User) GetMiddleName() string { + if x != nil { + return x.MiddleName + } + return "" +} + +func (x *User) GetNickname() string { + if x != nil { + return x.Nickname + } + return "" +} + +func (x *User) GetPreferredUsername() string { + if x != nil { + return x.PreferredUsername + } + return "" +} + +func (x *User) GetGender() string { + if x != nil { + return x.Gender + } + return "" +} + +func (x *User) GetBirthdate() string { + if x != nil { + return x.Birthdate + } + return "" +} + +func (x *User) GetPhoneNumber() string { + if x != nil { + return x.PhoneNumber + } + return "" +} + +func (x *User) GetPhoneNumberVerified() bool { + if x != nil { + return x.PhoneNumberVerified + } + return false +} + +func (x *User) GetPicture() string { + if x != nil { + return x.Picture + } + return "" +} + +func (x *User) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +func (x *User) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *User) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +func (x *User) GetRevokedTimestamp() int64 { + if x != nil { + return x.RevokedTimestamp + } + return 0 +} + +func (x *User) GetIsMultiFactorAuthEnabled() bool { + if x != nil { + return x.IsMultiFactorAuthEnabled + } + return false +} + +func (x *User) GetAppData() *v1.AppData { + if x != nil { + return x.AppData + } + return nil +} + +// AuthResponse mirrors the GraphQL AuthResponse type. Returned (wrapped) by +// every method that produces a session: Signup, Login, MagicLinkLogin, +// VerifyEmail, VerifyOtp, Session. +type AuthResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + ShouldShowEmailOtpScreen bool `protobuf:"varint,2,opt,name=should_show_email_otp_screen,json=shouldShowEmailOtpScreen,proto3" json:"should_show_email_otp_screen,omitempty"` + ShouldShowMobileOtpScreen bool `protobuf:"varint,3,opt,name=should_show_mobile_otp_screen,json=shouldShowMobileOtpScreen,proto3" json:"should_show_mobile_otp_screen,omitempty"` + ShouldShowTotpScreen bool `protobuf:"varint,4,opt,name=should_show_totp_screen,json=shouldShowTotpScreen,proto3" json:"should_show_totp_screen,omitempty"` + AccessToken string `protobuf:"bytes,5,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` + IdToken string `protobuf:"bytes,6,opt,name=id_token,json=idToken,proto3" json:"id_token,omitempty"` + RefreshToken string `protobuf:"bytes,7,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"` + ExpiresIn int64 `protobuf:"varint,8,opt,name=expires_in,json=expiresIn,proto3" json:"expires_in,omitempty"` + User *User `protobuf:"bytes,9,opt,name=user,proto3" json:"user,omitempty"` + // TOTP enrolment artifacts (populated only when this AuthResponse + // initiates TOTP setup; one-time, never re-shown). + AuthenticatorScannerImage string `protobuf:"bytes,10,opt,name=authenticator_scanner_image,json=authenticatorScannerImage,proto3" json:"authenticator_scanner_image,omitempty"` + AuthenticatorSecret string `protobuf:"bytes,11,opt,name=authenticator_secret,json=authenticatorSecret,proto3" json:"authenticator_secret,omitempty"` + AuthenticatorRecoveryCodes []string `protobuf:"bytes,12,rep,name=authenticator_recovery_codes,json=authenticatorRecoveryCodes,proto3" json:"authenticator_recovery_codes,omitempty"` +} + +func (x *AuthResponse) Reset() { + *x = AuthResponse{} + mi := &file_authorizer_v1_types_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AuthResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthResponse) ProtoMessage() {} + +func (x *AuthResponse) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_types_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthResponse.ProtoReflect.Descriptor instead. +func (*AuthResponse) Descriptor() ([]byte, []int) { + return file_authorizer_v1_types_proto_rawDescGZIP(), []int{1} +} + +func (x *AuthResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *AuthResponse) GetShouldShowEmailOtpScreen() bool { + if x != nil { + return x.ShouldShowEmailOtpScreen + } + return false +} + +func (x *AuthResponse) GetShouldShowMobileOtpScreen() bool { + if x != nil { + return x.ShouldShowMobileOtpScreen + } + return false +} + +func (x *AuthResponse) GetShouldShowTotpScreen() bool { + if x != nil { + return x.ShouldShowTotpScreen + } + return false +} + +func (x *AuthResponse) GetAccessToken() string { + if x != nil { + return x.AccessToken + } + return "" +} + +func (x *AuthResponse) GetIdToken() string { + if x != nil { + return x.IdToken + } + return "" +} + +func (x *AuthResponse) GetRefreshToken() string { + if x != nil { + return x.RefreshToken + } + return "" +} + +func (x *AuthResponse) GetExpiresIn() int64 { + if x != nil { + return x.ExpiresIn + } + return 0 +} + +func (x *AuthResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +func (x *AuthResponse) GetAuthenticatorScannerImage() string { + if x != nil { + return x.AuthenticatorScannerImage + } + return "" +} + +func (x *AuthResponse) GetAuthenticatorSecret() string { + if x != nil { + return x.AuthenticatorSecret + } + return "" +} + +func (x *AuthResponse) GetAuthenticatorRecoveryCodes() []string { + if x != nil { + return x.AuthenticatorRecoveryCodes + } + return nil +} + +// Permission is one (resource, scope) pair the caller is allowed to act on. +type Permission struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` + Scope string `protobuf:"bytes,2,opt,name=scope,proto3" json:"scope,omitempty"` +} + +func (x *Permission) Reset() { + *x = Permission{} + mi := &file_authorizer_v1_types_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Permission) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Permission) ProtoMessage() {} + +func (x *Permission) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_types_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Permission.ProtoReflect.Descriptor instead. +func (*Permission) Descriptor() ([]byte, []int) { + return file_authorizer_v1_types_proto_rawDescGZIP(), []int{2} +} + +func (x *Permission) GetResource() string { + if x != nil { + return x.Resource + } + return "" +} + +func (x *Permission) GetScope() string { + if x != nil { + return x.Scope + } + return "" +} + +// PermissionInput is the request-side mirror of Permission used by +// methods that take a list of required permissions. +type PermissionInput struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` + Scope string `protobuf:"bytes,2,opt,name=scope,proto3" json:"scope,omitempty"` +} + +func (x *PermissionInput) Reset() { + *x = PermissionInput{} + mi := &file_authorizer_v1_types_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PermissionInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PermissionInput) ProtoMessage() {} + +func (x *PermissionInput) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_types_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PermissionInput.ProtoReflect.Descriptor instead. +func (*PermissionInput) Descriptor() ([]byte, []int) { + return file_authorizer_v1_types_proto_rawDescGZIP(), []int{3} +} + +func (x *PermissionInput) GetResource() string { + if x != nil { + return x.Resource + } + return "" +} + +func (x *PermissionInput) GetScope() string { + if x != nil { + return x.Scope + } + return "" +} + +// Meta mirrors the GraphQL Meta type — server feature flags + provider +// availability, returned by the Meta query. +type Meta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + IsGoogleLoginEnabled bool `protobuf:"varint,3,opt,name=is_google_login_enabled,json=isGoogleLoginEnabled,proto3" json:"is_google_login_enabled,omitempty"` + IsFacebookLoginEnabled bool `protobuf:"varint,4,opt,name=is_facebook_login_enabled,json=isFacebookLoginEnabled,proto3" json:"is_facebook_login_enabled,omitempty"` + IsGithubLoginEnabled bool `protobuf:"varint,5,opt,name=is_github_login_enabled,json=isGithubLoginEnabled,proto3" json:"is_github_login_enabled,omitempty"` + IsLinkedinLoginEnabled bool `protobuf:"varint,6,opt,name=is_linkedin_login_enabled,json=isLinkedinLoginEnabled,proto3" json:"is_linkedin_login_enabled,omitempty"` + IsAppleLoginEnabled bool `protobuf:"varint,7,opt,name=is_apple_login_enabled,json=isAppleLoginEnabled,proto3" json:"is_apple_login_enabled,omitempty"` + IsDiscordLoginEnabled bool `protobuf:"varint,8,opt,name=is_discord_login_enabled,json=isDiscordLoginEnabled,proto3" json:"is_discord_login_enabled,omitempty"` + IsTwitterLoginEnabled bool `protobuf:"varint,9,opt,name=is_twitter_login_enabled,json=isTwitterLoginEnabled,proto3" json:"is_twitter_login_enabled,omitempty"` + IsMicrosoftLoginEnabled bool `protobuf:"varint,10,opt,name=is_microsoft_login_enabled,json=isMicrosoftLoginEnabled,proto3" json:"is_microsoft_login_enabled,omitempty"` + IsTwitchLoginEnabled bool `protobuf:"varint,11,opt,name=is_twitch_login_enabled,json=isTwitchLoginEnabled,proto3" json:"is_twitch_login_enabled,omitempty"` + IsRobloxLoginEnabled bool `protobuf:"varint,12,opt,name=is_roblox_login_enabled,json=isRobloxLoginEnabled,proto3" json:"is_roblox_login_enabled,omitempty"` + IsEmailVerificationEnabled bool `protobuf:"varint,13,opt,name=is_email_verification_enabled,json=isEmailVerificationEnabled,proto3" json:"is_email_verification_enabled,omitempty"` + IsBasicAuthenticationEnabled bool `protobuf:"varint,14,opt,name=is_basic_authentication_enabled,json=isBasicAuthenticationEnabled,proto3" json:"is_basic_authentication_enabled,omitempty"` + IsMagicLinkLoginEnabled bool `protobuf:"varint,15,opt,name=is_magic_link_login_enabled,json=isMagicLinkLoginEnabled,proto3" json:"is_magic_link_login_enabled,omitempty"` + IsSignUpEnabled bool `protobuf:"varint,16,opt,name=is_sign_up_enabled,json=isSignUpEnabled,proto3" json:"is_sign_up_enabled,omitempty"` + IsStrongPasswordEnabled bool `protobuf:"varint,17,opt,name=is_strong_password_enabled,json=isStrongPasswordEnabled,proto3" json:"is_strong_password_enabled,omitempty"` + IsMultiFactorAuthEnabled bool `protobuf:"varint,18,opt,name=is_multi_factor_auth_enabled,json=isMultiFactorAuthEnabled,proto3" json:"is_multi_factor_auth_enabled,omitempty"` + IsMobileBasicAuthenticationEnabled bool `protobuf:"varint,19,opt,name=is_mobile_basic_authentication_enabled,json=isMobileBasicAuthenticationEnabled,proto3" json:"is_mobile_basic_authentication_enabled,omitempty"` + IsPhoneVerificationEnabled bool `protobuf:"varint,20,opt,name=is_phone_verification_enabled,json=isPhoneVerificationEnabled,proto3" json:"is_phone_verification_enabled,omitempty"` +} + +func (x *Meta) Reset() { + *x = Meta{} + mi := &file_authorizer_v1_types_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Meta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Meta) ProtoMessage() {} + +func (x *Meta) ProtoReflect() protoreflect.Message { + mi := &file_authorizer_v1_types_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Meta.ProtoReflect.Descriptor instead. +func (*Meta) Descriptor() ([]byte, []int) { + return file_authorizer_v1_types_proto_rawDescGZIP(), []int{4} +} + +func (x *Meta) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *Meta) GetClientId() string { + if x != nil { + return x.ClientId + } + return "" +} + +func (x *Meta) GetIsGoogleLoginEnabled() bool { + if x != nil { + return x.IsGoogleLoginEnabled + } + return false +} + +func (x *Meta) GetIsFacebookLoginEnabled() bool { + if x != nil { + return x.IsFacebookLoginEnabled + } + return false +} + +func (x *Meta) GetIsGithubLoginEnabled() bool { + if x != nil { + return x.IsGithubLoginEnabled + } + return false +} + +func (x *Meta) GetIsLinkedinLoginEnabled() bool { + if x != nil { + return x.IsLinkedinLoginEnabled + } + return false +} + +func (x *Meta) GetIsAppleLoginEnabled() bool { + if x != nil { + return x.IsAppleLoginEnabled + } + return false +} + +func (x *Meta) GetIsDiscordLoginEnabled() bool { + if x != nil { + return x.IsDiscordLoginEnabled + } + return false +} + +func (x *Meta) GetIsTwitterLoginEnabled() bool { + if x != nil { + return x.IsTwitterLoginEnabled + } + return false +} + +func (x *Meta) GetIsMicrosoftLoginEnabled() bool { + if x != nil { + return x.IsMicrosoftLoginEnabled + } + return false +} + +func (x *Meta) GetIsTwitchLoginEnabled() bool { + if x != nil { + return x.IsTwitchLoginEnabled + } + return false +} + +func (x *Meta) GetIsRobloxLoginEnabled() bool { + if x != nil { + return x.IsRobloxLoginEnabled + } + return false +} + +func (x *Meta) GetIsEmailVerificationEnabled() bool { + if x != nil { + return x.IsEmailVerificationEnabled + } + return false +} + +func (x *Meta) GetIsBasicAuthenticationEnabled() bool { + if x != nil { + return x.IsBasicAuthenticationEnabled + } + return false +} + +func (x *Meta) GetIsMagicLinkLoginEnabled() bool { + if x != nil { + return x.IsMagicLinkLoginEnabled + } + return false +} + +func (x *Meta) GetIsSignUpEnabled() bool { + if x != nil { + return x.IsSignUpEnabled + } + return false +} + +func (x *Meta) GetIsStrongPasswordEnabled() bool { + if x != nil { + return x.IsStrongPasswordEnabled + } + return false +} + +func (x *Meta) GetIsMultiFactorAuthEnabled() bool { + if x != nil { + return x.IsMultiFactorAuthEnabled + } + return false +} + +func (x *Meta) GetIsMobileBasicAuthenticationEnabled() bool { + if x != nil { + return x.IsMobileBasicAuthenticationEnabled + } + return false +} + +func (x *Meta) GetIsPhoneVerificationEnabled() bool { + if x != nil { + return x.IsPhoneVerificationEnabled + } + return false +} + +var File_authorizer_v1_types_proto protoreflect.FileDescriptor + +var file_authorizer_v1_types_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, + 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc8, 0x05, 0x0a, + 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x5f, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, + 0x75, 0x70, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x76, + 0x65, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, + 0x69, 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x61, 0x6d, 0x69, + 0x6c, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, + 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x69, 0x64, + 0x64, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, + 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, + 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x72, 0x65, 0x64, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x11, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x55, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x1c, 0x0a, + 0x09, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, + 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x32, + 0x0a, 0x15, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x76, + 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x70, + 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, + 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x72, 0x65, 0x76, + 0x6f, 0x6b, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3e, 0x0a, + 0x1c, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, + 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x13, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x18, 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x46, 0x61, 0x63, 0x74, + 0x6f, 0x72, 0x41, 0x75, 0x74, 0x68, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x38, 0x0a, + 0x08, 0x61, 0x70, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x07, + 0x61, 0x70, 0x70, 0x44, 0x61, 0x74, 0x61, 0x22, 0xc1, 0x04, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x3e, 0x0a, 0x1c, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x73, 0x68, 0x6f, + 0x77, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x5f, 0x6f, 0x74, 0x70, 0x5f, 0x73, 0x63, 0x72, 0x65, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, + 0x53, 0x68, 0x6f, 0x77, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x4f, 0x74, 0x70, 0x53, 0x63, 0x72, 0x65, + 0x65, 0x6e, 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x73, 0x68, 0x6f, + 0x77, 0x5f, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x5f, 0x6f, 0x74, 0x70, 0x5f, 0x73, 0x63, 0x72, + 0x65, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x68, 0x6f, 0x75, 0x6c, + 0x64, 0x53, 0x68, 0x6f, 0x77, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x4f, 0x74, 0x70, 0x53, 0x63, + 0x72, 0x65, 0x65, 0x6e, 0x12, 0x35, 0x0a, 0x17, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x73, + 0x68, 0x6f, 0x77, 0x5f, 0x74, 0x6f, 0x74, 0x70, 0x5f, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x53, 0x68, 0x6f, + 0x77, 0x54, 0x6f, 0x74, 0x70, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x19, + 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x69, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, + 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x49, 0x6e, 0x12, 0x27, 0x0a, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x1b, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x5f, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x61, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x63, 0x61, 0x6e, 0x6e, 0x65, + 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x6f, 0x72, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x40, 0x0a, 0x1c, 0x61, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x1a, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x0a, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0x43, 0x0a, 0x0f, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, + 0x22, 0xfc, 0x08, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, + 0x12, 0x35, 0x0a, 0x17, 0x69, 0x73, 0x5f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5f, 0x6c, 0x6f, + 0x67, 0x69, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x14, 0x69, 0x73, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x19, 0x69, 0x73, 0x5f, 0x66, 0x61, + 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x69, 0x73, 0x46, 0x61, + 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x12, 0x35, 0x0a, 0x17, 0x69, 0x73, 0x5f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, + 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x14, 0x69, 0x73, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x19, 0x69, 0x73, 0x5f, + 0x6c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x69, 0x6e, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x69, 0x73, + 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x69, 0x6e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x69, 0x73, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x65, + 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x73, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x37, 0x0a, 0x18, 0x69, 0x73, 0x5f, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x69, 0x73, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x12, 0x37, 0x0a, 0x18, 0x69, 0x73, 0x5f, 0x74, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, + 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x69, 0x73, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x4c, + 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x69, + 0x73, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x69, + 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x17, 0x69, 0x73, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x4c, 0x6f, 0x67, 0x69, + 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x17, 0x69, 0x73, 0x5f, 0x74, + 0x77, 0x69, 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x69, 0x73, 0x54, 0x77, 0x69, + 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, + 0x35, 0x0a, 0x17, 0x69, 0x73, 0x5f, 0x72, 0x6f, 0x62, 0x6c, 0x6f, 0x78, 0x5f, 0x6c, 0x6f, 0x67, + 0x69, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x14, 0x69, 0x73, 0x52, 0x6f, 0x62, 0x6c, 0x6f, 0x78, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x69, 0x73, 0x5f, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x69, + 0x73, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x1f, 0x69, 0x73, 0x5f, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x1c, 0x69, 0x73, 0x42, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x65, + 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x12, 0x3c, 0x0a, 0x1b, 0x69, 0x73, 0x5f, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x5f, 0x6c, 0x69, 0x6e, + 0x6b, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x69, 0x73, 0x4d, 0x61, 0x67, 0x69, 0x63, 0x4c, 0x69, + 0x6e, 0x6b, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2b, + 0x0a, 0x12, 0x69, 0x73, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x73, 0x53, 0x69, + 0x67, 0x6e, 0x55, 0x70, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x69, + 0x73, 0x5f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x17, 0x69, 0x73, 0x53, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x3e, 0x0a, 0x1c, 0x69, 0x73, 0x5f, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x75, 0x74, 0x68, + 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, + 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x75, 0x74, + 0x68, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x52, 0x0a, 0x26, 0x69, 0x73, 0x5f, 0x6d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x61, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x69, 0x73, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x42, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, + 0x69, 0x73, 0x5f, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x14, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x1a, 0x69, 0x73, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x42, + 0xbb, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x54, 0x79, 0x70, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x64, 0x65, 0x76, 0x2f, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, + 0xaa, 0x02, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x56, 0x31, + 0xca, 0x02, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x5c, 0x56, 0x31, + 0xe2, 0x02, 0x19, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x5c, 0x56, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_authorizer_v1_types_proto_rawDescOnce sync.Once + file_authorizer_v1_types_proto_rawDescData = file_authorizer_v1_types_proto_rawDesc +) + +func file_authorizer_v1_types_proto_rawDescGZIP() []byte { + file_authorizer_v1_types_proto_rawDescOnce.Do(func() { + file_authorizer_v1_types_proto_rawDescData = protoimpl.X.CompressGZIP(file_authorizer_v1_types_proto_rawDescData) + }) + return file_authorizer_v1_types_proto_rawDescData +} + +var file_authorizer_v1_types_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_authorizer_v1_types_proto_goTypes = []any{ + (*User)(nil), // 0: authorizer.v1.User + (*AuthResponse)(nil), // 1: authorizer.v1.AuthResponse + (*Permission)(nil), // 2: authorizer.v1.Permission + (*PermissionInput)(nil), // 3: authorizer.v1.PermissionInput + (*Meta)(nil), // 4: authorizer.v1.Meta + (*v1.AppData)(nil), // 5: authorizer.common.v1.AppData +} +var file_authorizer_v1_types_proto_depIdxs = []int32{ + 5, // 0: authorizer.v1.User.app_data:type_name -> authorizer.common.v1.AppData + 0, // 1: authorizer.v1.AuthResponse.user:type_name -> authorizer.v1.User + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_authorizer_v1_types_proto_init() } +func file_authorizer_v1_types_proto_init() { + if File_authorizer_v1_types_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_authorizer_v1_types_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_authorizer_v1_types_proto_goTypes, + DependencyIndexes: file_authorizer_v1_types_proto_depIdxs, + MessageInfos: file_authorizer_v1_types_proto_msgTypes, + }.Build() + File_authorizer_v1_types_proto = out.File + file_authorizer_v1_types_proto_rawDesc = nil + file_authorizer_v1_types_proto_goTypes = nil + file_authorizer_v1_types_proto_depIdxs = nil +} diff --git a/gen/openapi/authorizer.swagger.json b/gen/openapi/authorizer.swagger.json new file mode 100644 index 00000000..94c00861 --- /dev/null +++ b/gen/openapi/authorizer.swagger.json @@ -0,0 +1,1370 @@ +{ + "swagger": "2.0", + "info": { + "title": "authorizer/common/v1/annotations.proto", + "version": "version not set" + }, + "tags": [ + { + "name": "AuthorizerService" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/v1/deactivate_account": { + "post": { + "summary": "DeactivateAccount soft-deletes the caller's account and revokes all\nrefresh tokens as a side effect. OAuth has no concept of account\ndeactivation; this is the typed equivalent of SCIM PATCH active=false.", + "operationId": "AuthorizerService_DeactivateAccount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1DeactivateAccountResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeactivateAccountRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/forgot_password": { + "post": { + "operationId": "AuthorizerService_ForgotPassword", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ForgotPasswordResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ForgotPasswordRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/login": { + "post": { + "summary": "Login authenticates with email/phone + password.", + "operationId": "AuthorizerService_Login", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1LoginResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1LoginRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/logout": { + "get": { + "summary": "Logout ends the caller's current session.", + "operationId": "AuthorizerService_Logout", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1LogoutResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/magic_link_login": { + "post": { + "summary": "MagicLinkLogin dispatches a passwordless email link. The clicked link\nhits the existing /verify_email browser handler.", + "operationId": "AuthorizerService_MagicLinkLogin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1MagicLinkLoginResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1MagicLinkLoginRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/meta": { + "get": { + "summary": "Meta returns server feature flags. No auth required.", + "operationId": "AuthorizerService_Meta", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1MetaResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/permissions": { + "get": { + "summary": "Permissions returns the caller's effective (resource, scope) pairs.", + "operationId": "AuthorizerService_Permissions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1PermissionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/profile": { + "get": { + "summary": "Profile returns the authenticated user.", + "operationId": "AuthorizerService_Profile", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ProfileResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/resend_otp": { + "post": { + "operationId": "AuthorizerService_ResendOtp", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ResendOtpResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ResendOtpRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/resend_verify_email": { + "post": { + "operationId": "AuthorizerService_ResendVerifyEmail", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ResendVerifyEmailResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ResendVerifyEmailRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/reset_password": { + "post": { + "operationId": "AuthorizerService_ResetPassword", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ResetPasswordResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ResetPasswordRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/revoke": { + "post": { + "summary": "Revoke invalidates a refresh token. Typed mirror of RFC 7009.", + "operationId": "AuthorizerService_Revoke", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1RevokeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1RevokeRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/session": { + "post": { + "summary": "Session returns the AuthResponse bound to the caller's cookie/bearer.", + "operationId": "AuthorizerService_Session", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1SessionResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1SessionRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/signup": { + "post": { + "summary": "Signup registers a new user. Public; requires sign-up enabled in config.\nReturns AuthResponse with tokens + (browser callers) Set-Cookie headers.", + "operationId": "AuthorizerService_Signup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1SignupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1SignupRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/update_profile": { + "post": { + "operationId": "AuthorizerService_UpdateProfile", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1UpdateProfileResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateProfileRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/validate_jwt_token": { + "post": { + "operationId": "AuthorizerService_ValidateJwtToken", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ValidateJwtTokenResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ValidateJwtTokenRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/validate_session": { + "post": { + "operationId": "AuthorizerService_ValidateSession", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ValidateSessionResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ValidateSessionRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/verify_email": { + "post": { + "operationId": "AuthorizerService_VerifyEmail", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1VerifyEmailResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1VerifyEmailRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + }, + "/v1/verify_otp": { + "post": { + "operationId": "AuthorizerService_VerifyOtp", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1VerifyOtpResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1VerifyOtpRequest" + } + } + ], + "tags": [ + "AuthorizerService" + ] + } + } + }, + "definitions": { + "authorizerv1Meta": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "is_google_login_enabled": { + "type": "boolean" + }, + "is_facebook_login_enabled": { + "type": "boolean" + }, + "is_github_login_enabled": { + "type": "boolean" + }, + "is_linkedin_login_enabled": { + "type": "boolean" + }, + "is_apple_login_enabled": { + "type": "boolean" + }, + "is_discord_login_enabled": { + "type": "boolean" + }, + "is_twitter_login_enabled": { + "type": "boolean" + }, + "is_microsoft_login_enabled": { + "type": "boolean" + }, + "is_twitch_login_enabled": { + "type": "boolean" + }, + "is_roblox_login_enabled": { + "type": "boolean" + }, + "is_email_verification_enabled": { + "type": "boolean" + }, + "is_basic_authentication_enabled": { + "type": "boolean" + }, + "is_magic_link_login_enabled": { + "type": "boolean" + }, + "is_sign_up_enabled": { + "type": "boolean" + }, + "is_strong_password_enabled": { + "type": "boolean" + }, + "is_multi_factor_auth_enabled": { + "type": "boolean" + }, + "is_mobile_basic_authentication_enabled": { + "type": "boolean" + }, + "is_phone_verification_enabled": { + "type": "boolean" + } + }, + "description": "Meta mirrors the GraphQL Meta type — server feature flags + provider\navailability, returned by the Meta query." + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "protobufNullValue": { + "type": "string", + "enum": [ + "NULL_VALUE" + ], + "default": "NULL_VALUE", + "description": "`NullValue` is a singleton enumeration to represent the null value for the\n`Value` type union.\n\nThe JSON representation for `NullValue` is JSON `null`.\n\n - NULL_VALUE: Null value." + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "v1AppData": { + "type": "object", + "properties": { + "value": { + "type": "object" + } + }, + "description": "AppData is a free-form key/value bag stored against a user. Mirrors the\nGraphQL `Map` scalar. Values are JSON-typed (string, number, bool, null,\nnested object, nested array) to match what the existing storage layer\naccepts." + }, + "v1AuthResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "should_show_email_otp_screen": { + "type": "boolean" + }, + "should_show_mobile_otp_screen": { + "type": "boolean" + }, + "should_show_totp_screen": { + "type": "boolean" + }, + "access_token": { + "type": "string" + }, + "id_token": { + "type": "string" + }, + "refresh_token": { + "type": "string" + }, + "expires_in": { + "type": "string", + "format": "int64" + }, + "user": { + "$ref": "#/definitions/v1User" + }, + "authenticator_scanner_image": { + "type": "string", + "description": "TOTP enrolment artifacts (populated only when this AuthResponse\ninitiates TOTP setup; one-time, never re-shown)." + }, + "authenticator_secret": { + "type": "string" + }, + "authenticator_recovery_codes": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "description": "AuthResponse mirrors the GraphQL AuthResponse type. Returned (wrapped) by\nevery method that produces a session: Signup, Login, MagicLinkLogin,\nVerifyEmail, VerifyOtp, Session." + }, + "v1DeactivateAccountRequest": { + "type": "object" + }, + "v1DeactivateAccountResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "v1ForgotPasswordRequest": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "phone_number": { + "type": "string" + }, + "state": { + "type": "string" + }, + "redirect_uri": { + "type": "string" + } + } + }, + "v1ForgotPasswordResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "should_show_mobile_otp_screen": { + "type": "boolean", + "description": "For SMS-driven flows the UI may need to render an OTP entry screen." + } + } + }, + "v1LoginRequest": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "phone_number": { + "type": "string" + }, + "password": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "scope": { + "type": "array", + "items": { + "type": "string" + } + }, + "state": { + "type": "string" + } + } + }, + "v1LoginResponse": { + "type": "object", + "properties": { + "auth": { + "$ref": "#/definitions/v1AuthResponse" + } + } + }, + "v1LogoutResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "v1MagicLinkLoginRequest": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "scope": { + "type": "array", + "items": { + "type": "string" + } + }, + "state": { + "type": "string" + }, + "redirect_uri": { + "type": "string" + } + } + }, + "v1MagicLinkLoginResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "v1MetaResponse": { + "type": "object", + "properties": { + "meta": { + "$ref": "#/definitions/authorizerv1Meta" + } + } + }, + "v1Permission": { + "type": "object", + "properties": { + "resource": { + "type": "string" + }, + "scope": { + "type": "string" + } + }, + "description": "Permission is one (resource, scope) pair the caller is allowed to act on." + }, + "v1PermissionInput": { + "type": "object", + "properties": { + "resource": { + "type": "string" + }, + "scope": { + "type": "string" + } + }, + "description": "PermissionInput is the request-side mirror of Permission used by\nmethods that take a list of required permissions." + }, + "v1PermissionsResponse": { + "type": "object", + "properties": { + "permissions": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Permission" + } + } + } + }, + "v1ProfileResponse": { + "type": "object", + "properties": { + "user": { + "$ref": "#/definitions/v1User" + } + } + }, + "v1ResendOtpRequest": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "phone_number": { + "type": "string" + }, + "state": { + "type": "string" + } + } + }, + "v1ResendOtpResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "v1ResendVerifyEmailRequest": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "identifier": { + "type": "string" + }, + "state": { + "type": "string" + } + } + }, + "v1ResendVerifyEmailResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "v1ResetPasswordRequest": { + "type": "object", + "properties": { + "token": { + "type": "string", + "description": "For email flows: the token from the reset email. For SMS flows: the OTP." + }, + "otp": { + "type": "string" + }, + "phone_number": { + "type": "string" + }, + "password": { + "type": "string" + }, + "confirm_password": { + "type": "string" + } + } + }, + "v1ResetPasswordResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "v1RevokeRequest": { + "type": "object", + "properties": { + "refresh_token": { + "type": "string" + } + } + }, + "v1RevokeResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "v1SessionRequest": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "scope": { + "type": "array", + "items": { + "type": "string" + } + }, + "state": { + "type": "string" + }, + "required_permissions": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PermissionInput" + }, + "description": "Optional AND-combined permission filter; deny if any is missing." + } + } + }, + "v1SessionResponse": { + "type": "object", + "properties": { + "auth": { + "$ref": "#/definitions/v1AuthResponse" + } + } + }, + "v1SignupRequest": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "phone_number": { + "type": "string" + }, + "password": { + "type": "string" + }, + "confirm_password": { + "type": "string" + }, + "given_name": { + "type": "string" + }, + "family_name": { + "type": "string" + }, + "middle_name": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "gender": { + "type": "string" + }, + "birthdate": { + "type": "string" + }, + "picture": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "scope": { + "type": "array", + "items": { + "type": "string" + } + }, + "redirect_uri": { + "type": "string" + }, + "is_multi_factor_auth_enabled": { + "type": "boolean" + }, + "state": { + "type": "string" + }, + "app_data": { + "$ref": "#/definitions/v1AppData" + } + } + }, + "v1SignupResponse": { + "type": "object", + "properties": { + "auth": { + "$ref": "#/definitions/v1AuthResponse" + } + } + }, + "v1UpdateProfileRequest": { + "type": "object", + "properties": { + "old_password": { + "type": "string" + }, + "new_password": { + "type": "string" + }, + "confirm_new_password": { + "type": "string" + }, + "email": { + "type": "string" + }, + "given_name": { + "type": "string" + }, + "family_name": { + "type": "string" + }, + "middle_name": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "gender": { + "type": "string" + }, + "birthdate": { + "type": "string" + }, + "phone_number": { + "type": "string" + }, + "picture": { + "type": "string" + }, + "is_multi_factor_auth_enabled": { + "type": "boolean" + }, + "app_data": { + "$ref": "#/definitions/v1AppData" + } + } + }, + "v1UpdateProfileResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "v1User": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string", + "description": "Either email or phone_number is always present." + }, + "email_verified": { + "type": "boolean" + }, + "signup_methods": { + "type": "string" + }, + "given_name": { + "type": "string" + }, + "family_name": { + "type": "string" + }, + "middle_name": { + "type": "string" + }, + "nickname": { + "type": "string" + }, + "preferred_username": { + "type": "string", + "description": "Defaults to email when unset." + }, + "gender": { + "type": "string" + }, + "birthdate": { + "type": "string" + }, + "phone_number": { + "type": "string" + }, + "phone_number_verified": { + "type": "boolean" + }, + "picture": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "created_at": { + "type": "string", + "format": "int64" + }, + "updated_at": { + "type": "string", + "format": "int64" + }, + "revoked_timestamp": { + "type": "string", + "format": "int64" + }, + "is_multi_factor_auth_enabled": { + "type": "boolean" + }, + "app_data": { + "$ref": "#/definitions/v1AppData", + "description": "Free-form key/value bag — same as GraphQL `app_data: Map`." + } + }, + "description": "User mirrors the GraphQL User type. Returned by Profile and embedded in\nAuthResponse." + }, + "v1ValidateJwtTokenRequest": { + "type": "object", + "properties": { + "token_type": { + "type": "string" + }, + "token": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "required_permissions": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PermissionInput" + } + } + } + }, + "v1ValidateJwtTokenResponse": { + "type": "object", + "properties": { + "is_valid": { + "type": "boolean" + }, + "claims": { + "$ref": "#/definitions/v1AppData", + "description": "Free-form JWT claims (matches GraphQL ValidateJWTTokenResponse.claims)." + } + } + }, + "v1ValidateSessionRequest": { + "type": "object", + "properties": { + "cookie": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "required_permissions": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PermissionInput" + } + } + } + }, + "v1ValidateSessionResponse": { + "type": "object", + "properties": { + "is_valid": { + "type": "boolean" + }, + "user": { + "$ref": "#/definitions/v1User" + } + } + }, + "v1VerifyEmailRequest": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "state": { + "type": "string" + } + } + }, + "v1VerifyEmailResponse": { + "type": "object", + "properties": { + "auth": { + "$ref": "#/definitions/v1AuthResponse" + } + } + }, + "v1VerifyOtpRequest": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Exactly one of email / phone_number is required." + }, + "phone_number": { + "type": "string" + }, + "otp": { + "type": "string" + }, + "is_totp": { + "type": "boolean" + }, + "state": { + "type": "string" + } + } + }, + "v1VerifyOtpResponse": { + "type": "object", + "properties": { + "auth": { + "$ref": "#/definitions/v1AuthResponse" + } + } + } + } +} diff --git a/gen/openapi/openapi.go b/gen/openapi/openapi.go new file mode 100644 index 00000000..8e113d41 --- /dev/null +++ b/gen/openapi/openapi.go @@ -0,0 +1,13 @@ +// Package openapi exposes the generated OpenAPI 2.0 spec as a byte slice +// so HTTP handlers can serve it from any working directory (test, Docker +// container, etc.). The file is embedded at compile time via go:embed so +// builds fail loudly if `make proto-gen` hasn't been run. +package openapi + +import _ "embed" + +//go:embed authorizer.swagger.json +var spec []byte + +// Spec returns the embedded OpenAPI 2.0 JSON. +func Spec() []byte { return spec } diff --git a/go.mod b/go.mod index 19a8bdbd..cd5a509f 100644 --- a/go.mod +++ b/go.mod @@ -31,9 +31,9 @@ require ( github.com/twilio/twilio-go v1.14.1 github.com/vektah/gqlparser/v2 v2.5.26 go.mongodb.org/mongo-driver v1.17.9 - golang.org/x/crypto v0.46.0 - golang.org/x/oauth2 v0.30.0 - golang.org/x/sync v0.19.0 + golang.org/x/crypto v0.49.0 + golang.org/x/oauth2 v0.36.0 + golang.org/x/sync v0.20.0 golang.org/x/time v0.15.0 gopkg.in/mail.v2 v2.3.1 gorm.io/driver/mysql v1.5.2 @@ -43,8 +43,12 @@ require ( ) require ( + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260415201107-50325440f8f2.1 // indirect + buf.build/go/protovalidate v1.2.0 // indirect + cel.dev/expr v0.25.1 // indirect github.com/agnivade/levenshtein v1.2.1 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect @@ -80,9 +84,12 @@ require ( github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/google/cel-go v0.28.0 // indirect + github.com/google/jsonschema-go v0.4.3 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -102,6 +109,7 @@ require ( github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/microsoft/go-mssqldb v1.6.0 // indirect + github.com/modelcontextprotocol/go-sdk v1.6.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/montanaflynn/stats v0.7.1 // indirect @@ -115,6 +123,8 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/segmentio/asm v1.1.3 // indirect + github.com/segmentio/encoding v0.5.4 // indirect github.com/sosodev/duration v1.3.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect @@ -124,16 +134,20 @@ require ( github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect + github.com/yosida95/uritemplate/v3 v3.0.2 // indirect github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/mod v0.30.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.39.0 // indirect - golang.org/x/text v0.32.0 // indirect - golang.org/x/tools v0.39.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 // indirect + golang.org/x/mod v0.34.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/text v0.36.0 // indirect + golang.org/x/tools v0.43.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260523011958-0a33c5d7ca68 // indirect + google.golang.org/grpc v1.81.1 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/sourcemap.v1 v1.0.5 // indirect diff --git a/go.sum b/go.sum index 2218e45c..3dc948ac 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,9 @@ +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260415201107-50325440f8f2.1 h1:s6hzCXtND/ICdGPTMGk7C+/BFlr2Jg5GyH0NKf4XGXg= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260415201107-50325440f8f2.1/go.mod h1:tvtbpgaVXZX4g6Pn+AnzFycuRK3MOz5HJfEGeEllXYM= +buf.build/go/protovalidate v1.2.0 h1:DQVrUWkmGTBij+kOYv/x2LLxwcLaGKMdzShj1/6/3H0= +buf.build/go/protovalidate v1.2.0/go.mod h1:7rYiQEhqvAipoazpVNBBH2S2f8bjG4huMVy1V2Yofn4= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= github.com/99designs/gqlgen v0.17.73 h1:A3Ki+rHWqKbAOlg5fxiZBnz6OjW3nwupDHEG15gEsrg= github.com/99designs/gqlgen v0.17.73/go.mod h1:2RyGWjy2k7W9jxrs8MOQthXGkD3L3oGr0jXW3Pu8lGg= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M= @@ -28,6 +34,8 @@ github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kk github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 h1:goHVqTbFX3AIo0tzGr14pgfAW2ZfPChKO21Z9MGf/gk= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/arangodb/go-driver v1.6.0 h1:NFWj/idqXZxhFVueihMSI2R9NotNIsgvNfM/xmpekb4= github.com/arangodb/go-driver v1.6.0/go.mod h1:HQmdGkvNMVBTE3SIPSQ8T/ZddC6iwNsfMR+dDJQxIsI= github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2LcQBbxd0ZFdbGSyRKTYMZCfBbw/pMJFOk1g= @@ -168,6 +176,7 @@ github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXe github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= @@ -179,14 +188,20 @@ github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgj github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/cel-go v0.28.0 h1:KjSWstCpz/MN5t4a8gnGJNIYUsJRpdi/r97xWDphIQc= +github.com/google/cel-go v0.28.0/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0= +github.com/google/jsonschema-go v0.4.3/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -198,6 +213,8 @@ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -263,6 +280,8 @@ github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6 github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc= github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= +github.com/modelcontextprotocol/go-sdk v1.6.1 h1:0zOSupjKUxPKSocPT1Wtago+mUHU2/uZ4xSOY0FGReU= +github.com/modelcontextprotocol/go-sdk v1.6.1/go.mod h1:kzm3kzFL1/+AziGOE0nUs3gvPoNxMCvkxokMkuFapXQ= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -308,6 +327,10 @@ github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc= +github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg= +github.com/segmentio/encoding v0.5.4 h1:OW1VRern8Nw6ITAtwSZ7Idrl3MXCFwXHPgqESYfvNt0= +github.com/segmentio/encoding v0.5.4/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= @@ -353,6 +376,8 @@ github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6 github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= +github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -376,13 +401,19 @@ golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0 golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 h1:SbTAbRFnd5kjQXbczszQ0hdk3ctwYf3qBNH9jIsGclE= +golang.org/x/exp v0.0.0-20250813145105-42675adae3e6/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -397,14 +428,20 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -425,6 +462,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -442,6 +481,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= @@ -452,14 +493,24 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= +golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260523011958-0a33c5d7ca68 h1:PvEgGJf9C/1u5CHkInMg7UFYYUoiaQmW2LbtH0pjB78= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260523011958-0a33c5d7ca68/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ= +google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/config/config.go b/internal/config/config.go index 213ca073..041bef5e 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -43,6 +43,20 @@ type Config struct { // GraphQL endpoint to prevent oversized-payload denial of service. GraphQLMaxBodyBytes int64 + // gRPC server configuration + // GRPCPort is the port the gRPC server listens on. + GRPCPort int + // EnableGRPCReflection toggles the gRPC server-reflection service. + // Default: on (matches the playground). Disable in locked-down prod. + EnableGRPCReflection bool + // GRPCTLSCert / GRPCTLSKey set the TLS material for the gRPC listener. + // When unset and GRPCInsecure is false, the server refuses to start. + GRPCTLSCert string + GRPCTLSKey string + // GRPCInsecure permits cleartext gRPC. For local dev only; production + // should always set TLS material. + GRPCInsecure bool + // Database Configurations // DatabaseType is the type of database to use DatabaseType string diff --git a/internal/cookie/cookie.go b/internal/cookie/cookie.go index dc4d1aa7..6cdd7fd0 100644 --- a/internal/cookie/cookie.go +++ b/internal/cookie/cookie.go @@ -25,22 +25,46 @@ func ParseSameSite(value string) http.SameSite { } } -// SetSession sets the session cookie in the response +// SetSession sets the session cookie in the response. func SetSession(gc *gin.Context, sessionID string, appCookieSecure bool, sameSite http.SameSite) { - secure := appCookieSecure - httpOnly := true - hostname := parsers.GetHost(gc) + for _, c := range BuildSessionCookies(parsers.GetHost(gc), sessionID, appCookieSecure, sameSite) { + gc.SetSameSite(c.SameSite) + gc.SetCookie(c.Name, c.Value, c.MaxAge, c.Path, c.Domain, c.Secure, c.HttpOnly) + } +} + +// BuildSessionCookies returns the pair of session cookies (host-scoped and +// domain-scoped) to set on the response. Transport-agnostic so non-gin +// callers (the service layer, gRPC handlers) can produce them as side-effects. +func BuildSessionCookies(hostname, sessionID string, appCookieSecure bool, sameSite http.SameSite) []*http.Cookie { host, _ := parsers.GetHostParts(hostname) domain := parsers.GetDomainName(hostname) if domain != "localhost" { domain = "." + domain } - - gc.SetSameSite(sameSite) day := 60 * 60 * 24 - - gc.SetCookie(constants.AppCookieName+"_session", sessionID, day, "/", host, secure, httpOnly) - gc.SetCookie(constants.AppCookieName+"_session_domain", sessionID, day, "/", domain, secure, httpOnly) + return []*http.Cookie{ + { + Name: constants.AppCookieName + "_session", + Value: sessionID, + MaxAge: day, + Path: "/", + Domain: host, + Secure: appCookieSecure, + HttpOnly: true, + SameSite: sameSite, + }, + { + Name: constants.AppCookieName + "_session_domain", + Value: sessionID, + MaxAge: day, + Path: "/", + Domain: domain, + Secure: appCookieSecure, + HttpOnly: true, + SameSite: sameSite, + }, + } } // DeleteSession sets session cookies to expire diff --git a/internal/cookie/cookie_test.go b/internal/cookie/cookie_test.go new file mode 100644 index 00000000..a53da661 --- /dev/null +++ b/internal/cookie/cookie_test.go @@ -0,0 +1,91 @@ +package cookie + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/authorizerdev/authorizer/internal/constants" +) + +func TestBuildSessionCookies(t *testing.T) { + tests := []struct { + name string + hostname string + secure bool + sameSite http.SameSite + wantDomain string // expected `.example.com`-style domain on the domain-scoped cookie + }{ + {"production https", "https://auth.example.com", true, http.SameSiteNoneMode, ".example.com"}, + {"localhost dev", "http://localhost:8080", false, http.SameSiteLaxMode, "localhost"}, + {"subdomain", "https://auth.svc.example.com", true, http.SameSiteStrictMode, ".example.com"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cookies := BuildSessionCookies(tt.hostname, "session-id", tt.secure, tt.sameSite) + require.Len(t, cookies, 2, "BuildSessionCookies must return exactly the host-scoped and domain-scoped pair") + + for _, c := range cookies { + assert.Equal(t, "session-id", c.Value) + assert.Equal(t, tt.secure, c.Secure) + assert.True(t, c.HttpOnly, "session cookies must be HttpOnly") + assert.Equal(t, "/", c.Path) + assert.Equal(t, tt.sameSite, c.SameSite) + assert.Equal(t, 24*60*60, c.MaxAge, "session cookie MaxAge must be 1 day") + } + + // Sanity-check cookie names. + assert.Equal(t, constants.AppCookieName+"_session", cookies[0].Name) + assert.Equal(t, constants.AppCookieName+"_session_domain", cookies[1].Name) + // Domain-scoped cookie picks up the apex. + assert.Equal(t, tt.wantDomain, cookies[1].Domain) + }) + } +} + +func TestBuildMfaSessionCookies(t *testing.T) { + cookies := BuildMfaSessionCookies("https://auth.example.com", "mfa-id", true) + require.Len(t, cookies, 2) + for _, c := range cookies { + assert.Equal(t, "mfa-id", c.Value) + assert.True(t, c.Secure) + assert.True(t, c.HttpOnly) + assert.Equal(t, http.SameSiteNoneMode, c.SameSite, "secure → SameSite=None") + assert.Equal(t, 60, c.MaxAge, "MFA cookies are short-lived (60s)") + } + assert.Equal(t, constants.MfaCookieName+"_session", cookies[0].Name) + assert.Equal(t, constants.MfaCookieName+"_session_domain", cookies[1].Name) +} + +func TestBuildMfaSessionCookies_InsecureLaxSameSite(t *testing.T) { + cookies := BuildMfaSessionCookies("http://localhost:8080", "mfa-id", false) + require.Len(t, cookies, 2) + for _, c := range cookies { + assert.False(t, c.Secure) + // Insecure → SameSite=Lax (so cross-site flows still complete when not behind TLS). + // Verified against the original SetMfaSession behaviour: this is intentional. + assert.Equal(t, http.SameSiteLaxMode, c.SameSite) + } +} + +func TestParseSameSite(t *testing.T) { + tests := []struct { + in string + want http.SameSite + }{ + {"none", http.SameSiteNoneMode}, + {"NONE", http.SameSiteNoneMode}, + {"strict", http.SameSiteStrictMode}, + {"lax", http.SameSiteLaxMode}, + {"", http.SameSiteLaxMode}, // unknown defaults to Lax + {"garbage", http.SameSiteLaxMode}, + {" none ", http.SameSiteNoneMode}, + } + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + assert.Equal(t, tt.want, ParseSameSite(tt.in)) + }) + } +} diff --git a/internal/cookie/mfa_session.go b/internal/cookie/mfa_session.go index bb09702e..3ebe8bb2 100644 --- a/internal/cookie/mfa_session.go +++ b/internal/cookie/mfa_session.go @@ -10,33 +10,55 @@ import ( "github.com/authorizerdev/authorizer/internal/parsers" ) -// SetMfaSession sets the mfa session cookie in the response +// SetMfaSession sets the mfa session cookie in the response. func SetMfaSession(gc *gin.Context, sessionID string, appCookieSecure bool) { - secure := appCookieSecure - httpOnly := true - hostname := parsers.GetHost(gc) + for _, c := range BuildMfaSessionCookies(parsers.GetHost(gc), sessionID, appCookieSecure) { + gc.SetSameSite(c.SameSite) + gc.SetCookie(c.Name, c.Value, c.MaxAge, c.Path, c.Domain, c.Secure, c.HttpOnly) + } +} + +// BuildMfaSessionCookies returns the MFA session cookies (host-scoped and +// domain-scoped) to set on the response. Transport-agnostic mirror of +// SetMfaSession. +// +// SameSite policy mirrors the gin path: Lax when insecure (so cross-site UI +// can still complete the flow), None when secure. See the SetMfaSession +// comment for the historical reasoning and the configurability TODO. +func BuildMfaSessionCookies(hostname, sessionID string, appCookieSecure bool) []*http.Cookie { host, _ := parsers.GetHostParts(hostname) domain := parsers.GetDomainName(hostname) if domain != "localhost" { domain = "." + domain } - - // Since app cookie can come from cross site it becomes important to set this in lax mode when insecure. - // Example person using custom UI on their app domain and making request to authorizer domain. - // For more information check: - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite - // https://github.com/gin-gonic/gin/blob/master/context.go#L86 - // TODO add ability to configure sameSite (none / lax / strict) via config + sameSite := http.SameSiteNoneMode if !appCookieSecure { - gc.SetSameSite(http.SameSiteLaxMode) - } else { - gc.SetSameSite(http.SameSiteNoneMode) + sameSite = http.SameSiteLaxMode } // TODO allow configuring cookie max-age via config age := 60 - - gc.SetCookie(constants.MfaCookieName+"_session", sessionID, age, "/", host, secure, httpOnly) - gc.SetCookie(constants.MfaCookieName+"_session_domain", sessionID, age, "/", domain, secure, httpOnly) + return []*http.Cookie{ + { + Name: constants.MfaCookieName + "_session", + Value: sessionID, + MaxAge: age, + Path: "/", + Domain: host, + Secure: appCookieSecure, + HttpOnly: true, + SameSite: sameSite, + }, + { + Name: constants.MfaCookieName + "_session_domain", + Value: sessionID, + MaxAge: age, + Path: "/", + Domain: domain, + Secure: appCookieSecure, + HttpOnly: true, + SameSite: sameSite, + }, + } } // DeleteMfaSession deletes the mfa session cookies to expire diff --git a/internal/gateway/mount.go b/internal/gateway/mount.go new file mode 100644 index 00000000..940ee9c0 --- /dev/null +++ b/internal/gateway/mount.go @@ -0,0 +1,84 @@ +// Package gateway translates REST (`/v1/*`) calls into in-process gRPC +// method invocations using grpc-gateway. The resulting http.Handler is +// mounted into the existing Gin router so middleware (CORS, security +// headers, rate limit, logging) is shared. +// +// We deliberately use the *in-process* dialer style: the gateway dials the +// running grpc.Server via bufconn rather than making a real network hop. +// This avoids the latency and TLS-cert plumbing of a loopback gRPC call, +// and removes the need to keep two ports in sync. +package gateway + +import ( + "context" + "net" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/test/bufconn" + "google.golang.org/protobuf/encoding/protojson" + + authorizerv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/v1" +) + +// bufconn size; large enough that in-process gateway calls never block. +const bufSize = 1 << 20 + +// Handler builds an http.Handler that translates `/v1/*` REST calls into +// gRPC calls against the supplied in-process *grpc.Server. Returns the +// handler and a cleanup function the caller invokes at shutdown. +func Handler(ctx context.Context, grpcSrv *grpc.Server) (http.Handler, func(), error) { + lis := bufconn.Listen(bufSize) + + // Serve gRPC over the bufconn in a goroutine; the existing TCP + // listener (started by grpcsrv.Server.Run) is the public entry point — + // this listener only carries in-process gateway traffic. + go func() { + _ = grpcSrv.Serve(lis) + }() + + conn, err := grpc.NewClient( + "passthrough:///bufconn", + grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) { return lis.Dial() }), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + _ = lis.Close() + return nil, nil, err + } + + mux := runtime.NewServeMux( + // Use snake_case proto field names (UseProtoNames=true) over the + // camelCase default — keeps payloads aligned with the existing + // GraphQL surface. DiscardUnknown tolerates older clients sending + // fields that have since been removed. + runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ + MarshalOptions: protojson.MarshalOptions{ + UseProtoNames: true, + EmitUnpopulated: true, + }, + UnmarshalOptions: protojson.UnmarshalOptions{ + DiscardUnknown: true, + }, + }), + ) + if err := registerAll(ctx, mux, conn); err != nil { + _ = conn.Close() + _ = lis.Close() + return nil, nil, err + } + + cleanup := func() { + _ = conn.Close() + _ = lis.Close() + } + return mux, cleanup, nil +} + +func registerAll(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + // Single AuthorizerService. As more services land (admin-side ones + // that today stay GraphQL-only), add their registrar here. + return authorizerv1.RegisterAuthorizerServiceHandler(ctx, mux, conn) +} diff --git a/internal/graphql/meta.go b/internal/graphql/meta.go index 6fa06d5e..94b8860b 100644 --- a/internal/graphql/meta.go +++ b/internal/graphql/meta.go @@ -3,71 +3,17 @@ package graphql import ( "context" - "github.com/authorizerdev/authorizer/internal/constants" "github.com/authorizerdev/authorizer/internal/graph/model" + "github.com/authorizerdev/authorizer/internal/service" + "github.com/authorizerdev/authorizer/internal/utils" ) -// Meta returns the meta information about the server. +// Meta delegates to the transport-agnostic service layer. Resolver is a thin +// transport adapter — same pattern as SignUp. +// // Permissions: none func (g *graphqlProvider) Meta(ctx context.Context) (*model.Meta, error) { - clientID := g.Config.ClientID - - googleClientID := g.Config.GoogleClientID - googleClientSecret := g.Config.GoogleClientSecret - - facebookClientID := g.Config.FacebookClientID - facebookClientSecret := g.Config.FacebookClientSecret - - linkedClientID := g.Config.LinkedinClientID - linkedInClientSecret := g.Config.LinkedinClientSecret - - appleClientID := g.Config.AppleClientID - appleClientSecret := g.Config.AppleClientSecret - - githubClientID := g.Config.GithubClientID - githubClientSecret := g.Config.GithubClientSecret - - twitterClientID := g.Config.TwitterClientID - twitterClientSecret := g.Config.TwitterClientSecret - - microsoftClientID := g.Config.MicrosoftClientID - microsoftClientSecret := g.Config.MicrosoftClientSecret - - twitchClientID := g.Config.TwitchClientID - twitchClientSecret := g.Config.TwitchClientSecret - - robloxClientID := g.Config.RobloxClientID - robloxClientSecret := g.Config.RobloxClientSecret - - isBasicAuthEnabled := g.Config.EnableBasicAuthentication - isMobileBasicAuthEnabled := g.Config.EnableMobileBasicAuthentication - isMobileVerificationEnabled := g.Config.EnablePhoneVerification - isMagicLinkLoginEnabled := g.Config.EnableMagicLinkLogin - isEmailVerificationEnabled := g.Config.EnableEmailVerification - isMultiFactorAuthenticationEnabled := g.Config.EnableMFA - isStrongPasswordEnabled := g.Config.EnableStrongPassword - isSignUpEnabled := g.Config.EnableSignup - - metaInfo := model.Meta{ - Version: constants.VERSION, - ClientID: clientID, - IsGoogleLoginEnabled: googleClientID != "" && googleClientSecret != "", - IsGithubLoginEnabled: githubClientID != "" && githubClientSecret != "", - IsFacebookLoginEnabled: facebookClientID != "" && facebookClientSecret != "", - IsLinkedinLoginEnabled: linkedClientID != "" && linkedInClientSecret != "", - IsAppleLoginEnabled: appleClientID != "" && appleClientSecret != "", - IsTwitterLoginEnabled: twitterClientID != "" && twitterClientSecret != "", - IsMicrosoftLoginEnabled: microsoftClientID != "" && microsoftClientSecret != "", - IsBasicAuthenticationEnabled: isBasicAuthEnabled, - IsEmailVerificationEnabled: isEmailVerificationEnabled, - IsMagicLinkLoginEnabled: isMagicLinkLoginEnabled, - IsSignUpEnabled: isSignUpEnabled, - IsStrongPasswordEnabled: isStrongPasswordEnabled, - IsMultiFactorAuthEnabled: isMultiFactorAuthenticationEnabled, - IsMobileBasicAuthenticationEnabled: isMobileBasicAuthEnabled, - IsPhoneVerificationEnabled: isMobileVerificationEnabled, - IsTwitchLoginEnabled: twitchClientID != "" && twitchClientSecret != "", - IsRobloxLoginEnabled: robloxClientID != "" && robloxClientSecret != "", - } - return &metaInfo, nil + gc, _ := utils.GinContextFromContext(ctx) + res, _, err := g.ServiceProvider.Meta(ctx, service.MetaFromGin(gc)) + return res, err } diff --git a/internal/graphql/provider.go b/internal/graphql/provider.go index 418c3147..c911e09b 100644 --- a/internal/graphql/provider.go +++ b/internal/graphql/provider.go @@ -13,6 +13,7 @@ import ( "github.com/authorizerdev/authorizer/internal/events" "github.com/authorizerdev/authorizer/internal/graph/model" "github.com/authorizerdev/authorizer/internal/memory_store" + "github.com/authorizerdev/authorizer/internal/service" "github.com/authorizerdev/authorizer/internal/sms" "github.com/authorizerdev/authorizer/internal/storage" "github.com/authorizerdev/authorizer/internal/token" @@ -41,6 +42,9 @@ type Dependencies struct { TokenProvider token.Provider // AuthorizationProvider is used for fine-grained authorization checks AuthorizationProvider authorization.Provider + // ServiceProvider hosts the transport-agnostic public-API operations. + // Resolvers for migrated ops (currently just SignUp) delegate here. + ServiceProvider service.Provider } // New constructs a new graphql provider with given arguments diff --git a/internal/graphql/signup.go b/internal/graphql/signup.go index cec217c2..83344742 100644 --- a/internal/graphql/signup.go +++ b/internal/graphql/signup.go @@ -2,35 +2,17 @@ package graphql import ( "context" - "encoding/json" - "errors" - "fmt" - "strings" - "time" - "github.com/google/uuid" - "golang.org/x/crypto/bcrypt" - - "github.com/authorizerdev/authorizer/internal/audit" - "github.com/authorizerdev/authorizer/internal/constants" - "github.com/authorizerdev/authorizer/internal/cookie" - "github.com/authorizerdev/authorizer/internal/crypto" "github.com/authorizerdev/authorizer/internal/graph/model" - "github.com/authorizerdev/authorizer/internal/metrics" - "github.com/authorizerdev/authorizer/internal/parsers" - "github.com/authorizerdev/authorizer/internal/refs" - "github.com/authorizerdev/authorizer/internal/storage/schemas" - "github.com/authorizerdev/authorizer/internal/token" + "github.com/authorizerdev/authorizer/internal/service" "github.com/authorizerdev/authorizer/internal/utils" - "github.com/authorizerdev/authorizer/internal/validators" ) -// dummyHash is a precomputed bcrypt hash used to equalise the response time -// of the "user exists" path with the "new signup" path, preventing account -// enumeration via timing. -var dummyHash, _ = bcrypt.GenerateFromPassword([]byte("dummy-password-for-timing"), bcrypt.DefaultCost) - -// SignUp is the method to singup user +// SignUp delegates to the transport-agnostic service layer. Resolvers in this +// package are thin transport adapters: pull gin.Context out of the GraphQL +// context, build RequestMetadata, call the service, apply any cookie +// side-effects back onto gin. +// // Permission: none func (g *graphqlProvider) SignUp(ctx context.Context, params *model.SignUpRequest) (*model.AuthResponse, error) { log := g.Log.With().Str("func", "SignUp").Logger() @@ -39,363 +21,10 @@ func (g *graphqlProvider) SignUp(ctx context.Context, params *model.SignUpReques log.Debug().Err(err).Msg("Failed to get GinContext") return nil, err } - - email := strings.TrimSpace(refs.StringValue(params.Email)) - phoneNumber := strings.TrimSpace(refs.StringValue(params.PhoneNumber)) - if email == "" && phoneNumber == "" { - log.Debug().Msg("Email or phone number is required") - return nil, fmt.Errorf(`email or phone number is required`) - } - - isSignupEnabled := g.Config.EnableSignup - if !isSignupEnabled { - log.Debug().Msg("Signup is disabled") - return nil, fmt.Errorf(`signup is disabled for this instance`) - } - - isBasicAuthEnabled := g.Config.EnableBasicAuthentication - isMobileBasicAuthEnabled := g.Config.EnableMobileBasicAuthentication - if params.ConfirmPassword != params.Password { - log.Debug().Msg("Passwords do not match") - return nil, fmt.Errorf(`password and confirm password does not match`) - } - if err := validators.IsValidPassword(params.Password, !g.Config.EnableStrongPassword); err != nil { - log.Debug().Msg("Invalid password") - return nil, err - } - - log = log.With().Str("email", email).Str("phone_number", phoneNumber).Logger() - isEmailSignup := email != "" - isMobileSignup := phoneNumber != "" - if !isBasicAuthEnabled && isEmailSignup { - log.Debug().Msg("Basic authentication is disabled") - return nil, fmt.Errorf(`basic authentication is disabled for this instance`) - } - if !isMobileBasicAuthEnabled && isMobileSignup { - log.Debug().Msg("Mobile basic authentication is disabled") - return nil, fmt.Errorf(`mobile basic authentication is disabled for this instance`) - } - if isEmailSignup && !validators.IsValidEmail(email) { - log.Debug().Msg("Invalid email") - return nil, fmt.Errorf(`invalid email address`) - } - if isMobileSignup && (phoneNumber == "" || len(phoneNumber) < 10) { - log.Debug().Msg("Invalid phone number") - return nil, fmt.Errorf(`invalid phone number`) - } - // find user with email / phone number - if isEmailSignup { - existingUser, err := g.StorageProvider.GetUserByEmail(ctx, email) - if err != nil { - log.Debug().Err(err).Msg("Failed to get user by email") - } - if existingUser != nil && (existingUser.EmailVerifiedAt != nil || existingUser.ID != "") { - log.Debug().Msg("Email is already signed up.") - bcrypt.CompareHashAndPassword(dummyHash, []byte("timing-equalization")) - return nil, fmt.Errorf("signup failed. please check your credentials or try a different method") - } - } else { - existingUser, err := g.StorageProvider.GetUserByPhoneNumber(ctx, phoneNumber) - if err != nil { - log.Debug().Err(err).Msg("Failed to get user by phone number") - } - if existingUser != nil && (existingUser.PhoneNumberVerifiedAt != nil || existingUser.ID != "") { - log.Debug().Msg("Phone number is already signed up.") - bcrypt.CompareHashAndPassword(dummyHash, []byte("timing-equalization")) - return nil, fmt.Errorf("signup failed. please check your credentials or try a different method") - } - } - - inputRoles := params.Roles - if len(inputRoles) > 0 { - // check if roles exists - roles := g.Config.Roles - if !validators.IsValidRoles(inputRoles, roles) { - log.Debug().Err(err).Strs("roles", params.Roles).Msg("Invalid roles") - return nil, fmt.Errorf(`invalid roles`) - } - } else { - inputRoles = g.Config.DefaultRoles - } - user := &schemas.User{} - user.Roles = strings.Join(inputRoles, ",") - password, _ := crypto.EncryptPassword(params.Password) - user.Password = &password - if email != "" { - user.SignupMethods = constants.AuthRecipeMethodBasicAuth - user.Email = &email - } - if params.GivenName != nil { - user.GivenName = params.GivenName - } - - if params.FamilyName != nil { - user.FamilyName = params.FamilyName - } - - if params.MiddleName != nil { - user.MiddleName = params.MiddleName - } - - if params.Nickname != nil { - user.Nickname = params.Nickname - } - - if params.Gender != nil { - user.Gender = params.Gender - } - - if params.Birthdate != nil { - user.Birthdate = params.Birthdate - } - - if phoneNumber != "" { - user.SignupMethods = constants.AuthRecipeMethodMobileBasicAuth - user.PhoneNumber = refs.NewStringRef(phoneNumber) - } - - if params.Picture != nil { - user.Picture = params.Picture - } - - if params.IsMultiFactorAuthEnabled != nil { - user.IsMultiFactorAuthEnabled = params.IsMultiFactorAuthEnabled - } - - isMFAEnforced := g.Config.EnforceMFA - if isMFAEnforced { - user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true) - } - - if params.AppData != nil { - appDataString := "" - appDataBytes, err := json.Marshal(params.AppData) - if err != nil { - log.Debug().Msg("failed to marshall source app_data") - return nil, errors.New("malformed app_data") - } - appDataString = string(appDataBytes) - user.AppData = &appDataString - } - isEmailServiceEnabled := g.Config.IsEmailServiceEnabled - isEmailVerificationEnabled := g.Config.EnableEmailVerification && isEmailServiceEnabled - if !isEmailVerificationEnabled && isEmailSignup { - now := time.Now().Unix() - user.EmailVerifiedAt = &now - } - isSMSServiceEnabled := g.Config.IsSMSServiceEnabled - isPhoneVerificationEnabled := g.Config.EnablePhoneVerification && isSMSServiceEnabled - if !isPhoneVerificationEnabled && isMobileSignup { - now := time.Now().Unix() - user.PhoneNumberVerifiedAt = &now - } - user, err = g.StorageProvider.AddUser(ctx, user) - if err != nil { - log.Debug().Err(err).Msg("failed to add user") - return nil, err - } - roles := strings.Split(user.Roles, ",") - userToReturn := user.AsAPIUser() - hostname := parsers.GetHost(gc) - if isEmailVerificationEnabled && isEmailSignup { - // insert verification request - _, nonceHash, err := utils.GenerateNonce() - if err != nil { - log.Debug().Err(err).Msg("Failed to generate nonce") - return nil, err - } - verificationType := constants.VerificationTypeBasicAuthSignup - redirectURL := parsers.GetAppURL(gc) - if params.RedirectURI != nil { - redirectURL = *params.RedirectURI - if !validators.IsValidRedirectURI(redirectURL, g.Config.AllowedOrigins, hostname) { - log.Debug().Msg("Invalid redirect URI") - return nil, fmt.Errorf("invalid redirect URI") - } - } - verificationToken, err := g.TokenProvider.CreateVerificationToken(&token.AuthTokenConfig{ - Nonce: nonceHash, - HostName: hostname, - User: user, - LoginMethod: constants.AuthRecipeMethodBasicAuth, - }, redirectURL, verificationType) - if err != nil { - log.Debug().Err(err).Msg("Failed to create verification token") - return nil, err - } - _, err = g.StorageProvider.AddVerificationRequest(ctx, &schemas.VerificationRequest{ - Token: verificationToken, - Identifier: verificationType, - ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), - Email: email, - Nonce: nonceHash, - RedirectURI: redirectURL, - }) - if err != nil { - log.Debug().Err(err).Msg("Failed to add verification request") - return nil, err - } - // exec it as go routine so that we can reduce the api latency - go func() { - // exec it as go routine so that we can reduce the api latency - g.EmailProvider.SendEmail([]string{email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{ - "user": user.ToMap(), - "organization": utils.GetOrganization(g.Config), - "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL), - }) - g.EventsProvider.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) - }() - - return &model.AuthResponse{ - Message: `Verification email has been sent. Please check your inbox`, - }, nil - } else if isPhoneVerificationEnabled && isMobileSignup { - duration, _ := time.ParseDuration("10m") - smsCode, err := utils.GenerateOTP() - if err != nil { - log.Debug().Err(err).Msg("Failed to generate OTP") - return nil, err - } - smsBody := strings.Builder{} - smsBody.WriteString("Your verification code is: ") - smsBody.WriteString(smsCode) - expiresAt := time.Now().Add(duration).Unix() - // Store the HMAC digest of the OTP; smsCode (plaintext) is sent - // over SMS by the existing smsBody above. - _, err = g.StorageProvider.UpsertOTP(ctx, &schemas.OTP{ - PhoneNumber: phoneNumber, - Otp: crypto.HashOTP(smsCode, g.Config.JWTSecret), - ExpiresAt: expiresAt, - }) - if err != nil { - log.Debug().Err(err).Msg("error while upserting OTP") - return nil, err - } - mfaSession := uuid.NewString() - err = g.MemoryStoreProvider.SetMfaSession(user.ID, mfaSession, expiresAt) - if err != nil { - log.Debug().Err(err).Msg("Failed to add mfasession") - return nil, err - } - cookie.SetMfaSession(gc, mfaSession, g.Config.AppCookieSecure) - go func() { - g.SMSProvider.SendSMS(phoneNumber, smsBody.String()) - g.EventsProvider.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user) - }() - return &model.AuthResponse{ - Message: "Please check the OTP in your inbox", - ShouldShowMobileOtpScreen: refs.NewBoolRef(true), - }, nil - } - scope := []string{"openid", "email", "profile"} - if params.Scope != nil && len(params.Scope) > 0 { - scope = params.Scope - } - - code := "" - codeChallenge := "" - nonce := "" - oidcNonce := "" - authorizeRedirectURI := "" - if params.State != nil { - // Get state from store - authorizeState, _ := g.MemoryStoreProvider.GetState(refs.StringValue(params.State)) - if authorizeState != "" { - authorizeStateSplit := strings.Split(authorizeState, "@@") - if len(authorizeStateSplit) > 1 { - code = authorizeStateSplit[0] - codeChallenge = authorizeStateSplit[1] - if len(authorizeStateSplit) > 2 { - oidcNonce = authorizeStateSplit[2] - } - if len(authorizeStateSplit) > 3 { - authorizeRedirectURI = authorizeStateSplit[3] - } - } else { - nonce = authorizeState - } - g.MemoryStoreProvider.RemoveState(refs.StringValue(params.State)) - } - } - - if nonce == "" { - nonce = uuid.New().String() - } - authToken, err := g.TokenProvider.CreateAuthToken(gc, &token.AuthTokenConfig{ - User: user, - Roles: roles, - Scope: scope, - Nonce: nonce, - OIDCNonce: oidcNonce, - Code: code, - LoginMethod: constants.AuthRecipeMethodBasicAuth, - HostName: hostname, - }) + res, side, err := g.ServiceProvider.SignUp(ctx, service.MetaFromGin(gc), params) if err != nil { - log.Debug().Err(err).Msg("Failed to create auth token") return nil, err } - - // Code challenge could be optional if PKCE flow is not used - if code != "" { - if err := g.MemoryStoreProvider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash+"@@"+oidcNonce+"@@"+authorizeRedirectURI); err != nil { - log.Debug().Err(err).Msg("SetState failed") - return nil, err - } - } - - expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix() - if expiresIn <= 0 { - expiresIn = 1 - } - - res := &model.AuthResponse{ - Message: `Signed up successfully.`, - AccessToken: &authToken.AccessToken.Token, - ExpiresIn: &expiresIn, - User: userToReturn, - } - - sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID - cookie.SetSession(gc, authToken.FingerPrintHash, g.Config.AppCookieSecure, cookie.ParseSameSite(g.Config.AppCookieSameSite)) - g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt) - g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt) - - if authToken.RefreshToken != nil { - res.RefreshToken = &authToken.RefreshToken.Token - g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt) - } - - go func() { - g.EventsProvider.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) - if isEmailSignup { - g.EventsProvider.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) - g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) - } else { - g.EventsProvider.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user) - g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user) - } - - if err := g.StorageProvider.AddSession(ctx, &schemas.Session{ - UserID: user.ID, - UserAgent: utils.GetUserAgent(gc.Request), - IP: utils.GetIP(gc.Request), - }); err != nil { - log.Debug().Err(err).Msg("Failed to add session") - } - }() - metrics.RecordAuthEvent(metrics.EventSignup, metrics.StatusSuccess) - metrics.ActiveSessions.Inc() - g.AuditProvider.LogEvent(audit.Event{ - Action: constants.AuditSignupEvent, - ActorID: user.ID, - ActorType: constants.AuditActorTypeUser, - ActorEmail: refs.StringValue(user.Email), - ResourceType: constants.AuditResourceTypeUser, - ResourceID: user.ID, - IPAddress: utils.GetIP(gc.Request), - UserAgent: utils.GetUserAgent(gc.Request), - }) - + service.ApplyToGin(gc, side) return res, nil } diff --git a/internal/grpcsrv/handlers/authorizer.go b/internal/grpcsrv/handlers/authorizer.go new file mode 100644 index 00000000..dc95d9ed --- /dev/null +++ b/internal/grpcsrv/handlers/authorizer.go @@ -0,0 +1,62 @@ +// Package handlers contains the AuthorizerHandler, the single gRPC service +// handler for Authorizer's public API. Methods that have already been +// migrated into internal/service (currently just Meta) delegate there; the +// rest embed the proto-generated UnimplementedAuthorizerServer so they +// return codes.Unimplemented until their underlying service method lands. +// +// As each follow-up PR migrates one GraphQL op into internal/service, the +// corresponding stub here is replaced with a real delegation following the +// Meta pattern. Tests in internal/integration_tests/grpc_surface_test.go +// guard the Unimplemented contract until each migration ships. +package handlers + +import ( + "context" + + "github.com/authorizerdev/authorizer/internal/grpcsrv/transport" + "github.com/authorizerdev/authorizer/internal/service" + + authorizerv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/v1" +) + +// AuthorizerHandler implements authorizer.v1.AuthorizerService. The single +// struct satisfies the entire service interface; methods become real one at +// a time. The Go type name stays "AuthorizerHandler" (not "...ServiceHandler") +// because in Go we don't repeat the "Service" suffix at the call site. +type AuthorizerHandler struct { + authorizerv1.UnimplementedAuthorizerServiceServer + Service service.Provider +} + +// Meta delegates to service.Meta and projects the GraphQL Meta model into +// the proto MetaResponse. +func (h *AuthorizerHandler) Meta(ctx context.Context, _ *authorizerv1.MetaRequest) (*authorizerv1.MetaResponse, error) { + m, _, err := h.Service.Meta(ctx, transport.MetaFromGRPC(ctx)) + if err != nil { + return nil, err + } + return &authorizerv1.MetaResponse{ + Meta: &authorizerv1.Meta{ + Version: m.Version, + ClientId: m.ClientID, + IsGoogleLoginEnabled: m.IsGoogleLoginEnabled, + IsFacebookLoginEnabled: m.IsFacebookLoginEnabled, + IsGithubLoginEnabled: m.IsGithubLoginEnabled, + IsLinkedinLoginEnabled: m.IsLinkedinLoginEnabled, + IsAppleLoginEnabled: m.IsAppleLoginEnabled, + IsDiscordLoginEnabled: m.IsDiscordLoginEnabled, + IsTwitterLoginEnabled: m.IsTwitterLoginEnabled, + IsMicrosoftLoginEnabled: m.IsMicrosoftLoginEnabled, + IsTwitchLoginEnabled: m.IsTwitchLoginEnabled, + IsRobloxLoginEnabled: m.IsRobloxLoginEnabled, + IsEmailVerificationEnabled: m.IsEmailVerificationEnabled, + IsBasicAuthenticationEnabled: m.IsBasicAuthenticationEnabled, + IsMagicLinkLoginEnabled: m.IsMagicLinkLoginEnabled, + IsSignUpEnabled: m.IsSignUpEnabled, + IsStrongPasswordEnabled: m.IsStrongPasswordEnabled, + IsMultiFactorAuthEnabled: m.IsMultiFactorAuthEnabled, + IsMobileBasicAuthenticationEnabled: m.IsMobileBasicAuthenticationEnabled, + IsPhoneVerificationEnabled: m.IsPhoneVerificationEnabled, + }, + }, nil +} diff --git a/internal/grpcsrv/interceptors/interceptors_test.go b/internal/grpcsrv/interceptors/interceptors_test.go new file mode 100644 index 00000000..007ba22a --- /dev/null +++ b/internal/grpcsrv/interceptors/interceptors_test.go @@ -0,0 +1,139 @@ +package interceptors + +import ( + "bytes" + "context" + "strings" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + authorizerv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/v1" +) + +// info builds a *grpc.UnaryServerInfo for a fake RPC. The full-method name is +// the only field interceptors actually read. +func info(method string) *grpc.UnaryServerInfo { + return &grpc.UnaryServerInfo{FullMethod: method} +} + +func TestRecovery_TurnsPanicIntoInternal(t *testing.T) { + var buf bytes.Buffer + log := zerolog.New(&buf) + + r := Recovery(&log) + _, err := r(context.Background(), nil, info("/svc/Method"), func(_ context.Context, _ any) (any, error) { + panic("kaboom") + }) + + st, ok := status.FromError(err) + require.True(t, ok, "expected a gRPC status error") + assert.Equal(t, codes.Internal, st.Code()) + assert.Equal(t, "internal server error", st.Message(), "panic detail must not leak to clients") + // The stack stays server-side. + assert.Contains(t, buf.String(), "panicked") + assert.Contains(t, buf.String(), "kaboom") +} + +func TestRecovery_PassesNormalErrorsThrough(t *testing.T) { + log := zerolog.Nop() + r := Recovery(&log) + want := status.Error(codes.NotFound, "no") + _, err := r(context.Background(), nil, info("/svc/X"), func(_ context.Context, _ any) (any, error) { + return nil, want + }) + assert.Equal(t, want, err) +} + +func TestLogging_OkPath(t *testing.T) { + var buf bytes.Buffer + log := zerolog.New(&buf) + mw := Logging(&log) + _, err := mw(context.Background(), nil, info("/svc/Foo"), func(_ context.Context, _ any) (any, error) { + return "ok", nil + }) + require.NoError(t, err) + out := buf.String() + assert.Contains(t, out, `"method":"/svc/Foo"`) + assert.Contains(t, out, `"code":"OK"`) + assert.Contains(t, out, `"level":"info"`) +} + +func TestLogging_ErrorPathRaisesLevel(t *testing.T) { + var buf bytes.Buffer + log := zerolog.New(&buf) + mw := Logging(&log) + _, _ = mw(context.Background(), nil, info("/svc/Bad"), func(_ context.Context, _ any) (any, error) { + return nil, status.Error(codes.Internal, "boom") + }) + out := buf.String() + assert.Contains(t, out, `"code":"Internal"`) + assert.Contains(t, out, `"level":"error"`, "Internal/Unknown/DataLoss must raise log level to error") +} + +func TestLogging_PermissionDeniedIsWarn(t *testing.T) { + var buf bytes.Buffer + log := zerolog.New(&buf) + mw := Logging(&log) + _, _ = mw(context.Background(), nil, info("/svc/X"), func(_ context.Context, _ any) (any, error) { + return nil, status.Error(codes.PermissionDenied, "no") + }) + assert.Contains(t, buf.String(), `"level":"warn"`, "non-Internal failures must log at warn, not error") +} + +func TestValidate_RejectsBadRequest(t *testing.T) { + mw, err := Validate() + require.NoError(t, err) + + // RevokeRequest enforces refresh_token min_len=1 via buf.validate.field + // — an empty string should fail the interceptor before any handler runs. + req := &authorizerv1.RevokeRequest{RefreshToken: ""} + _, err = mw(context.Background(), req, info("/authorizer.v1.Authorizer/Revoke"), func(_ context.Context, _ any) (any, error) { + t.Fatal("handler must NOT run for an invalid request") + return nil, nil + }) + st, ok := status.FromError(err) + require.True(t, ok) + assert.Equal(t, codes.InvalidArgument, st.Code()) +} + +func TestValidate_AllowsValidRequest(t *testing.T) { + mw, err := Validate() + require.NoError(t, err) + called := false + _, err = mw(context.Background(), &authorizerv1.MetaRequest{}, info("/authorizer.v1.Authorizer/Meta"), func(_ context.Context, _ any) (any, error) { + called = true + return &authorizerv1.MetaResponse{}, nil + }) + require.NoError(t, err) + assert.True(t, called, "valid request must reach the handler") +} + +func TestValidate_NonProtoRequestPassesThrough(t *testing.T) { + mw, err := Validate() + require.NoError(t, err) + _, err = mw(context.Background(), "not-a-proto", info("/svc/X"), func(_ context.Context, _ any) (any, error) { + return nil, nil + }) + require.NoError(t, err, "non-proto requests must not be rejected by the validator") +} + +// TestValidate_PreservesInvariant guards against regressions where someone +// makes Validate() return a non-functional middleware (e.g. by reordering +// the protovalidate.New() call). If the validator itself fails to build, +// callers must learn about it at startup, not at first request. +func TestValidate_BuildsCleanly(t *testing.T) { + mw, err := Validate() + require.NoError(t, err) + require.NotNil(t, mw) + // Sanity check: the returned interceptor type is what gRPC expects. + _ = grpc.UnaryServerInterceptor(mw) +} + +// helper used by some of the future interceptor tests +func _ignoreUnused() { _ = strings.Builder{} } diff --git a/internal/grpcsrv/interceptors/logging.go b/internal/grpcsrv/interceptors/logging.go new file mode 100644 index 00000000..67226b0c --- /dev/null +++ b/internal/grpcsrv/interceptors/logging.go @@ -0,0 +1,40 @@ +package interceptors + +import ( + "context" + "time" + + "github.com/rs/zerolog" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// Logging returns a unary interceptor that emits one structured log line per +// RPC at info level (or error/warn when the status code reflects failure). +// Method name, duration, and gRPC code are always present. +func Logging(log *zerolog.Logger) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { + start := time.Now() + resp, err := handler(ctx, req) + dur := time.Since(start) + + code := status.Code(err) + evt := log.Info() + switch code { + case codes.OK: + // stays info + case codes.Internal, codes.Unknown, codes.DataLoss: + evt = log.Error() + default: + evt = log.Warn() + } + evt. + Str("method", info.FullMethod). + Str("code", code.String()). + Dur("duration", dur). + Err(err). + Msg("grpc") + return resp, err + } +} diff --git a/internal/grpcsrv/interceptors/recovery.go b/internal/grpcsrv/interceptors/recovery.go new file mode 100644 index 00000000..9a2dfa37 --- /dev/null +++ b/internal/grpcsrv/interceptors/recovery.go @@ -0,0 +1,38 @@ +// Package interceptors contains the gRPC server interceptors shared across +// Authorizer services. They run in this order (outermost first): +// +// recovery → logging → validate → ... (auth, permission, audit — added per service in later PRs) +// +// Recovery is outermost so it catches panics raised by anything later, and +// converts them to a clean codes.Internal status instead of crashing the +// server. +package interceptors + +import ( + "context" + "runtime/debug" + + "github.com/rs/zerolog" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// Recovery returns a unary interceptor that converts handler panics into a +// codes.Internal error and logs the stack at error level. The stack stays +// server-side — clients only see a generic "internal error" message. +func Recovery(log *zerolog.Logger) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) { + defer func() { + if r := recover(); r != nil { + log.Error(). + Str("method", info.FullMethod). + Interface("panic", r). + Bytes("stack", debug.Stack()). + Msg("gRPC handler panicked") + err = status.Error(codes.Internal, "internal server error") + } + }() + return handler(ctx, req) + } +} diff --git a/internal/grpcsrv/interceptors/validate.go b/internal/grpcsrv/interceptors/validate.go new file mode 100644 index 00000000..6226888e --- /dev/null +++ b/internal/grpcsrv/interceptors/validate.go @@ -0,0 +1,32 @@ +package interceptors + +import ( + "context" + + "buf.build/go/protovalidate" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Validate returns a unary interceptor that runs protovalidate on every +// inbound request that's a proto.Message. Failures convert to +// codes.InvalidArgument with a human-readable detail. +// +// The validator is built once at startup and shared across requests +// (protovalidate.Validator is safe for concurrent use). +func Validate() (grpc.UnaryServerInterceptor, error) { + v, err := protovalidate.New() + if err != nil { + return nil, err + } + return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { + if msg, ok := req.(proto.Message); ok { + if err := v.Validate(msg); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "%v", err) + } + } + return handler(ctx, req) + }, nil +} diff --git a/internal/grpcsrv/server.go b/internal/grpcsrv/server.go new file mode 100644 index 00000000..8d33a68b --- /dev/null +++ b/internal/grpcsrv/server.go @@ -0,0 +1,107 @@ +// Package grpcsrv builds and runs the Authorizer gRPC server. It registers +// every public-API service (real or stubbed), enables reflection, exposes +// the standard gRPC health checking protocol, and applies the shared +// interceptor chain. +package grpcsrv + +import ( + "context" + "net" + + "github.com/rs/zerolog" + "google.golang.org/grpc" + "google.golang.org/grpc/health" + healthv1 "google.golang.org/grpc/health/grpc_health_v1" + "google.golang.org/grpc/reflection" + + "github.com/authorizerdev/authorizer/internal/config" + "github.com/authorizerdev/authorizer/internal/grpcsrv/handlers" + "github.com/authorizerdev/authorizer/internal/grpcsrv/interceptors" + "github.com/authorizerdev/authorizer/internal/service" + + authorizerv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/v1" +) + +// Dependencies is the minimum set the gRPC server needs. +type Dependencies struct { + Log *zerolog.Logger + Config *config.Config + ServiceProvider service.Provider +} + +// Server wraps a *grpc.Server plus its listener address. +type Server struct { + deps *Dependencies + addr string + srv *grpc.Server + health *health.Server +} + +// New constructs a configured gRPC server. The server is not yet listening; +// call Run to start serving. +func New(addr string, deps *Dependencies) (*Server, error) { + validate, err := interceptors.Validate() + if err != nil { + return nil, err + } + + srv := grpc.NewServer( + grpc.ChainUnaryInterceptor( + interceptors.Recovery(deps.Log), + interceptors.Logging(deps.Log), + validate, + ), + ) + + // Register the single AuthorizerService. AuthorizerHandler embeds + // UnimplementedAuthorizerServiceServer, so any RPC whose method has + // not yet been migrated returns codes.Unimplemented. Migrated methods + // (today: Meta) override the unimplemented stubs. + authorizerv1.RegisterAuthorizerServiceServer(srv, &handlers.AuthorizerHandler{Service: deps.ServiceProvider}) + + // gRPC health checking protocol (used by k8s grpc-probe and similar). + hs := health.NewServer() + hs.SetServingStatus("", healthv1.HealthCheckResponse_SERVING) + healthv1.RegisterHealthServer(srv, hs) + + // Reflection is gated on a config flag so prod deployments can lock it + // off, but defaults on for dev/test parity with the playground. + if deps.Config.EnableGRPCReflection { + reflection.Register(srv) + } + + return &Server{ + deps: deps, + addr: addr, + srv: srv, + health: hs, + }, nil +} + +// GRPCServer exposes the underlying *grpc.Server. Used by the in-process +// REST gateway mount to dial via bufconn during tests. +func (s *Server) GRPCServer() *grpc.Server { return s.srv } + +// Run starts the listener and blocks until ctx is cancelled or Serve errors. +// On context cancellation, the server is gracefully stopped (existing RPCs +// finish, no new ones accepted). +func (s *Server) Run(ctx context.Context) error { + lis, err := net.Listen("tcp", s.addr) + if err != nil { + return err + } + s.deps.Log.Info().Str("addr", s.addr).Msg("Starting gRPC server") + + errCh := make(chan error, 1) + go func() { errCh <- s.srv.Serve(lis) }() + + select { + case <-ctx.Done(): + s.deps.Log.Info().Msg("gRPC shutdown signal received, draining") + s.health.Shutdown() + s.srv.GracefulStop() + return nil + case err := <-errCh: + return err + } +} diff --git a/internal/grpcsrv/transport/grpc_metadata.go b/internal/grpcsrv/transport/grpc_metadata.go new file mode 100644 index 00000000..6c76f523 --- /dev/null +++ b/internal/grpcsrv/transport/grpc_metadata.go @@ -0,0 +1,101 @@ +// Package transport bridges between gRPC's incoming metadata / outgoing +// trailers and the service layer's transport-agnostic RequestMetadata / +// ResponseSideEffects. +// +// gRPC has no native cookie concept; cookies in ResponseSideEffects are +// serialised to `Set-Cookie` metadata entries. grpc-gateway promotes those +// into real `Set-Cookie` response headers when the call came in via REST. +// Pure-gRPC clients can read them via the response trailers or ignore them. +package transport + +import ( + "context" + "net/http" + "strings" + + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" + + "github.com/authorizerdev/authorizer/internal/service" +) + +// MetaFromGRPC builds a RequestMetadata from a gRPC context. Headers +// populated by grpc-gateway (`grpcgateway-*` prefix) are honored so the +// service sees the same host/IP/UA whether the call came via gRPC directly +// or via REST through the gateway. +func MetaFromGRPC(ctx context.Context) service.RequestMetadata { + md, _ := metadata.FromIncomingContext(ctx) + meta := service.RequestMetadata{ + HostURL: firstHeader(md, "x-authorizer-url", "grpcgateway-x-authorizer-url"), + IPAddress: firstHeader(md, "x-forwarded-for", "grpcgateway-x-forwarded-for", "x-real-ip"), + UserAgent: firstHeader(md, "grpcgateway-user-agent", "user-agent"), + AuthorizationHeader: firstHeader(md, "authorization", "grpcgateway-authorization"), + Cookies: cookiesFromMetadata(md), + } + // Default the host URL when no header was set (pure-gRPC caller, no + // proxy headers). The :authority pseudo-header is the gRPC equivalent + // of Host; use it as a fallback. + if meta.HostURL == "" { + if authority := firstHeader(md, ":authority"); authority != "" { + meta.HostURL = "http://" + authority + } + } + return meta +} + +// ApplyToGRPC writes the response side-effects to the outgoing gRPC stream. +// Every cookie becomes its own `Set-Cookie` metadata entry — preserving +// multi-cookie responses (e.g. host-scoped + domain-scoped session pair). +// grpc-gateway promotes the metadata back to real `Set-Cookie` HTTP headers. +// A nil receiver is a no-op. +func ApplyToGRPC(ctx context.Context, side *service.ResponseSideEffects) error { + if side == nil || len(side.Cookies) == 0 { + return nil + } + // grpc-gateway honours the per-RPC `Set-Cookie` metadata when prefixed + // `Grpc-Metadata-Set-Cookie` or under the canonical header. Use + // metadata.Pairs equivalents: same key, repeated values. + header := http.CanonicalHeaderKey("Set-Cookie") + md := metadata.MD{} + for _, c := range side.Cookies { + if c == nil { + continue + } + md.Append(header, c.String()) + } + if len(md) == 0 { + return nil + } + return grpc.SendHeader(ctx, md) +} + +func firstHeader(md metadata.MD, keys ...string) string { + for _, k := range keys { + if vs := md.Get(k); len(vs) > 0 { + return vs[0] + } + } + return "" +} + +// cookiesFromMetadata parses Cookie header(s) supplied via gRPC metadata. +// grpc-gateway forwards browser cookies as the `grpcgateway-cookie` key; +// pure-gRPC clients can set `cookie` directly. Multiple Cookie headers are +// concatenated (semicolon-separated per RFC 6265). +func cookiesFromMetadata(md metadata.MD) []*http.Cookie { + var raw []string + raw = append(raw, md.Get("grpcgateway-cookie")...) + raw = append(raw, md.Get("cookie")...) + if len(raw) == 0 { + return nil + } + // http.Request.Cookies parses the Cookie header for us. Synthesize a + // minimal request rather than re-implementing the cookie grammar. + req := &http.Request{Header: http.Header{}} + for _, line := range raw { + // One header may contain multiple cookies separated by "; ". + // http.Header.Add preserves the line; cookies are parsed downstream. + req.Header.Add("Cookie", strings.TrimSpace(line)) + } + return req.Cookies() +} diff --git a/internal/grpcsrv/transport/grpc_metadata_test.go b/internal/grpcsrv/transport/grpc_metadata_test.go new file mode 100644 index 00000000..6dd6c8ba --- /dev/null +++ b/internal/grpcsrv/transport/grpc_metadata_test.go @@ -0,0 +1,77 @@ +package transport + +import ( + "context" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/metadata" + + "github.com/authorizerdev/authorizer/internal/service" +) + +func TestMetaFromGRPC_ExtractsAllSignals(t *testing.T) { + md := metadata.New(map[string]string{ + "grpcgateway-x-authorizer-url": "https://auth.example.com", + "grpcgateway-x-forwarded-for": "10.1.2.3", + "grpcgateway-user-agent": "browser/1.0", + "grpcgateway-authorization": "Bearer abc", + "grpcgateway-cookie": "authorizer_session=abc; mfa=xyz", + }) + ctx := metadata.NewIncomingContext(context.Background(), md) + meta := MetaFromGRPC(ctx) + assert.Equal(t, "https://auth.example.com", meta.HostURL) + assert.Equal(t, "10.1.2.3", meta.IPAddress) + assert.Equal(t, "browser/1.0", meta.UserAgent) + assert.Equal(t, "Bearer abc", meta.AuthorizationHeader) + require.Len(t, meta.Cookies, 2) + cookieValues := map[string]string{} + for _, c := range meta.Cookies { + cookieValues[c.Name] = c.Value + } + assert.Equal(t, "abc", cookieValues["authorizer_session"]) + assert.Equal(t, "xyz", cookieValues["mfa"]) +} + +func TestMetaFromGRPC_FallsBackToAuthority(t *testing.T) { + md := metadata.New(map[string]string{":authority": "auth.example.com"}) + ctx := metadata.NewIncomingContext(context.Background(), md) + meta := MetaFromGRPC(ctx) + assert.Equal(t, "http://auth.example.com", meta.HostURL) +} + +func TestMetaFromGRPC_NoMetadata(t *testing.T) { + meta := MetaFromGRPC(context.Background()) + assert.Equal(t, service.RequestMetadata{}, meta) +} + +func TestCookiesFromMetadata_MultipleHeaders(t *testing.T) { + md := metadata.MD{} + md.Append("grpcgateway-cookie", "a=1; b=2") + md.Append("grpcgateway-cookie", "c=3") + cookies := cookiesFromMetadata(md) + require.Len(t, cookies, 3) + got := map[string]string{} + for _, c := range cookies { + got[c.Name] = c.Value + } + assert.Equal(t, map[string]string{"a": "1", "b": "2", "c": "3"}, got) +} + +func TestCookiesFromMetadata_NoCookies(t *testing.T) { + assert.Nil(t, cookiesFromMetadata(metadata.MD{})) +} + +func TestApplyToGRPC_NilSafe(t *testing.T) { + // nil receiver / empty cookies must not error. + assert.NoError(t, ApplyToGRPC(context.Background(), nil)) + assert.NoError(t, ApplyToGRPC(context.Background(), &service.ResponseSideEffects{})) + assert.NoError(t, ApplyToGRPC(context.Background(), &service.ResponseSideEffects{Cookies: []*http.Cookie{nil}})) +} + +// Note: ApplyToGRPC's success path uses grpc.SendHeader which requires a +// real *grpc.ServerStream / handler context. That's covered end-to-end by +// the integration tests in internal/integration_tests where cookies emitted +// by a CreateSession handler land in the REST response. diff --git a/internal/http_handlers/graphql.go b/internal/http_handlers/graphql.go index ad6e5e97..1585da29 100644 --- a/internal/http_handlers/graphql.go +++ b/internal/http_handlers/graphql.go @@ -219,6 +219,7 @@ func (h *httpProvider) GraphqlHandler() gin.HandlerFunc { StorageProvider: h.StorageProvider, TokenProvider: h.TokenProvider, AuthorizationProvider: h.AuthorizationProvider, + ServiceProvider: h.ServiceProvider, }) if err != nil { h.Log.Error().Err(err).Msg("Failed to create graphql provider") diff --git a/internal/http_handlers/provider.go b/internal/http_handlers/provider.go index 966c2c3c..e26e16e3 100644 --- a/internal/http_handlers/provider.go +++ b/internal/http_handlers/provider.go @@ -13,6 +13,7 @@ import ( "github.com/authorizerdev/authorizer/internal/memory_store" "github.com/authorizerdev/authorizer/internal/oauth" "github.com/authorizerdev/authorizer/internal/rate_limit" + "github.com/authorizerdev/authorizer/internal/service" "github.com/authorizerdev/authorizer/internal/sms" "github.com/authorizerdev/authorizer/internal/storage" "github.com/authorizerdev/authorizer/internal/token" @@ -45,6 +46,9 @@ type Dependencies struct { RateLimitProvider rate_limit.Provider // AuthorizationProvider is used for fine-grained authorization checks AuthorizationProvider authorization.Provider + // ServiceProvider hosts the transport-agnostic public-API operations. + // Migrated GraphQL resolvers (currently SignUp) delegate here. + ServiceProvider service.Provider } // New constructs a new http provider with given arguments diff --git a/internal/integration_tests/grpc_meta_test.go b/internal/integration_tests/grpc_meta_test.go new file mode 100644 index 00000000..56bb5605 --- /dev/null +++ b/internal/integration_tests/grpc_meta_test.go @@ -0,0 +1,58 @@ +package integration_tests + +import ( + "context" + "net" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/test/bufconn" + + "github.com/authorizerdev/authorizer/internal/grpcsrv" + "github.com/authorizerdev/authorizer/internal/service" + + authorizerv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/v1" +) + +// TestGRPCMeta exercises AuthorizerService.Meta end-to-end over a bufconn +// in-process gRPC channel. Validates the consolidated single-service +// design: proto → handler → service.Meta → response projection. +func TestGRPCMeta(t *testing.T) { + cfg := getTestConfig() + cfg.ClientID = "test-client" + + log := zerolog.New(zerolog.NewTestWriter(t)).With().Timestamp().Logger() + + svc, err := service.New(cfg, &service.Dependencies{Log: &log}) + require.NoError(t, err) + + srv, err := grpcsrv.New(":0", &grpcsrv.Dependencies{ + Log: &log, + Config: cfg, + ServiceProvider: svc, + }) + require.NoError(t, err) + + lis := bufconn.Listen(1 << 20) + t.Cleanup(func() { _ = lis.Close() }) + go func() { _ = srv.GRPCServer().Serve(lis) }() + t.Cleanup(srv.GRPCServer().GracefulStop) + + conn, err := grpc.NewClient( + "passthrough:///bufconn", + grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) { return lis.Dial() }), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + require.NoError(t, err) + t.Cleanup(func() { _ = conn.Close() }) + + client := authorizerv1.NewAuthorizerServiceClient(conn) + resp, err := client.Meta(context.Background(), &authorizerv1.MetaRequest{}) + require.NoError(t, err) + require.NotNil(t, resp.Meta) + require.Equal(t, "test-client", resp.Meta.ClientId) + require.NotEmpty(t, resp.Meta.Version) +} diff --git a/internal/integration_tests/grpc_surface_test.go b/internal/integration_tests/grpc_surface_test.go new file mode 100644 index 00000000..fb39b701 --- /dev/null +++ b/internal/integration_tests/grpc_surface_test.go @@ -0,0 +1,159 @@ +package integration_tests + +import ( + "context" + "net" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" + healthv1 "google.golang.org/grpc/health/grpc_health_v1" + "google.golang.org/grpc/status" + "google.golang.org/grpc/test/bufconn" + + "github.com/authorizerdev/authorizer/internal/grpcsrv" + "github.com/authorizerdev/authorizer/internal/service" + + authorizerv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/v1" +) + +// bootGRPCBufconn builds a gRPC server identical to the production one, +// served over an in-process bufconn. Returns a dialed *grpc.ClientConn the +// test uses to issue real RPCs. +func bootGRPCBufconn(t *testing.T) *grpc.ClientConn { + t.Helper() + cfg := getTestConfig() + cfg.ClientID = "test-client" + log := zerolog.New(zerolog.NewTestWriter(t)).With().Timestamp().Logger() + + svc, err := service.New(cfg, &service.Dependencies{Log: &log}) + require.NoError(t, err) + srv, err := grpcsrv.New(":0", &grpcsrv.Dependencies{Log: &log, Config: cfg, ServiceProvider: svc}) + require.NoError(t, err) + + lis := bufconn.Listen(1 << 20) + t.Cleanup(func() { _ = lis.Close() }) + go func() { _ = srv.GRPCServer().Serve(lis) }() + t.Cleanup(srv.GRPCServer().GracefulStop) + + conn, err := grpc.NewClient( + "passthrough:///bufconn", + grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) { return lis.Dial() }), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + require.NoError(t, err) + t.Cleanup(func() { _ = conn.Close() }) + return conn +} + +// TestAuthorizerServiceStubsReturnUnimplemented locks down the contract for +// every not-yet-migrated method on the consolidated AuthorizerService. +// Today Meta is the only real implementation; the remaining 18 methods +// return codes.Unimplemented. As each one gets migrated out of +// internal/graphql into internal/service, the corresponding sub-test here +// will start returning OK and the case can be moved to a happy-path test. +func TestAuthorizerServiceStubsReturnUnimplemented(t *testing.T) { + conn := bootGRPCBufconn(t) + ctx := context.Background() + c := authorizerv1.NewAuthorizerServiceClient(conn) + + type call func(context.Context) error + cases := map[string]call{ + "Signup": func(c0 context.Context) error { + _, err := c.Signup(c0, &authorizerv1.SignupRequest{Password: "p", ConfirmPassword: "p"}) + return err + }, + "Login": func(c0 context.Context) error { + _, err := c.Login(c0, &authorizerv1.LoginRequest{Password: "p"}) + return err + }, + "Logout": func(c0 context.Context) error { + _, err := c.Logout(c0, &authorizerv1.LogoutRequest{}) + return err + }, + "MagicLinkLogin": func(c0 context.Context) error { + _, err := c.MagicLinkLogin(c0, &authorizerv1.MagicLinkLoginRequest{Email: "x@example.com"}) + return err + }, + "VerifyEmail": func(c0 context.Context) error { + _, err := c.VerifyEmail(c0, &authorizerv1.VerifyEmailRequest{Token: "t"}) + return err + }, + "ResendVerifyEmail": func(c0 context.Context) error { + _, err := c.ResendVerifyEmail(c0, &authorizerv1.ResendVerifyEmailRequest{Email: "x@example.com", Identifier: "id"}) + return err + }, + "VerifyOtp": func(c0 context.Context) error { + _, err := c.VerifyOtp(c0, &authorizerv1.VerifyOtpRequest{Email: "x@example.com", Otp: "1"}) + return err + }, + "ResendOtp": func(c0 context.Context) error { + _, err := c.ResendOtp(c0, &authorizerv1.ResendOtpRequest{Email: "x@example.com"}) + return err + }, + "ForgotPassword": func(c0 context.Context) error { + _, err := c.ForgotPassword(c0, &authorizerv1.ForgotPasswordRequest{Email: "x@example.com"}) + return err + }, + "ResetPassword": func(c0 context.Context) error { + _, err := c.ResetPassword(c0, &authorizerv1.ResetPasswordRequest{Token: "t", Password: "p", ConfirmPassword: "p"}) + return err + }, + "Profile": func(c0 context.Context) error { + _, err := c.Profile(c0, &authorizerv1.ProfileRequest{}) + return err + }, + "UpdateProfile": func(c0 context.Context) error { + _, err := c.UpdateProfile(c0, &authorizerv1.UpdateProfileRequest{}) + return err + }, + "DeactivateAccount": func(c0 context.Context) error { + _, err := c.DeactivateAccount(c0, &authorizerv1.DeactivateAccountRequest{}) + return err + }, + "Revoke": func(c0 context.Context) error { + _, err := c.Revoke(c0, &authorizerv1.RevokeRequest{RefreshToken: "t"}) + return err + }, + "Session": func(c0 context.Context) error { + _, err := c.Session(c0, &authorizerv1.SessionRequest{}) + return err + }, + "ValidateJwtToken": func(c0 context.Context) error { + _, err := c.ValidateJwtToken(c0, &authorizerv1.ValidateJwtTokenRequest{TokenType: "access_token", Token: "t"}) + return err + }, + "ValidateSession": func(c0 context.Context) error { + _, err := c.ValidateSession(c0, &authorizerv1.ValidateSessionRequest{Cookie: "c"}) + return err + }, + "Permissions": func(c0 context.Context) error { + _, err := c.Permissions(c0, &authorizerv1.PermissionsRequest{}) + return err + }, + } + + for name, fn := range cases { + t.Run(name, func(t *testing.T) { + err := fn(ctx) + require.Error(t, err) + st, ok := status.FromError(err) + require.True(t, ok) + assert.Equal(t, codes.Unimplemented, st.Code(), + "stub for AuthorizerService.%s should return Unimplemented until its handler is wired", name) + }) + } +} + +// TestGRPCHealthCheckProtocol exercises the standard grpc.health.v1.Health +// service that the gRPC server registers for k8s readiness probes. +func TestGRPCHealthCheckProtocol(t *testing.T) { + conn := bootGRPCBufconn(t) + resp, err := healthv1.NewHealthClient(conn).Check(context.Background(), &healthv1.HealthCheckRequest{}) + require.NoError(t, err) + assert.Equal(t, healthv1.HealthCheckResponse_SERVING, resp.Status) +} diff --git a/internal/integration_tests/mcp_stubs_test.go b/internal/integration_tests/mcp_stubs_test.go new file mode 100644 index 00000000..3105d608 --- /dev/null +++ b/internal/integration_tests/mcp_stubs_test.go @@ -0,0 +1,64 @@ +package integration_tests + +import ( + "context" + "testing" + + "github.com/modelcontextprotocol/go-sdk/mcp" + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/authorizerdev/authorizer/internal/grpcsrv" + authmcp "github.com/authorizerdev/authorizer/internal/mcp" + "github.com/authorizerdev/authorizer/internal/service" +) + +// TestMCPStubReturnsError exercises the "MCP tool exposed in proto but its +// underlying gRPC handler is still a stub" path. This is the current state +// of get_user, get_current_session, and list_my_permissions: they appear in +// tools/list (proven by TestMCPListAndCallGetMeta) and a call must surface +// the underlying codes.Unimplemented as a tool error rather than silently +// succeeding or panicking. +func TestMCPStubReturnsError(t *testing.T) { + cfg := getTestConfig() + cfg.ClientID = "test-client" + log := zerolog.New(zerolog.NewTestWriter(t)).With().Timestamp().Logger() + + svc, err := service.New(cfg, &service.Dependencies{Log: &log}) + require.NoError(t, err) + grpcSrv, err := grpcsrv.New(":0", &grpcsrv.Dependencies{Log: &log, Config: cfg, ServiceProvider: svc}) + require.NoError(t, err) + mcpSrv, err := authmcp.New(&log, grpcSrv.GRPCServer(), "authorizer-test", "v0") + require.NoError(t, err) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + cTransport, sTransport := mcp.NewInMemoryTransports() + serverSession, err := mcpSrv.MCPServer().Connect(ctx, sTransport, nil) + require.NoError(t, err) + defer serverSession.Close() + + client := mcp.NewClient(&mcp.Implementation{Name: "test", Version: "v0"}, nil) + clientSession, err := client.Connect(ctx, cTransport, nil) + require.NoError(t, err) + defer clientSession.Close() + + // permissions is exposed via the proto annotation but its + // AuthorizerService.Permissions handler is a stub returning codes.Unimplemented. + // The MCP server must surface this as a CallToolResult{IsError:true} + // (tool-level error) rather than a JSON-RPC protocol error — so the + // LLM gets actionable text and can react / try a different tool. + res, err := clientSession.CallTool(ctx, &mcp.CallToolParams{ + Name: "permissions", + Arguments: map[string]any{}, + }) + require.NoError(t, err, "tool execution errors must NOT surface as protocol errors") + require.NotNil(t, res) + assert.True(t, res.IsError, "stubbed tool must return IsError=true") + require.NotEmpty(t, res.Content) + text, ok := res.Content[0].(*mcp.TextContent) + require.True(t, ok, "error content should be text") + assert.Contains(t, text.Text, "Unimplemented", + "the underlying gRPC Unimplemented code should be reflected in the MCP error text") +} diff --git a/internal/integration_tests/mcp_test.go b/internal/integration_tests/mcp_test.go new file mode 100644 index 00000000..712fde37 --- /dev/null +++ b/internal/integration_tests/mcp_test.go @@ -0,0 +1,85 @@ +package integration_tests + +import ( + "context" + "encoding/json" + "testing" + + "github.com/modelcontextprotocol/go-sdk/mcp" + "github.com/rs/zerolog" + "github.com/stretchr/testify/require" + + "github.com/authorizerdev/authorizer/internal/grpcsrv" + authmcp "github.com/authorizerdev/authorizer/internal/mcp" + "github.com/authorizerdev/authorizer/internal/service" +) + +// TestMCPListAndCallMeta exercises the vertical slice end-to-end on the +// consolidated single-service design: boot a gRPC server, wrap it in the +// MCP server (which auto-discovers tools from proto annotations), connect a +// client via in-memory transports, then list_tools + call meta. +func TestMCPListAndCallMeta(t *testing.T) { + cfg := getTestConfig() + cfg.ClientID = "test-client" + + log := zerolog.New(zerolog.NewTestWriter(t)).With().Timestamp().Logger() + + svc, err := service.New(cfg, &service.Dependencies{Log: &log}) + require.NoError(t, err) + + grpcSrv, err := grpcsrv.New(":0", &grpcsrv.Dependencies{ + Log: &log, + Config: cfg, + ServiceProvider: svc, + }) + require.NoError(t, err) + + mcpSrv, err := authmcp.New(&log, grpcSrv.GRPCServer(), "authorizer-test", "v0") + require.NoError(t, err) + + // Wire client ↔ server via in-memory transports (no stdio). + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + cTransport, sTransport := mcp.NewInMemoryTransports() + serverSession, err := mcpSrv.MCPServer().Connect(ctx, sTransport, nil) + require.NoError(t, err) + defer serverSession.Close() + + client := mcp.NewClient(&mcp.Implementation{Name: "test", Version: "v0"}, nil) + clientSession, err := client.Connect(ctx, cTransport, nil) + require.NoError(t, err) + defer clientSession.Close() + + // tools/list — should include the four proto-annotated MCP tools: + // meta, profile, session, permissions. + list, err := clientSession.ListTools(ctx, nil) + require.NoError(t, err) + gotNames := map[string]bool{} + for _, tool := range list.Tools { + gotNames[tool.Name] = true + } + for _, want := range []string{"meta", "profile", "session", "permissions"} { + require.True(t, gotNames[want], "expected MCP tool %q to be exposed; got %v", want, gotNames) + } + + // tools/call meta — should invoke AuthorizerService.Meta and return JSON + // wrapped in the per-RPC MetaResponse shape. + call, err := clientSession.CallTool(ctx, &mcp.CallToolParams{ + Name: "meta", + Arguments: map[string]any{}, + }) + require.NoError(t, err) + require.NotNil(t, call.StructuredContent) + + body, err := json.Marshal(call.StructuredContent) + require.NoError(t, err) + var got struct { + Meta struct { + ClientID string `json:"client_id"` + Version string `json:"version"` + } `json:"meta"` + } + require.NoError(t, json.Unmarshal(body, &got)) + require.Equal(t, "test-client", got.Meta.ClientID) + require.NotEmpty(t, got.Meta.Version) +} diff --git a/internal/integration_tests/rest_meta_test.go b/internal/integration_tests/rest_meta_test.go new file mode 100644 index 00000000..85786d30 --- /dev/null +++ b/internal/integration_tests/rest_meta_test.go @@ -0,0 +1,71 @@ +package integration_tests + +import ( + "context" + "encoding/json" + "io" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gin-gonic/gin" + "github.com/rs/zerolog" + "github.com/stretchr/testify/require" + + "github.com/authorizerdev/authorizer/internal/gateway" + "github.com/authorizerdev/authorizer/internal/grpcsrv" + "github.com/authorizerdev/authorizer/internal/service" +) + +// TestRESTMeta exercises GET /v1/meta through the grpc-gateway. Validates +// that the gateway translates the REST call into an in-process gRPC +// invocation against AuthorizerService.Meta, then renders the response as +// JSON. The wrapped response shape (`{"meta": {...}}`) is intentional: +// every AuthorizerService RPC's response is a thin wrapper around the +// inner type so buf STANDARD's RPC_REQUEST_RESPONSE_UNIQUE lint is satisfied. +func TestRESTMeta(t *testing.T) { + cfg := getTestConfig() + cfg.ClientID = "test-client" + + log := zerolog.New(zerolog.NewTestWriter(t)).With().Timestamp().Logger() + + svc, err := service.New(cfg, &service.Dependencies{Log: &log}) + require.NoError(t, err) + + grpcSrv, err := grpcsrv.New(":0", &grpcsrv.Dependencies{ + Log: &log, + Config: cfg, + ServiceProvider: svc, + }) + require.NoError(t, err) + + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + gw, cleanup, err := gateway.Handler(ctx, grpcSrv.GRPCServer()) + require.NoError(t, err) + t.Cleanup(cleanup) + + gin.SetMode(gin.TestMode) + r := gin.New() + r.Any("/v1/*path", gin.WrapH(gw)) + ts := httptest.NewServer(r) + t.Cleanup(ts.Close) + + resp, err := http.Get(ts.URL + "/v1/meta") + require.NoError(t, err) + defer resp.Body.Close() + require.Equal(t, http.StatusOK, resp.StatusCode) + + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + + var got struct { + Meta struct { + ClientID string `json:"client_id"` + Version string `json:"version"` + } `json:"meta"` + } + require.NoError(t, json.Unmarshal(body, &got)) + require.Equal(t, "test-client", got.Meta.ClientID) + require.NotEmpty(t, got.Meta.Version) +} diff --git a/internal/integration_tests/rest_openapi_test.go b/internal/integration_tests/rest_openapi_test.go new file mode 100644 index 00000000..730922e2 --- /dev/null +++ b/internal/integration_tests/rest_openapi_test.go @@ -0,0 +1,46 @@ +package integration_tests + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/authorizerdev/authorizer/gen/openapi" +) + +// TestOpenAPIEndpointServesValidJSON verifies the /openapi.json route +// returns the embedded swagger spec, with a body that parses as JSON and +// declares the v1 services. Guards against two regressions: +// 1. Path-based reads of the spec file would fail when cwd is not the +// repo root (Docker, tests). The embed should make this path-free. +// 2. The merged swagger is non-empty and includes recognisable v1 routes. +func TestOpenAPIEndpointServesValidJSON(t *testing.T) { + gin.SetMode(gin.TestMode) + r := gin.New() + r.GET("/openapi.json", func(c *gin.Context) { + c.Data(http.StatusOK, "application/json", openapi.Spec()) + }) + + ts := httptest.NewServer(r) + t.Cleanup(ts.Close) + + resp, err := http.Get(ts.URL + "/openapi.json") + require.NoError(t, err) + defer resp.Body.Close() + require.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "application/json", resp.Header.Get("Content-Type")) + + var doc map[string]any + require.NoError(t, json.NewDecoder(resp.Body).Decode(&doc)) + + // Sanity: swagger 2.0 doc with at least one path under /v1. + assert.Contains(t, doc, "swagger") + paths, ok := doc["paths"].(map[string]any) + require.True(t, ok, "openapi spec missing paths object") + assert.NotEmpty(t, paths, "openapi spec should declare at least one path") +} diff --git a/internal/integration_tests/test_helper.go b/internal/integration_tests/test_helper.go index f4005c35..3890e329 100644 --- a/internal/integration_tests/test_helper.go +++ b/internal/integration_tests/test_helper.go @@ -25,6 +25,7 @@ import ( "github.com/authorizerdev/authorizer/internal/memory_store" "github.com/authorizerdev/authorizer/internal/oauth" "github.com/authorizerdev/authorizer/internal/rate_limit" + "github.com/authorizerdev/authorizer/internal/service" "github.com/authorizerdev/authorizer/internal/sms" "github.com/authorizerdev/authorizer/internal/storage" "github.com/authorizerdev/authorizer/internal/token" @@ -207,6 +208,19 @@ func initTestSetup(t *testing.T, cfg *config.Config) *testSetup { StorageProvider: storageProvider, }) + // Transport-agnostic service layer for migrated public ops (SignUp etc.). + serviceProvider, err := service.New(cfg, &service.Dependencies{ + Log: &logger, + AuditProvider: auditProvider, + EmailProvider: emailProvider, + EventsProvider: eventsProvider, + MemoryStoreProvider: memoryStoreProvider, + SMSProvider: smsProvider, + StorageProvider: storageProvider, + TokenProvider: tokenProvider, + }) + require.NoError(t, err) + // Create dependencies struct gqlDeps := &graphql.Dependencies{ Log: &logger, @@ -219,6 +233,7 @@ func initTestSetup(t *testing.T, cfg *config.Config) *testSetup { SMSProvider: smsProvider, StorageProvider: storageProvider, TokenProvider: tokenProvider, + ServiceProvider: serviceProvider, } // Create dependencies struct @@ -234,6 +249,7 @@ func initTestSetup(t *testing.T, cfg *config.Config) *testSetup { TokenProvider: tokenProvider, RateLimitProvider: rateLimitProvider, OAuthProvider: oauthProvider, + ServiceProvider: serviceProvider, } // Create GraphQL provider diff --git a/internal/mcp/scanner.go b/internal/mcp/scanner.go new file mode 100644 index 00000000..4b461d33 --- /dev/null +++ b/internal/mcp/scanner.go @@ -0,0 +1,113 @@ +// Package mcp exposes a subset of Authorizer's gRPC methods as MCP tools. +// Which methods are exposed is declared at the proto layer via the custom +// option `authorizer.common.v1.mcp_tool` — the scanner reads it at startup +// to build the tool registry. No service-by-service hand-registration. +package mcp + +import ( + "fmt" + "strings" + + "google.golang.org/grpc" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + + commonv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/common/v1" +) + +// ToolBinding is one MCP-exposed RPC: a tool name, plus enough metadata to +// dispatch a JSON-arg invocation back to the gRPC server. +type ToolBinding struct { + // Name surfaced to MCP clients (e.g. "get_meta"). Defaults to + // snake_case(method) unless the proto annotation overrides it. + Name string + // Description from the RPC's leading comment, surfaced to the MCP host. + Description string + // Destructive hints to the MCP host that user confirmation is warranted. + Destructive bool + + // FullMethod is the gRPC method name in `/pkg.Service/Method` form. + // Used directly with grpc.ClientConn.Invoke. + FullMethod string + // InputDescriptor / OutputDescriptor are the proto message descriptors + // for request/response. Used by the dispatcher to construct dynamic + // proto.Message instances for JSON unmarshalling/marshalling. + InputDescriptor protoreflect.MessageDescriptor + OutputDescriptor protoreflect.MessageDescriptor +} + +// Scan walks the supplied gRPC server's registered services and returns the +// set of methods marked `(authorizer.common.v1.mcp_tool).exposed = true`. +// Methods that aren't exposed (the default) are silently skipped. +func Scan(srv *grpc.Server) ([]ToolBinding, error) { + var bindings []ToolBinding + for svcName := range srv.GetServiceInfo() { + // Look up the proto descriptor for this service by full name. + desc, err := protoregistry.GlobalFiles.FindDescriptorByName(protoreflect.FullName(svcName)) + if err != nil { + // Not all gRPC services come from compiled proto (e.g. the + // gRPC health checking and reflection services). Skip silently. + continue + } + svcDesc, ok := desc.(protoreflect.ServiceDescriptor) + if !ok { + continue + } + + methods := svcDesc.Methods() + for i := 0; i < methods.Len(); i++ { + m := methods.Get(i) + tool := mcpToolFromMethod(m) + if tool == nil || !tool.Exposed { + continue + } + + name := tool.ToolName + if name == "" { + name = camelToSnake(string(m.Name())) + } + + bindings = append(bindings, ToolBinding{ + Name: name, + Description: strings.TrimSpace(string(m.ParentFile().SourceLocations().ByDescriptor(m).LeadingComments)), + Destructive: tool.Destructive, + FullMethod: fmt.Sprintf("/%s/%s", svcName, m.Name()), + InputDescriptor: m.Input(), + OutputDescriptor: m.Output(), + }) + } + } + return bindings, nil +} + +// mcpToolFromMethod reads the (authorizer.common.v1.mcp_tool) option off a +// method descriptor. Returns nil when the option is absent or unset. +func mcpToolFromMethod(m protoreflect.MethodDescriptor) *commonv1.McpTool { + opts := m.Options() + if opts == nil { + return nil + } + t, ok := proto.GetExtension(opts, commonv1.E_McpTool).(*commonv1.McpTool) + if !ok || t == nil { + return nil + } + return t +} + +// camelToSnake converts MixedCase / camelCase to snake_case. ASCII only; +// proto method names never contain non-ASCII. +func camelToSnake(s string) string { + var b strings.Builder + for i, r := range s { + if i > 0 && r >= 'A' && r <= 'Z' { + b.WriteByte('_') + } + if r >= 'A' && r <= 'Z' { + b.WriteRune(r + ('a' - 'A')) + } else { + b.WriteRune(r) + } + } + return b.String() +} diff --git a/internal/mcp/schema.go b/internal/mcp/schema.go new file mode 100644 index 00000000..7246f7c2 --- /dev/null +++ b/internal/mcp/schema.go @@ -0,0 +1,87 @@ +package mcp + +import ( + "google.golang.org/protobuf/reflect/protoreflect" +) + +// jsonSchema is a tiny JSON-Schema subset — enough to describe the input of +// a typical Authorizer RPC. We don't bring in a full schema library because +// the MCP host only needs property names, types, and descriptions for tool +// discovery. +type jsonSchema struct { + Type string `json:"type"` + Properties map[string]jsonSchema `json:"properties,omitempty"` + Items *jsonSchema `json:"items,omitempty"` + Description string `json:"description,omitempty"` + Required []string `json:"required,omitempty"` +} + +// schemaForMessage derives a JSON Schema (object form) for a proto message +// descriptor. Field naming uses the proto field name (snake_case), matching +// the gateway's UseProtoNames=true configuration. +func schemaForMessage(md protoreflect.MessageDescriptor) jsonSchema { + return schemaForMessageWithVisited(md, map[protoreflect.FullName]struct{}{}) +} + +// schemaForMessageWithVisited recurses into nested message fields while +// guarding against cycles. The descriptor full-name is the visit key — +// well-known types like google.protobuf.Value reference themselves via +// repeated-Value lists, which would stack-overflow without this. +// +// On a re-visit we emit an opaque `object` rather than the full schema, +// which is the most honest thing to tell an MCP host about a self-recursive +// type (it can pass any JSON object; the server validates at the proto +// layer via protovalidate). +func schemaForMessageWithVisited(md protoreflect.MessageDescriptor, visited map[protoreflect.FullName]struct{}) jsonSchema { + if _, seen := visited[md.FullName()]; seen { + return jsonSchema{Type: "object"} + } + visited[md.FullName()] = struct{}{} + defer delete(visited, md.FullName()) + + root := jsonSchema{ + Type: "object", + Properties: map[string]jsonSchema{}, + } + fields := md.Fields() + for i := 0; i < fields.Len(); i++ { + f := fields.Get(i) + root.Properties[string(f.Name())] = schemaForField(f, visited) + } + return root +} + +func schemaForField(f protoreflect.FieldDescriptor, visited map[protoreflect.FullName]struct{}) jsonSchema { + // repeated → JSON array + if f.IsList() { + item := schemaForKind(f, visited) + return jsonSchema{Type: "array", Items: &item} + } + if f.IsMap() { + return jsonSchema{Type: "object"} + } + return schemaForKind(f, visited) +} + +func schemaForKind(f protoreflect.FieldDescriptor, visited map[protoreflect.FullName]struct{}) jsonSchema { + switch f.Kind() { + case protoreflect.BoolKind: + return jsonSchema{Type: "boolean"} + case protoreflect.Int32Kind, protoreflect.Int64Kind, + protoreflect.Uint32Kind, protoreflect.Uint64Kind, + protoreflect.Sint32Kind, protoreflect.Sint64Kind, + protoreflect.Fixed32Kind, protoreflect.Fixed64Kind, + protoreflect.Sfixed32Kind, protoreflect.Sfixed64Kind: + return jsonSchema{Type: "integer"} + case protoreflect.FloatKind, protoreflect.DoubleKind: + return jsonSchema{Type: "number"} + case protoreflect.StringKind, protoreflect.BytesKind: + return jsonSchema{Type: "string"} + case protoreflect.EnumKind: + return jsonSchema{Type: "string"} + case protoreflect.MessageKind, protoreflect.GroupKind: + return schemaForMessageWithVisited(f.Message(), visited) + default: + return jsonSchema{Type: "string"} + } +} diff --git a/internal/mcp/schema_test.go b/internal/mcp/schema_test.go new file mode 100644 index 00000000..5dc72f00 --- /dev/null +++ b/internal/mcp/schema_test.go @@ -0,0 +1,72 @@ +package mcp + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/reflect/protoreflect" + + authorizerv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/v1" +) + +// TestSchemaForMessage_FlatScalars covers the most common case: a request +// message with only scalar fields. SignupRequest is a good representative — +// string / repeated string / bool / message-typed (AppData). +func TestSchemaForMessage_FlatScalars(t *testing.T) { + md := (&authorizerv1.SignupRequest{}).ProtoReflect().Descriptor() + s := schemaForMessage(md) + + assert.Equal(t, "object", s.Type) + require.NotNil(t, s.Properties) + + assert.Equal(t, "string", s.Properties["email"].Type) + assert.Equal(t, "string", s.Properties["password"].Type) + assert.Equal(t, "boolean", s.Properties["is_multi_factor_auth_enabled"].Type) + + // repeated string → array of strings + roles := s.Properties["roles"] + require.Equal(t, "array", roles.Type) + require.NotNil(t, roles.Items) + assert.Equal(t, "string", roles.Items.Type) + + // Nested message field (AppData) — recurses into its sub-schema. + app := s.Properties["app_data"] + assert.Equal(t, "object", app.Type) +} + +// TestSchemaForMessage_EmptyRequest — MetaRequest has no fields. +func TestSchemaForMessage_EmptyRequest(t *testing.T) { + md := (&authorizerv1.MetaRequest{}).ProtoReflect().Descriptor() + s := schemaForMessage(md) + assert.Equal(t, "object", s.Type) + assert.Empty(t, s.Properties) +} + +// TestSchemaForMessage_CycleSafe — google.protobuf.Value references itself +// via repeated Value (ListValue.values). Before the cycle-guard fix, exposing +// any tool whose request includes a Struct or Value field would stack-overflow +// at boot. The visited-set short-circuits and emits an opaque `object`. +func TestSchemaForMessage_CycleSafe(t *testing.T) { + // AppData wraps google.protobuf.Struct, which contains a + // map, where Value can hold a ListValue of more Values. + // That's the exact recursion that would stack-overflow without the guard. + app := (&authorizerv1.SignupRequest{}).ProtoReflect().Descriptor().Fields().ByName("app_data") + require.NotNil(t, app) + + schema := schemaForField(app, map[protoreflect.FullName]struct{}{}) + // Doesn't panic / overflow. The deeply-nested Value type collapses to + // an opaque object once the cycle is detected. + assert.Equal(t, "object", schema.Type) +} + +// TestSchemaForMessage_ScalarOnly walks a request that's purely scalars +// (no nested message). Profile takes no arguments at all; Session takes +// a few list-of-string + nested PermissionInput. +func TestSchemaForMessage_AllScalarKinds(t *testing.T) { + md := (&authorizerv1.ValidateJwtTokenRequest{}).ProtoReflect().Descriptor() + s := schemaForMessage(md) + assert.Equal(t, "string", s.Properties["token_type"].Type) + assert.Equal(t, "string", s.Properties["token"].Type) + assert.Equal(t, "array", s.Properties["roles"].Type) +} diff --git a/internal/mcp/server.go b/internal/mcp/server.go new file mode 100644 index 00000000..9bd5c0c9 --- /dev/null +++ b/internal/mcp/server.go @@ -0,0 +1,167 @@ +package mcp + +import ( + "context" + "encoding/json" + "fmt" + "net" + "strings" + + "github.com/modelcontextprotocol/go-sdk/mcp" + "github.com/rs/zerolog" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/test/bufconn" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/dynamicpb" +) + +const bufSize = 1 << 20 + +// Server wraps an MCP server that bridges to an in-process gRPC server. The +// gRPC server is the source of truth for which tools exist (via the +// `mcp_tool` proto annotation); we never hand-register tools here. +type Server struct { + log *zerolog.Logger + mcpSrv *mcp.Server + gwConn *grpc.ClientConn + lis *bufconn.Listener + grpcSrv *grpc.Server +} + +// New builds an MCP server that exposes every gRPC method on `grpcSrv` +// whose proto annotation has `(authorizer.common.v1.mcp_tool).exposed = true`. +// The gRPC server is served over an in-process bufconn — same pattern as +// the REST gateway — so MCP tool invocations become local method calls with +// no extra network hop. +func New(log *zerolog.Logger, grpcSrv *grpc.Server, name, version string) (*Server, error) { + bindings, err := Scan(grpcSrv) + if err != nil { + return nil, fmt.Errorf("mcp: scan tools: %w", err) + } + log.Info().Int("tools", len(bindings)).Msg("MCP: discovered tools from proto annotations") + + // Same bufconn dance as the REST gateway. + lis := bufconn.Listen(bufSize) + go func() { _ = grpcSrv.Serve(lis) }() + conn, err := grpc.NewClient( + "passthrough:///bufconn", + grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) { return lis.Dial() }), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + _ = lis.Close() + return nil, fmt.Errorf("mcp: dial in-process grpc: %w", err) + } + + mcpSrv := mcp.NewServer(&mcp.Implementation{ + Name: name, + Version: version, + }, nil) + + for _, b := range bindings { + registerTool(log, mcpSrv, conn, b) + } + + return &Server{ + log: log, + mcpSrv: mcpSrv, + gwConn: conn, + lis: lis, + grpcSrv: grpcSrv, + }, nil +} + +// MCPServer exposes the underlying *mcp.Server. Used by tests to drive the +// server with an in-memory transport pair. +func (s *Server) MCPServer() *mcp.Server { return s.mcpSrv } + +// RunStdio serves MCP over stdio (the default Claude Code transport). Blocks +// until ctx is cancelled or the client disconnects. +func (s *Server) RunStdio(ctx context.Context) error { + defer s.cleanup() + return s.mcpSrv.Run(ctx, &mcp.StdioTransport{}) +} + +func (s *Server) cleanup() { + _ = s.gwConn.Close() + _ = s.lis.Close() +} + +// registerTool wires one ToolBinding into the MCP server. The handler: +// 1. Constructs a fresh proto.Message of the right type via dynamicpb +// 2. Unmarshals JSON args into it +// 3. Invokes the gRPC method via grpc.ClientConn.Invoke +// 4. Marshals the response back to JSON for the MCP client +func registerTool(log *zerolog.Logger, srv *mcp.Server, conn *grpc.ClientConn, b ToolBinding) { + schema := schemaForMessage(b.InputDescriptor) + tool := &mcp.Tool{ + Name: b.Name, + Description: b.Description, + InputSchema: schema, + } + if b.Destructive { + // MCP clients show a destructive-action confirmation when this is set. + tool.Annotations = &mcp.ToolAnnotations{DestructiveHint: ptrTrue()} + } + + srv.AddTool(tool, func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) { + // Build a dynamic proto.Message for the request, then unmarshal JSON. + reqMsg := dynamicpb.NewMessage(b.InputDescriptor) + if len(req.Params.Arguments) > 0 && !isJSONNull(req.Params.Arguments) { + if err := (protojson.UnmarshalOptions{DiscardUnknown: true}).Unmarshal(req.Params.Arguments, reqMsg); err != nil { + // Argument decode failures surface as tool errors (not + // protocol errors) so the LLM gets actionable text. + return errorResult("invalid arguments: " + err.Error()), nil + } + } + + respMsg := dynamicpb.NewMessage(b.OutputDescriptor) + if err := conn.Invoke(ctx, b.FullMethod, reqMsg, respMsg); err != nil { + log.Debug().Err(err).Str("tool", b.Name).Str("method", b.FullMethod).Msg("MCP tool invocation failed") + // gRPC errors (Unimplemented, PermissionDenied, NotFound, ...) + // become CallToolResult{IsError: true} with the gRPC status + // message as the content. The MCP host shows this to the LLM + // in a way that lets it react / try a different tool, rather + // than a low-level JSON-RPC failure that would just abort. + return errorResult(err.Error()), nil + } + + respJSON, err := (protojson.MarshalOptions{UseProtoNames: true, EmitUnpopulated: true}).Marshal(respMsg) + if err != nil { + return errorResult("encode response: " + err.Error()), nil + } + // Surface as both Content (text-shaped) and StructuredContent so MCP + // clients that prefer either get something they can consume. + var structured any + _ = json.Unmarshal(respJSON, &structured) + return &mcp.CallToolResult{ + Content: []mcp.Content{&mcp.TextContent{Text: string(respJSON)}}, + StructuredContent: structured, + }, nil + }) +} + +func ptrTrue() *bool { v := true; return &v } + +// errorResult wraps a message as a CallToolResult with IsError set. This is +// the MCP-spec way to tell the host that the tool *ran* but produced a +// recoverable error (vs the JSON-RPC-level error path which signals a +// protocol/transport failure). +func errorResult(msg string) *mcp.CallToolResult { + return &mcp.CallToolResult{ + IsError: true, + Content: []mcp.Content{&mcp.TextContent{Text: msg}}, + } +} + +// isJSONNull returns true when the raw JSON encodes a literal `null`, with +// any surrounding whitespace tolerated. +func isJSONNull(raw json.RawMessage) bool { + s := strings.TrimSpace(string(raw)) + return s == "null" +} + +// compile-time assertion that ToolBinding messages descriptors implement what we need. +var _ proto.Message = (*dynamicpb.Message)(nil) diff --git a/internal/parsers/url.go b/internal/parsers/url.go index ddbfb0d8..24b29c70 100644 --- a/internal/parsers/url.go +++ b/internal/parsers/url.go @@ -1,17 +1,26 @@ package parsers import ( + "net/http" "net/url" "strings" "github.com/gin-gonic/gin" ) -// GetHost returns the authorizer host URL from the request context. -// Priority: X-Authorizer-URL header, then scheme (X-Forwarded-Proto) + host (X-Forwarded-Host or Request.Host). -// Headers are validated to prevent host header injection attacks. +// GetHost returns the authorizer host URL from the gin request context. +// Thin shim over GetHostFromRequest so non-gin transports (gRPC, plain HTTP) +// can reuse the same host-derivation logic. func GetHost(c *gin.Context) string { - authorizerURL := strings.TrimSpace(c.Request.Header.Get("X-Authorizer-URL")) + return GetHostFromRequest(c.Request) +} + +// GetHostFromRequest returns the authorizer host URL from a raw *http.Request. +// Priority: X-Authorizer-URL header, then scheme (X-Forwarded-Proto) + host +// (X-Forwarded-Host or Request.Host). Headers are validated to prevent host +// header injection attacks. +func GetHostFromRequest(r *http.Request) string { + authorizerURL := strings.TrimSpace(r.Header.Get("X-Authorizer-URL")) if authorizerURL != "" { if sanitized := sanitizeAuthorizerURL(authorizerURL); sanitized != "" { return sanitized @@ -19,13 +28,13 @@ func GetHost(c *gin.Context) string { // Invalid header value — fall through to standard host detection } - scheme := c.Request.Header.Get("X-Forwarded-Proto") + scheme := r.Header.Get("X-Forwarded-Proto") if scheme != "https" { scheme = "http" } - host := sanitizeHost(c.Request.Header.Get("X-Forwarded-Host")) + host := sanitizeHost(r.Header.Get("X-Forwarded-Host")) if host == "" { - host = sanitizeHost(c.Request.Host) + host = sanitizeHost(r.Host) } if host == "" { host = "localhost" @@ -131,6 +140,10 @@ func GetDomainName(uri string) string { // GetAppURL to get /app url if not configured by user func GetAppURL(gc *gin.Context) string { - envAppURL := GetHost(gc) + "/app" - return envAppURL + return GetAppURLFromRequest(gc.Request) +} + +// GetAppURLFromRequest is the transport-agnostic form of GetAppURL. +func GetAppURLFromRequest(r *http.Request) string { + return GetHostFromRequest(r) + "/app" } diff --git a/internal/parsers/url_test.go b/internal/parsers/url_test.go index ca71fb48..5dffd83a 100644 --- a/internal/parsers/url_test.go +++ b/internal/parsers/url_test.go @@ -1,6 +1,7 @@ package parsers import ( + "net/http" "testing" "github.com/stretchr/testify/assert" @@ -60,3 +61,71 @@ func TestSanitizeHost(t *testing.T) { }) } } + +func TestGetHostFromRequest(t *testing.T) { + tests := []struct { + name string + headers map[string]string + host string + want string + }{ + { + name: "X-Authorizer-URL takes priority", + headers: map[string]string{ + "X-Authorizer-URL": "https://auth.example.com", + "X-Forwarded-Proto": "http", + "X-Forwarded-Host": "ignored.example.com", + }, + host: "request.example.com", + want: "https://auth.example.com", + }, + { + name: "falls back to X-Forwarded-Proto + X-Forwarded-Host", + headers: map[string]string{"X-Forwarded-Proto": "https", "X-Forwarded-Host": "edge.example.com"}, + host: "internal.example.com", + want: "https://edge.example.com", + }, + { + name: "ignores invalid X-Authorizer-URL", + headers: map[string]string{ + "X-Authorizer-URL": "user:pass@evil.example.com", + "X-Forwarded-Proto": "https", + "X-Forwarded-Host": "edge.example.com", + }, + host: "ignored", + want: "https://edge.example.com", + }, + { + name: "falls back to Request.Host", + headers: map[string]string{}, + host: "auth.example.com", + want: "http://auth.example.com", + }, + { + name: "defaults to localhost when nothing is set", + headers: map[string]string{}, + host: "", + want: "http://localhost", + }, + { + name: "rejects spoofed X-Forwarded-Host with path injection", + headers: map[string]string{"X-Forwarded-Host": "evil.example.com/path"}, + host: "auth.example.com", + want: "http://auth.example.com", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &http.Request{Host: tt.host, Header: http.Header{}} + for k, v := range tt.headers { + r.Header.Set(k, v) + } + assert.Equal(t, tt.want, GetHostFromRequest(r)) + }) + } +} + +func TestGetAppURLFromRequest(t *testing.T) { + r := &http.Request{Host: "auth.example.com", Header: http.Header{}} + assert.Equal(t, "http://auth.example.com/app", GetAppURLFromRequest(r)) +} diff --git a/internal/server/http_routes.go b/internal/server/http_routes.go index f619092b..29a862cf 100644 --- a/internal/server/http_routes.go +++ b/internal/server/http_routes.go @@ -3,10 +3,13 @@ package server import ( "encoding/json" "html/template" + "net/http" "path" "strings" "github.com/gin-gonic/gin" + + "github.com/authorizerdev/authorizer/gen/openapi" ) // spaBuildCacheMiddleware sets cache headers for SPA build assets: @@ -73,6 +76,27 @@ func (s *server) NewRouter() *gin.Engine { router.POST("/oauth/revoke", s.Dependencies.HTTPProvider.RevokeRefreshTokenHandler()) router.POST("/oauth/introspect", s.Dependencies.HTTPProvider.IntrospectHandler()) + // gRPC-gateway REST surface at /v1/*. Mounted only when the gRPC + // server is configured. Shares all gin middleware (CORS, security + // headers, rate limit, logging) automatically since the route group + // inherits them from `router.Use(...)` above. + if s.gatewayHandler != nil { + // The gateway's routes are registered with their full /v1/... path + // (driven by google.api.http annotations). Mount it as a catch-all + // under /v1 so gin matches the prefix and hands the full request + // path to grpc-gateway untouched. + gw := gin.WrapH(s.gatewayHandler) + router.Any("/v1/*path", gw) + + // OpenAPI spec — generated alongside the gRPC stubs by buf and + // embedded into the binary (so it works regardless of cwd: tests, + // containers, etc.). Path is intentionally separate from the + // gateway mux so it doesn't fight a /v1/openapi.json gateway route. + router.GET("/openapi.json", func(c *gin.Context) { + c.Data(http.StatusOK, "application/json", openapi.Spec()) + }) + } + // Set up template functions for JSON encoding. // Escape and