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 09767464..607bb6aa 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..64c13426 --- /dev/null +++ b/cmd/mcp.go @@ -0,0 +1,177 @@ +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/authorization" + "github.com/authorizerdev/authorizer/internal/constants" + "github.com/authorizerdev/authorizer/internal/email" + "github.com/authorizerdev/authorizer/internal/events" + "github.com/authorizerdev/authorizer/internal/grpcsrv" + "github.com/authorizerdev/authorizer/internal/mcp" + "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" +) + +// mcpArgs are the MCP-subcommand-only flags. The root command's flags +// (--database-type, --client-id, --jwt-secret, ...) are inherited by the +// subcommand automatically since they live on RootCmd. +var mcpArgs struct { + // bearer is propagated as `Authorization: Bearer ` on every + // outgoing gRPC call. Without it the MCP server runs anonymously — + // fine for the `meta` tool (public) but identity-bearing tools + // (`profile`, `permissions`) won't have a caller to attribute to. + bearer string +} + +// 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 --mcp-bearer=$TOKEN +// +// 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. +// +// Transport: STDIO ONLY. The MCP server has no auth/rate-limit interceptors +// of its own — the security model relies on the OS-level trust boundary of +// the subprocess. See internal/mcp/server.go's Server type comment. +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. Stdio is the only supported transport.", + Run: runMCP, +} + +func init() { + mcpCmd.Flags().StringVar(&mcpArgs.bearer, "mcp-bearer", "", + "Bearer token to attach to every outgoing gRPC call (carries the "+ + "user identity for tools like Profile / Permissions / Session). "+ + "When unset the MCP server runs anonymously; public tools (Meta) "+ + "still work but identity-bearing tools will fail authn.") + 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() + + // Wire all subsystems an MCP-exposed tool might need. As more ops + // migrate into internal/service, this list stays the same — the + // service-provider dependencies don't change per op, only the methods + // on the provider do. + storageProvider, err := storage.New(&rootArgs.config, &storage.Dependencies{Log: &log}) + if err != nil { + log.Fatal().Err(err).Msg("failed to create storage provider") + } + memoryStoreProvider, err := memory_store.New(&rootArgs.config, &memory_store.Dependencies{ + Log: &log, + StorageProvider: storageProvider, + }) + if err != nil { + log.Fatal().Err(err).Msg("failed to create memory store provider") + } + tokenProvider, err := token.New(&rootArgs.config, &token.Dependencies{ + Log: &log, + MemoryStoreProvider: memoryStoreProvider, + }) + if err != nil { + log.Fatal().Err(err).Msg("failed to create token provider") + } + emailProvider, err := email.New(&rootArgs.config, &email.Dependencies{ + Log: &log, + StorageProvider: storageProvider, + }) + if err != nil { + log.Fatal().Err(err).Msg("failed to create email provider") + } + smsProvider, err := sms.New(&rootArgs.config, &sms.Dependencies{Log: &log}) + if err != nil { + log.Fatal().Err(err).Msg("failed to create sms provider") + } + auditProvider := audit.New(&audit.Dependencies{ + Log: &log, + StorageProvider: storageProvider, + }) + eventsProvider, err := events.New(&rootArgs.config, &events.Dependencies{ + Log: &log, + StorageProvider: storageProvider, + }) + if err != nil { + log.Fatal().Err(err).Msg("failed to create events provider") + } + + authorizationProvider, err := authorization.New( + &authorization.Config{CacheTTL: 0}, + &authorization.Dependencies{ + Log: &log, + StorageProvider: storageProvider, + MemoryStoreProvider: memoryStoreProvider, + }, + ) + if err != nil { + log.Fatal().Err(err).Msg("failed to create authorization provider") + } + + svc, err := service.New(&rootArgs.config, &service.Dependencies{ + Log: &log, + AuditProvider: auditProvider, + AuthorizationProvider: authorizationProvider, + 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") + } + + 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(), mcp.Options{ + Name: "authorizer", + Version: constants.VERSION, + Bearer: mcpArgs.bearer, + }) + 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..6bcabd3a 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. + // GraphQL, gRPC, and REST surfaces all delegate to this. + serviceProvider, err := service.New(&rootArgs.config, &service.Dependencies{ + Log: &log, + AuditProvider: auditProvider, + AuthorizationProvider: authorizationProvider, + 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..f37abc41 --- /dev/null +++ b/gen/go/authorizer/v1/authorizer.pb.go @@ -0,0 +1,2825 @@ +// 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, 0xe6, 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, 0x60, 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, 0x16, 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..bbbc25cc --- /dev/null +++ b/gen/go/authorizer/v1/authorizer_grpc.pb.go @@ -0,0 +1,856 @@ +// 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. + // NOT exposed as an MCP tool — SessionResponse carries access_token, + // refresh_token, id_token, authenticator_secret, and recovery codes, + // none of which should land in an LLM transcript. (Security audit C1.) + 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. + // NOT exposed as an MCP tool — SessionResponse carries access_token, + // refresh_token, id_token, authenticator_secret, and recovery codes, + // none of which should land in an LLM transcript. (Security audit C1.) + 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..31ff63a6 --- /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.\nNOT exposed as an MCP tool — SessionResponse carries access_token,\nrefresh_token, id_token, authenticator_secret, and recovery codes,\nnone of which should land in an LLM transcript. (Security audit C1.)", + "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 820533ce..684d9e8f 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module github.com/authorizerdev/authorizer go 1.26.4 require ( + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260415201107-50325440f8f2.1 + buf.build/go/protovalidate v1.2.0 github.com/99designs/gqlgen v0.17.73 github.com/arangodb/go-driver v1.6.0 github.com/aws/aws-sdk-go-v2 v1.41.5 @@ -21,6 +23,8 @@ require ( github.com/gocql/gocql v1.6.0 github.com/golang-jwt/jwt/v4 v4.5.2 github.com/google/uuid v1.6.0 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 + github.com/modelcontextprotocol/go-sdk v1.6.1 github.com/pquerna/otp v1.4.0 github.com/prometheus/client_golang v1.23.2 github.com/redis/go-redis/v9 v9.6.3 @@ -32,9 +36,12 @@ require ( github.com/vektah/gqlparser/v2 v2.5.26 go.mongodb.org/mongo-driver v1.17.9 golang.org/x/crypto v0.52.0 - golang.org/x/oauth2 v0.30.0 + golang.org/x/oauth2 v0.36.0 golang.org/x/sync v0.20.0 golang.org/x/time v0.15.0 + google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa + google.golang.org/grpc v1.81.1 + google.golang.org/protobuf v1.36.11 gopkg.in/mail.v2 v2.3.1 gorm.io/driver/mysql v1.5.2 gorm.io/driver/postgres v1.6.0 @@ -43,8 +50,10 @@ require ( ) require ( + 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,8 +89,9 @@ 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/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/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect @@ -115,6 +125,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 +136,17 @@ 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/exp v0.0.0-20250813145105-42675adae3e6 // indirect golang.org/x/mod v0.35.0 // indirect golang.org/x/net v0.55.0 // indirect golang.org/x/sys v0.45.0 // indirect golang.org/x/text v0.37.0 // indirect golang.org/x/tools v0.44.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260523011958-0a33c5d7ca68 // 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 0c3a44c6..8ba7415f 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= @@ -81,6 +89,8 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4Yn github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/brianvoe/gofakeit/v6 v6.28.0 h1:Xib46XXuQfmlLS2EXRuJpqcw8St6qSZz75OUo0tgAW4= +github.com/brianvoe/gofakeit/v6 v6.28.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -133,6 +143,10 @@ github.com/glebarez/sqlite v1.10.0 h1:u4gt8y7OND/cCei/NMHmfbLxF6xP2wgKcT/BJf2pYk github.com/glebarez/sqlite v1.10.0/go.mod h1:IJ+lfSOmiekhQsFTJRx/lHtGYmCdtAiTaf5wI9u5uHA= github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -166,8 +180,9 @@ github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= 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-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= 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= @@ -176,17 +191,19 @@ github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -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 +215,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 +282,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= @@ -301,6 +322,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/robertkrimen/otto v0.2.1 h1:FVP0PJ0AHIjC+N4pKCG9yCDz6LHNPCwi/GKID5pGGF0= github.com/robertkrimen/otto v0.2.1/go.mod h1:UPwtJ1Xu7JrLcZjNWN8orJaM5n5YEtqL//farB5FlRY= +github.com/rodaine/protogofakeit v0.1.1 h1:ZKouljuRM3A+TArppfBqnH8tGZHOwM/pjvtXe9DaXH8= +github.com/rodaine/protogofakeit v0.1.1/go.mod h1:pXn/AstBYMaSfc1/RqH3N82pBuxtWgejz1AlYpY1mI0= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -308,6 +331,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,16 +380,32 @@ 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= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU= go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -376,8 +419,8 @@ 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.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= -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= @@ -397,8 +440,8 @@ 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.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= -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= @@ -456,10 +499,16 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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/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= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +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.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..9003a517 100644 --- a/internal/cookie/cookie.go +++ b/internal/cookie/cookie.go @@ -25,38 +25,87 @@ 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 +// DeleteSession sets session cookies to expire. func DeleteSession(gc *gin.Context, appCookieSecure bool, sameSite http.SameSite) { - secure := appCookieSecure - httpOnly := true - hostname := parsers.GetHost(gc) + for _, c := range BuildDeleteSessionCookies(parsers.GetHost(gc), appCookieSecure, sameSite) { + gc.SetSameSite(c.SameSite) + gc.SetCookie(c.Name, c.Value, c.MaxAge, c.Path, c.Domain, c.Secure, c.HttpOnly) + } +} + +// BuildDeleteSessionCookies returns the pair of zero-value, expired session +// cookies that cause browsers to delete the host-scoped and domain-scoped +// session cookies. Transport-agnostic mirror of DeleteSession. +func BuildDeleteSessionCookies(hostname string, appCookieSecure bool, sameSite http.SameSite) []*http.Cookie { host, _ := parsers.GetHostParts(hostname) domain := parsers.GetDomainName(hostname) if domain != "localhost" { domain = "." + domain } - - gc.SetSameSite(sameSite) - gc.SetCookie(constants.AppCookieName+"_session", "", -1, "/", host, secure, httpOnly) - gc.SetCookie(constants.AppCookieName+"_session_domain", "", -1, "/", domain, secure, httpOnly) + return []*http.Cookie{ + { + Name: constants.AppCookieName + "_session", + Value: "", + MaxAge: -1, + Path: "/", + Domain: host, + Secure: appCookieSecure, + HttpOnly: true, + SameSite: sameSite, + }, + { + Name: constants.AppCookieName + "_session_domain", + Value: "", + MaxAge: -1, + Path: "/", + Domain: domain, + Secure: appCookieSecure, + HttpOnly: true, + SameSite: sameSite, + }, + } } // GetSession gets the session cookie from context 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/logout.go b/internal/graphql/logout.go index 2c739539..83da52ae 100644 --- a/internal/graphql/logout.go +++ b/internal/graphql/logout.go @@ -3,55 +3,19 @@ package graphql import ( "context" - "github.com/authorizerdev/authorizer/internal/audit" - "github.com/authorizerdev/authorizer/internal/constants" - "github.com/authorizerdev/authorizer/internal/cookie" "github.com/authorizerdev/authorizer/internal/graph/model" - "github.com/authorizerdev/authorizer/internal/metrics" + "github.com/authorizerdev/authorizer/internal/service" "github.com/authorizerdev/authorizer/internal/utils" ) -// Logout is the method to logout a user. -// Permissions: authenticated:* +// Logout delegates to the transport-agnostic service layer. +// Permissions: authenticated user. func (g *graphqlProvider) Logout(ctx context.Context) (*model.Response, error) { - log := g.Log.With().Str("func", "Logout").Logger() - gc, err := utils.GinContextFromContext(ctx) + gc, _ := utils.GinContextFromContext(ctx) + res, side, err := g.ServiceProvider.Logout(ctx, service.MetaFromGin(gc)) if err != nil { - log.Debug().Err(err).Msg("Failed to get GinContext") return nil, err } - - tokenData, err := g.TokenProvider.GetUserIDFromSessionOrAccessToken(gc) - if err != nil { - log.Debug().Err(err).Msg("Failed to get user id from session or access token") - return nil, err - } - - sessionKey := tokenData.UserID - if tokenData.LoginMethod != "" { - sessionKey = tokenData.LoginMethod + ":" + tokenData.UserID - } - - if err = g.MemoryStoreProvider.DeleteUserSession(sessionKey, tokenData.Nonce); err != nil { - log.Debug().Err(err).Msg("Failed to delete user session") - return nil, err - } - cookie.DeleteSession(gc, g.Config.AppCookieSecure, cookie.ParseSameSite(g.Config.AppCookieSameSite)) - metrics.RecordAuthEvent(metrics.EventLogout, metrics.StatusSuccess) - metrics.ActiveSessions.Dec() - g.AuditProvider.LogEvent(audit.Event{ - Action: constants.AuditLogoutEvent, - ActorID: tokenData.UserID, - ActorType: constants.AuditActorTypeUser, - ResourceType: constants.AuditResourceTypeSession, - ResourceID: tokenData.UserID, - IPAddress: utils.GetIP(gc.Request), - UserAgent: utils.GetUserAgent(gc.Request), - }) - - res := &model.Response{ - Message: "Logged out successfully", - } - + service.ApplyToGin(gc, side) return res, nil } 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/permissions.go b/internal/graphql/permissions.go index 07c66077..ad72308e 100644 --- a/internal/graphql/permissions.go +++ b/internal/graphql/permissions.go @@ -2,61 +2,16 @@ package graphql import ( "context" - "fmt" - "strings" - "github.com/authorizerdev/authorizer/internal/authorization" - "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" ) -// Permissions is the method to get all permissions for the authenticated user. -// Permissions: authorized user +// Permissions delegates to the transport-agnostic service layer. +// Permissions: authenticated user. func (g *graphqlProvider) Permissions(ctx context.Context) ([]*model.Permission, error) { - log := g.Log.With().Str("func", "Permissions").Logger() - gc, err := utils.GinContextFromContext(ctx) - if err != nil { - log.Debug().Err(err).Msg("Failed to get GinContext") - return nil, err - } - - tokenData, err := g.TokenProvider.GetUserIDFromSessionOrAccessToken(gc) - if err != nil { - log.Debug().Err(err).Msg("Failed to get user from token") - return nil, fmt.Errorf("unauthorized") - } - - user, err := g.StorageProvider.GetUserByID(ctx, tokenData.UserID) - if err != nil { - log.Debug().Err(err).Msg("Failed to get user by ID") - return nil, err - } - - var roles []string - if user.Roles != "" { - roles = strings.Split(user.Roles, ",") - } - - principal := &authorization.Principal{ - ID: user.ID, - Type: constants.PrincipalTypeUser, - Roles: roles, - } - - resourceScopes, err := g.AuthorizationProvider.GetPrincipalPermissions(ctx, principal) - if err != nil { - log.Debug().Err(err).Msg("Failed to get principal permissions") - return nil, err - } - - res := make([]*model.Permission, len(resourceScopes)) - for i, rs := range resourceScopes { - res[i] = &model.Permission{ - Resource: rs.Resource, - Scope: rs.Scope, - } - } - - return res, nil + gc, _ := utils.GinContextFromContext(ctx) + res, _, err := g.ServiceProvider.Permissions(ctx, service.MetaFromGin(gc)) + return res, err } diff --git a/internal/graphql/profile.go b/internal/graphql/profile.go index ebcb4926..d2aaecbe 100644 --- a/internal/graphql/profile.go +++ b/internal/graphql/profile.go @@ -4,29 +4,14 @@ import ( "context" "github.com/authorizerdev/authorizer/internal/graph/model" + "github.com/authorizerdev/authorizer/internal/service" "github.com/authorizerdev/authorizer/internal/utils" ) -// Profile is the method to get the profile of a user. +// Profile delegates to the transport-agnostic service layer. +// Permissions: authenticated user. func (g *graphqlProvider) Profile(ctx context.Context) (*model.User, error) { - log := g.Log.With().Str("func", "Profile").Logger() - - gc, err := utils.GinContextFromContext(ctx) - if err != nil { - log.Debug().Err(err).Msg("Failed to get GinContext") - return nil, err - } - tokenData, err := g.TokenProvider.GetUserIDFromSessionOrAccessToken(gc) - if err != nil { - log.Debug().Err(err).Msg("Failed to get user id from session or access token") - return nil, err - } - log = log.With().Str("user_id", tokenData.UserID).Logger() - user, err := g.StorageProvider.GetUserByID(ctx, tokenData.UserID) - if err != nil { - log.Debug().Err(err).Msg("Failed to get user by id") - return nil, err - } - - return user.AsAPIUser(), nil + gc, _ := utils.GinContextFromContext(ctx) + res, _, err := g.ServiceProvider.Profile(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/revoke.go b/internal/graphql/revoke.go index 3eb11c85..c9df7d56 100644 --- a/internal/graphql/revoke.go +++ b/internal/graphql/revoke.go @@ -2,66 +2,15 @@ package graphql import ( "context" - "errors" - "strings" - "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" ) -// Revoke is the method to revoke refresh token +// Revoke delegates to the transport-agnostic service layer. func (g *graphqlProvider) Revoke(ctx context.Context, params *model.OAuthRevokeRequest) (*model.Response, error) { - log := g.Log.With().Str("func", "Revoke").Logger() - token := strings.TrimSpace(params.RefreshToken) - if token == "" { - log.Error().Msg("Refresh token is empty") - return nil, errors.New("missing refresh token") - } - claims, err := g.TokenProvider.ParseJWTToken(token) - if err != nil { - log.Debug().Err(err).Msg("failed to parse jwt") - return nil, err - } - - userID, ok := claims["sub"].(string) - if !ok || userID == "" { - log.Debug().Msg("Invalid subject in token") - return nil, errors.New("invalid token") - } - loginMethod := claims["login_method"] - sessionToken := userID - if lm, ok := loginMethod.(string); ok && lm != "" { - sessionToken = lm + ":" + userID - } - - nonce, ok := claims["nonce"].(string) - if !ok || nonce == "" { - log.Debug().Msg("Invalid nonce in token") - return nil, errors.New("invalid token") - } - - existingToken, err := g.MemoryStoreProvider.GetUserSession(sessionToken, constants.TokenTypeRefreshToken+"_"+nonce) - if err != nil { - log.Debug().Err(err).Msg("Failed to get refresh token") - return nil, err - } - - if existingToken == "" { - log.Debug().Msg("Token not found") - return nil, errors.New("token not found") - } - - if existingToken != token { - log.Debug().Msg("Token does not match") - return nil, errors.New("token does not match") - } - - // Remove the token from the memory store - if err := g.MemoryStoreProvider.DeleteUserSession(sessionToken, nonce); err != nil { - log.Debug().Err(err).Msg("failed to delete user session") - return nil, err - } - return &model.Response{ - Message: "Token revoked", - }, nil + gc, _ := utils.GinContextFromContext(ctx) + res, _, err := g.ServiceProvider.Revoke(ctx, service.MetaFromGin(gc), params) + return res, err } diff --git a/internal/graphql/session.go b/internal/graphql/session.go index 2539f434..37cdaf82 100644 --- a/internal/graphql/session.go +++ b/internal/graphql/session.go @@ -2,167 +2,20 @@ package graphql import ( "context" - "errors" - "fmt" - "strings" - "time" - "github.com/google/uuid" - - "github.com/authorizerdev/authorizer/internal/constants" - "github.com/authorizerdev/authorizer/internal/cookie" "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/token" + "github.com/authorizerdev/authorizer/internal/service" "github.com/authorizerdev/authorizer/internal/utils" ) -// Session is the method to get session. -// It also refreshes the session token. -// TODO allow validating with code and code verifier instead of cookie (PKCE flow) +// Session delegates to the transport-agnostic service layer; the rotated +// session cookie is applied back to the gin response from side-effects. func (g *graphqlProvider) Session(ctx context.Context, params *model.SessionQueryRequest) (*model.AuthResponse, error) { - log := g.Log.With().Str("func", "Session").Logger() - gc, err := utils.GinContextFromContext(ctx) - if err != nil { - log.Debug().Err(err).Msg("Failed to get GinContext") - return nil, err - } - - sessionToken, err := cookie.GetSession(gc) - if err != nil { - log.Debug().Err(err).Msg("Failed to get session token") - return nil, errors.New("unauthorized") - } - - // get session from cookie - claims, err := g.TokenProvider.ValidateBrowserSession(gc, sessionToken) - if err != nil { - log.Debug().Err(err).Msg("Failed to validate session token") - return nil, errors.New("unauthorized") - } - userID := claims.Subject - log = log.With().Str("user_id", userID).Logger() - user, err := g.StorageProvider.GetUserByID(ctx, userID) - if err != nil { - log.Debug().Err(err).Msg("Failed to get user") - return nil, err - } - - // refresh token has "roles" as claim - claimRoleInterface := claims.Roles - claimRoles := []string{} - claimRoles = append(claimRoles, claimRoleInterface...) - - if params != nil && params.Roles != nil && len(params.Roles) > 0 { - for _, v := range params.Roles { - if !utils.StringSliceContains(claimRoles, v) { - log.Debug().Msg("User does not have required role") - return nil, fmt.Errorf(`unauthorized`) - } - } - } - - if params != nil { - if err := g.enforceRequiredPermissions(ctx, log, metrics.RequiredPermissionsEndpointSession, user.ID, claimRoles, params.RequiredPermissions); err != nil { - return nil, err - } - } - - scope := []string{"openid", "email", "profile"} - if params != nil && params.Scope != nil && len(params.Scope) > 0 { - scope = params.Scope - } - - // OIDC authorize flow: if state is provided, consume the authorize state - // and prepare code/challenge data so the authorization code can be stored - // after token creation. This handles the case where the login UI auto-detects - // an existing session (e.g., prompt=login forced re-auth at /authorize but - // the session cookie is still valid for GraphQL queries). - code := "" - codeChallenge := "" - oidcNonce := "" - authorizeRedirectURI := "" - if params != nil && params.State != nil { - 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] - } - } - g.MemoryStoreProvider.RemoveState(refs.StringValue(params.State)) - } - } - - nonce := uuid.New().String() - hostname := parsers.GetHost(gc) - authToken, err := g.TokenProvider.CreateAuthToken(gc, &token.AuthTokenConfig{ - User: user, - Nonce: nonce, - OIDCNonce: oidcNonce, - Code: code, - Roles: claimRoles, - Scope: scope, - LoginMethod: claims.LoginMethod, - HostName: hostname, - }) + gc, _ := utils.GinContextFromContext(ctx) + res, side, err := g.ServiceProvider.Session(ctx, service.MetaFromGin(gc), params) if err != nil { - log.Debug().Err(err).Msg("Failed to CreateAuthToken") return nil, err } - - // Store the authorization code state so /oauth/token can find it. - // The authorizeRedirectURI is already URL-encoded from the authorize state. - if code != "" { - if err := g.MemoryStoreProvider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash+"@@"+oidcNonce+"@@"+authorizeRedirectURI); err != nil { - log.Debug().Err(err).Msg("Failed to set code state") - return nil, err - } - } - - sessionKey := userID - if claims.LoginMethod != "" { - sessionKey = claims.LoginMethod + ":" + userID - } - - expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix() - if expiresIn <= 0 { - expiresIn = 1 - } - - res := &model.AuthResponse{ - Message: `Session token refreshed`, - AccessToken: &authToken.AccessToken.Token, - ExpiresIn: &expiresIn, - IDToken: &authToken.IDToken.Token, - User: user.AsAPIUser(), - } - - // Establish the new session first, then revoke the old one. Doing both - // synchronously closes the window where a stolen pre-rotation token - // remains valid alongside the rotated one; doing "new then old" avoids - // any moment where the user has no valid session token. DeleteUserSession - // is in-memory or a single Redis DEL — failure is non-fatal (log and - // continue) since the new session is already live. - 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) - } - - if err := g.MemoryStoreProvider.DeleteUserSession(sessionKey, claims.Nonce); err != nil { - log.Warn().Err(err).Str("session_key", sessionKey).Msg("failed to delete old session during rollover") - } + service.ApplyToGin(gc, side) return res, nil } 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/graphql/validate_jwt_token.go b/internal/graphql/validate_jwt_token.go index 8b17ff50..8a815742 100644 --- a/internal/graphql/validate_jwt_token.go +++ b/internal/graphql/validate_jwt_token.go @@ -2,135 +2,15 @@ package graphql import ( "context" - "errors" - "fmt" - "github.com/golang-jwt/jwt/v4" - - "github.com/authorizerdev/authorizer/internal/constants" "github.com/authorizerdev/authorizer/internal/graph/model" - "github.com/authorizerdev/authorizer/internal/metrics" - "github.com/authorizerdev/authorizer/internal/parsers" - "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" ) -// ValidateJwtToken is used to validate a jwt token without its rotation -// this can be used at API level (backend) -// it can validate: -// access_token -// id_token -// refresh_token -// Permission: none +// ValidateJWTToken delegates to the transport-agnostic service layer. func (g *graphqlProvider) ValidateJWTToken(ctx context.Context, params *model.ValidateJWTTokenRequest) (*model.ValidateJWTTokenResponse, error) { - log := g.Log.With().Str("func", "ValidateJWTToken").Logger() - gc, err := utils.GinContextFromContext(ctx) - if err != nil { - log.Debug().Err(err).Msg("Failed to get GinContext") - return nil, err - } - - tokenType := params.TokenType - if tokenType != constants.TokenTypeAccessToken && tokenType != constants.TokenTypeRefreshToken && tokenType != constants.TokenTypeIdentityToken { - log.Debug().Str("token_type", tokenType).Msg("Invalid token type") - return nil, errors.New("invalid token type") - } - - var claimRoles []string - var claims jwt.MapClaims - userID := "" - nonce := "" - - claims, err = g.TokenProvider.ParseJWTToken(params.Token) - if err != nil { - log.Debug().Err(err).Msg("Failed to parse jwt token") - return nil, err - } - sub, ok := claims["sub"].(string) - if !ok || sub == "" { - log.Debug().Msg("Invalid subject in token") - return nil, errors.New("invalid token") - } - userID = sub - - // access_token and refresh_token should be validated from session store as well - if tokenType == constants.TokenTypeAccessToken || tokenType == constants.TokenTypeRefreshToken { - nonceVal, ok := claims["nonce"].(string) - if !ok || nonceVal == "" { - log.Debug().Msg("Invalid nonce in token") - return nil, errors.New("invalid token") - } - nonce = nonceVal - loginMethod := claims["login_method"] - sessionKey := userID - if lm, ok := loginMethod.(string); ok && lm != "" { - sessionKey = lm + ":" + userID - } - token, err := g.MemoryStoreProvider.GetUserSession(sessionKey, tokenType+"_"+nonceVal) - if err != nil || token == "" { - log.Debug().Err(err).Msg("Failed to get token from session store") - return nil, errors.New("invalid token") - } - } - - hostname := parsers.GetHost(gc) - - // we cannot validate nonce in case of id_token as that token is not persisted in session store - if nonce != "" { - if ok, err := g.TokenProvider.ValidateJWTClaims(claims, &token.AuthTokenConfig{ - HostName: hostname, - Nonce: nonce, - User: &schemas.User{ - ID: userID, - }, - }); !ok || err != nil { - log.Debug().Err(err).Msg("Failed to validate jwt claims") - return nil, errors.New("invalid claims") - } - } else { - if ok, err := g.TokenProvider.ValidateJWTTokenWithoutNonce(claims, &token.AuthTokenConfig{ - HostName: hostname, - User: &schemas.User{ - ID: userID, - }, - }); !ok || err != nil { - log.Debug().Err(err).Msg("Failed to validate jwt claims") - return nil, errors.New("invalid claims") - } - } - - // Read roles from the configured claim key (used for id_token), falling - // back to the hardcoded "roles" claim that CreateAccessToken emits. This - // avoids a missing-roles principal when JWTRoleClaim is the default - // "role" (singular) but the token is an access_token (plural "roles"). - claimRolesInterface := claims[g.Config.JWTRoleClaim] - roleSlice := utils.ConvertInterfaceToSlice(claimRolesInterface) - if len(roleSlice) == 0 { - roleSlice = utils.ConvertInterfaceToSlice(claims["roles"]) - } - for _, v := range roleSlice { - roleStr, ok := v.(string) - if !ok || roleStr == "" { - log.Debug().Msg("Invalid role claim value") - return nil, errors.New("invalid claims") - } - claimRoles = append(claimRoles, roleStr) - } - - if len(params.Roles) > 0 { - for _, v := range params.Roles { - if !utils.StringSliceContains(claimRoles, v) { - log.Debug().Str("role", v).Msg("Role not found in claims") - return nil, fmt.Errorf(`unauthorized`) - } - } - } - if err := g.enforceRequiredPermissions(ctx, log, metrics.RequiredPermissionsEndpointValidateJWTToken, userID, claimRoles, params.RequiredPermissions); err != nil { - return nil, err - } - return &model.ValidateJWTTokenResponse{ - IsValid: true, - Claims: claims, - }, nil + gc, _ := utils.GinContextFromContext(ctx) + res, _, err := g.ServiceProvider.ValidateJwtToken(ctx, service.MetaFromGin(gc), params) + return res, err } diff --git a/internal/graphql/validate_session.go b/internal/graphql/validate_session.go index f5686cad..06fcbd4e 100644 --- a/internal/graphql/validate_session.go +++ b/internal/graphql/validate_session.go @@ -2,72 +2,15 @@ package graphql import ( "context" - "errors" - "fmt" - "github.com/authorizerdev/authorizer/internal/cookie" "github.com/authorizerdev/authorizer/internal/graph/model" - "github.com/authorizerdev/authorizer/internal/metrics" + "github.com/authorizerdev/authorizer/internal/service" "github.com/authorizerdev/authorizer/internal/utils" ) -// ValidateSession is used to validate a cookie session without its rotation -// Permission: authorized:user +// ValidateSession delegates to the transport-agnostic service layer. func (g *graphqlProvider) ValidateSession(ctx context.Context, params *model.ValidateSessionRequest) (*model.ValidateSessionResponse, error) { - log := g.Log.With().Str("func", "ValidateSession").Logger() - gc, err := utils.GinContextFromContext(ctx) - if err != nil { - log.Debug().Err(err).Msg("Failed to get GinContext") - return nil, err - } - sessionToken := "" - if params != nil && params.Cookie != "" { - sessionToken = params.Cookie - } else { - sessionToken, err = cookie.GetSession(gc) - if err != nil { - log.Debug().Err(err).Msg("Failed to get session token") - return nil, errors.New("unauthorized") - } - } - if sessionToken == "" { - sessionToken, err = cookie.GetSession(gc) - if err != nil { - log.Debug().Err(err).Msg("Failed to get session token") - return nil, errors.New("unauthorized") - } - } - claims, err := g.TokenProvider.ValidateBrowserSession(gc, sessionToken) - if err != nil { - log.Debug().Err(err).Msg("Failed to validate session") - return nil, errors.New("unauthorized") - } - userID := claims.Subject - log.Debug().Str("userID", userID).Msg("Validated session") - user, err := g.StorageProvider.GetUserByID(ctx, userID) - if err != nil { - log.Debug().Err(err).Msg("failed GetUserByID") - return nil, err - } - // refresh token has "roles" as claim - claimRoleInterface := claims.Roles - claimRoles := []string{} - claimRoles = append(claimRoles, claimRoleInterface...) - if params != nil && params.Roles != nil && len(params.Roles) > 0 { - for _, v := range params.Roles { - if !utils.StringSliceContains(claimRoles, v) { - log.Debug().Str("role", v).Msg("Role not found in claims") - return nil, fmt.Errorf(`unauthorized`) - } - } - } - if params != nil { - if err := g.enforceRequiredPermissions(ctx, log, metrics.RequiredPermissionsEndpointValidateSession, user.ID, claimRoles, params.RequiredPermissions); err != nil { - return nil, err - } - } - return &model.ValidateSessionResponse{ - IsValid: true, - User: user.AsAPIUser(), - }, nil + gc, _ := utils.GinContextFromContext(ctx) + res, _, err := g.ServiceProvider.ValidateSession(ctx, service.MetaFromGin(gc), params) + return res, err } diff --git a/internal/grpcsrv/handlers/authorizer.go b/internal/grpcsrv/handlers/authorizer.go new file mode 100644 index 00000000..4fe5950b --- /dev/null +++ b/internal/grpcsrv/handlers/authorizer.go @@ -0,0 +1,163 @@ +// 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" + + authorizerv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/v1" + "github.com/authorizerdev/authorizer/internal/graph/model" + "github.com/authorizerdev/authorizer/internal/grpcsrv/transport" + "github.com/authorizerdev/authorizer/internal/refs" + "github.com/authorizerdev/authorizer/internal/service" +) + +// 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 +} + +// Revoke delegates to service.Revoke and projects the result. +func (h *AuthorizerHandler) Revoke(ctx context.Context, req *authorizerv1.RevokeRequest) (*authorizerv1.RevokeResponse, error) { + res, _, err := h.Service.Revoke(ctx, transport.MetaFromGRPC(ctx), &model.OAuthRevokeRequest{RefreshToken: req.RefreshToken}) + if err != nil { + return nil, err + } + return &authorizerv1.RevokeResponse{Message: res.Message}, nil +} + +// ValidateJwtToken delegates to service.ValidateJwtToken. The JWT claims +// map (free-form) is projected to AppData (which wraps Struct) to preserve +// the existing GraphQL semantics. +func (h *AuthorizerHandler) ValidateJwtToken(ctx context.Context, req *authorizerv1.ValidateJwtTokenRequest) (*authorizerv1.ValidateJwtTokenResponse, error) { + res, _, err := h.Service.ValidateJwtToken(ctx, transport.MetaFromGRPC(ctx), &model.ValidateJWTTokenRequest{ + TokenType: req.TokenType, + Token: req.Token, + Roles: req.Roles, + RequiredPermissions: protoToModelPermissions(req.RequiredPermissions), + }) + if err != nil { + return nil, err + } + return &authorizerv1.ValidateJwtTokenResponse{ + IsValid: res.IsValid, + Claims: claimsToAppData(res.Claims), + }, nil +} + +// ValidateSession delegates to service.ValidateSession. +func (h *AuthorizerHandler) ValidateSession(ctx context.Context, req *authorizerv1.ValidateSessionRequest) (*authorizerv1.ValidateSessionResponse, error) { + res, _, err := h.Service.ValidateSession(ctx, transport.MetaFromGRPC(ctx), &model.ValidateSessionRequest{ + Cookie: req.Cookie, + Roles: req.Roles, + RequiredPermissions: protoToModelPermissions(req.RequiredPermissions), + }) + if err != nil { + return nil, err + } + return &authorizerv1.ValidateSessionResponse{ + IsValid: res.IsValid, + User: projectUser(res.User), + }, nil +} + +// Session delegates to service.Session, applies the rotated session cookie +// to the outgoing stream, and projects the AuthResponse. SessionResponse +// carries credentials and is intentionally NOT MCP-exposed (audit C1). +func (h *AuthorizerHandler) Session(ctx context.Context, req *authorizerv1.SessionRequest) (*authorizerv1.SessionResponse, error) { + res, side, err := h.Service.Session(ctx, transport.MetaFromGRPC(ctx), &model.SessionQueryRequest{ + Roles: req.Roles, + Scope: req.Scope, + State: refs.NewStringRef(req.State), + RequiredPermissions: protoToModelPermissions(req.RequiredPermissions), + }) + if err != nil { + return nil, err + } + _ = transport.ApplyToGRPC(ctx, side) + return &authorizerv1.SessionResponse{Auth: projectAuthResponse(res)}, nil +} + +// Profile delegates to service.Profile and projects the result into the +// proto ProfileResponse. Requires session/bearer auth (handled inside the +// service via TokenProvider.GetUserIDFromSessionOrAccessToken). +func (h *AuthorizerHandler) Profile(ctx context.Context, _ *authorizerv1.ProfileRequest) (*authorizerv1.ProfileResponse, error) { + u, _, err := h.Service.Profile(ctx, transport.MetaFromGRPC(ctx)) + if err != nil { + return nil, err + } + return &authorizerv1.ProfileResponse{User: projectUser(u)}, nil +} + +// Permissions delegates to service.Permissions and projects the result into +// the proto PermissionsResponse. +func (h *AuthorizerHandler) Permissions(ctx context.Context, _ *authorizerv1.PermissionsRequest) (*authorizerv1.PermissionsResponse, error) { + perms, _, err := h.Service.Permissions(ctx, transport.MetaFromGRPC(ctx)) + if err != nil { + return nil, err + } + out := make([]*authorizerv1.Permission, len(perms)) + for i, p := range perms { + out[i] = &authorizerv1.Permission{Resource: p.Resource, Scope: p.Scope} + } + return &authorizerv1.PermissionsResponse{Permissions: out}, nil +} + +// Logout delegates to service.Logout, applies any cookie side-effects to +// the outgoing gRPC stream (grpc-gateway lifts them to Set-Cookie when +// the call came in via REST), then returns the typed response. +func (h *AuthorizerHandler) Logout(ctx context.Context, _ *authorizerv1.LogoutRequest) (*authorizerv1.LogoutResponse, error) { + res, side, err := h.Service.Logout(ctx, transport.MetaFromGRPC(ctx)) + if err != nil { + return nil, err + } + // Best-effort: cookie application is out-of-band; a SendHeader failure + // degrades to "user has to re-auth" rather than failing the request. + _ = transport.ApplyToGRPC(ctx, side) + return &authorizerv1.LogoutResponse{Message: res.Message}, nil +} + +// 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/handlers/project.go b/internal/grpcsrv/handlers/project.go new file mode 100644 index 00000000..6d4dd4f8 --- /dev/null +++ b/internal/grpcsrv/handlers/project.go @@ -0,0 +1,157 @@ +// Package-internal projection helpers: convert the GraphQL/storage model +// types returned by service.* into the proto wire types. Centralised here +// so each handler can stay focused on its delegation pattern. +package handlers + +import ( + "encoding/json" + + "google.golang.org/protobuf/types/known/structpb" + + "github.com/authorizerdev/authorizer/internal/graph/model" + "github.com/authorizerdev/authorizer/internal/refs" + + commonv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/common/v1" + authorizerv1 "github.com/authorizerdev/authorizer/gen/go/authorizer/v1" +) + +// projectUser converts the GraphQL User model into the proto User message. +// Optional fields (nil pointers / nil maps) collapse to zero values; the +// gateway's UseProtoNames + EmitUnpopulated configuration makes them +// visible to REST clients regardless. +func projectUser(u *model.User) *authorizerv1.User { + if u == nil { + return nil + } + out := &authorizerv1.User{ + Id: u.ID, + Email: refs.StringValue(u.Email), + EmailVerified: u.EmailVerified, + SignupMethods: u.SignupMethods, + GivenName: refs.StringValue(u.GivenName), + FamilyName: refs.StringValue(u.FamilyName), + MiddleName: refs.StringValue(u.MiddleName), + Nickname: refs.StringValue(u.Nickname), + PreferredUsername: refs.StringValue(u.PreferredUsername), + Gender: refs.StringValue(u.Gender), + Birthdate: refs.StringValue(u.Birthdate), + PhoneNumber: refs.StringValue(u.PhoneNumber), + PhoneNumberVerified: u.PhoneNumberVerified, + Picture: refs.StringValue(u.Picture), + Roles: u.Roles, + CreatedAt: refs.Int64Value(u.CreatedAt), + UpdatedAt: refs.Int64Value(u.UpdatedAt), + RevokedTimestamp: refs.Int64Value(u.RevokedTimestamp), + IsMultiFactorAuthEnabled: refs.BoolValue(u.IsMultiFactorAuthEnabled), + } + if u.AppData != nil { + out.AppData = projectAppData(u.AppData) + } + return out +} + +// projectAuthResponse converts the GraphQL AuthResponse model into the +// proto AuthResponse. Used by the Session handler; the credential fields +// (tokens, authenticator secret/recovery codes) are passed through to gRPC +// + REST callers but the proto annotation on Session intentionally keeps +// it OFF the MCP surface (security audit C1). +func projectAuthResponse(a *model.AuthResponse) *authorizerv1.AuthResponse { + if a == nil { + return nil + } + return &authorizerv1.AuthResponse{ + Message: a.Message, + ShouldShowEmailOtpScreen: refs.BoolValue(a.ShouldShowEmailOtpScreen), + ShouldShowMobileOtpScreen: refs.BoolValue(a.ShouldShowMobileOtpScreen), + ShouldShowTotpScreen: refs.BoolValue(a.ShouldShowTotpScreen), + AccessToken: refs.StringValue(a.AccessToken), + IdToken: refs.StringValue(a.IDToken), + RefreshToken: refs.StringValue(a.RefreshToken), + ExpiresIn: refs.Int64Value(a.ExpiresIn), + User: projectUser(a.User), + AuthenticatorScannerImage: refs.StringValue(a.AuthenticatorScannerImage), + AuthenticatorSecret: refs.StringValue(a.AuthenticatorSecret), + AuthenticatorRecoveryCodes: derefStringSlice(a.AuthenticatorRecoveryCodes), + } +} + +// projectAppData converts the free-form GraphQL Map into the proto AppData +// (which wraps a google.protobuf.Struct). The conversion uses JSON as the +// lingua franca, matching how AppData is persisted today. +func projectAppData(m map[string]any) *commonv1.AppData { + if len(m) == 0 { + return nil + } + // Round-trip via JSON so anything Struct can't represent natively + // (e.g. nested numbers > int64) gets surfaced consistently. + b, err := json.Marshal(m) + if err != nil { + return nil + } + var generic map[string]any + if err := json.Unmarshal(b, &generic); err != nil { + return nil + } + s, err := structpb.NewStruct(generic) + if err != nil { + return nil + } + return &commonv1.AppData{Value: s} +} + +// derefStringSlice converts []*string (GraphQL's nullable string list shape) +// into []string, dropping nil entries. +func derefStringSlice(in []*string) []string { + if len(in) == 0 { + return nil + } + out := make([]string, 0, len(in)) + for _, s := range in { + if s != nil { + out = append(out, *s) + } + } + return out +} + +// protoToModelPermissions converts the proto PermissionInput repeated field +// into the GraphQL model.PermissionInput slice used by service methods. +func protoToModelPermissions(in []*authorizerv1.PermissionInput) []*model.PermissionInput { + if len(in) == 0 { + return nil + } + out := make([]*model.PermissionInput, 0, len(in)) + for _, p := range in { + if p == nil { + continue + } + out = append(out, &model.PermissionInput{ + Resource: p.Resource, + Scope: p.Scope, + }) + } + return out +} + +// claimsToAppData converts a free-form JWT claims map (interface{}-valued) +// into the proto AppData wrapper around google.protobuf.Struct. JSON is the +// lingua franca — matches projectAppData's strategy and tolerates anything +// the underlying JWT library produces. +func claimsToAppData(claims map[string]any) *commonv1.AppData { + if len(claims) == 0 { + return nil + } + b, err := json.Marshal(claims) + if err != nil { + return nil + } + var generic map[string]any + if err := json.Unmarshal(b, &generic); err != nil { + return nil + } + s, err := structpb.NewStruct(generic) + if err != nil { + return nil + } + return &commonv1.AppData{Value: s} +} diff --git a/internal/grpcsrv/interceptors/interceptors_test.go b/internal/grpcsrv/interceptors/interceptors_test.go new file mode 100644 index 00000000..d5b02e84 --- /dev/null +++ b/internal/grpcsrv/interceptors/interceptors_test.go @@ -0,0 +1,161 @@ +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") + out := buf.String() + // The stack + type get logged. The recovered VALUE does NOT — security + // audit H2: panic values can carry credentials (Password / RefreshToken + // / OTP / AdminSecret) that must not reach the log stream. + assert.Contains(t, out, "panicked") + assert.Contains(t, out, `"panic_type":"string"`) + assert.NotContains(t, out, "kaboom", + "the panic VALUE must not appear in logs; only its type — see H2") +} + +// TestRecovery_DoesNotLogCredentialBearingPanicValue is the regression test +// for security audit H2: a handler that panics with a value containing +// credentials must NOT have those credentials written to the log stream. +func TestRecovery_DoesNotLogCredentialBearingPanicValue(t *testing.T) { + var buf bytes.Buffer + log := zerolog.New(&buf) + r := Recovery(&log) + _, _ = r(context.Background(), nil, info("/svc/X"), func(_ context.Context, _ any) (any, error) { + // Simulate a handler panicking with a credential-bearing value. + panic("password=hunter2 token=secretXYZ") + }) + out := buf.String() + assert.NotContains(t, out, "hunter2", "panic value must not reach logs") + assert.NotContains(t, out, "secretXYZ", "panic value must not reach logs") + assert.Contains(t, out, `"panic_type":"string"`, "type should still be logged for triage") +} + +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..01e73805 --- /dev/null +++ b/internal/grpcsrv/interceptors/recovery.go @@ -0,0 +1,46 @@ +// 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" + "fmt" + "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. +// +// Security: the panic value is logged as TYPE only, never its full content. +// A handler can panic with a request struct that includes credentials +// (Password, RefreshToken, OTP, AdminSecret, ...); dumping the value via +// .Interface() would write those credentials to the log stream verbatim. +// Logging just the type lets ops correlate the panic with the stack without +// exposing payload fields. (Security audit finding H2.) +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). + Str("panic_type", fmt.Sprintf("%T", 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..99ed4c8a --- /dev/null +++ b/internal/integration_tests/grpc_surface_test.go @@ -0,0 +1,130 @@ +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. +// Real today: Meta, Profile, Permissions, Logout, Revoke, Session, +// ValidateJwtToken, ValidateSession (covered elsewhere). As each remaining +// method's handler is wired up, drop its entry below. +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 + }, + "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 + }, + "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 + }, + } + + 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..d1589b35 --- /dev/null +++ b/internal/integration_tests/mcp_stubs_test.go @@ -0,0 +1,65 @@ +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" +) + +// TestMCPToolErrorSurfacesAsIsErrorResult verifies that when the underlying +// gRPC handler returns a non-OK status, the MCP server surfaces it as a +// CallToolResult{IsError:true} (tool-level error) rather than as a +// JSON-RPC protocol error. This is the MCP-spec way to give the LLM +// actionable text it can react to (vs aborting the whole exchange). +// +// We exercise this by calling `permissions` without a bearer token; the +// underlying Permissions handler returns "unauthorized" from +// TokenProvider.GetUserIDFromSessionOrAccessToken. This is also a check +// that the MCP-side auth gating works (security audit H1): calling an +// identity-bearing tool with no Authorization metadata produces a clean, +// auditable error. +func TestMCPToolErrorSurfacesAsIsErrorResult(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) + // Note: opts.Bearer deliberately empty — the server runs anonymously, + // so identity-bearing tools must fail with a clean tool error. + mcpSrv, err := authmcp.New(&log, grpcSrv.GRPCServer(), authmcp.Options{Name: "authorizer-test", Version: "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() + + 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, "anonymous call to identity-bearing tool must return IsError=true") + require.NotEmpty(t, res.Content) + _, ok := res.Content[0].(*mcp.TextContent) + require.True(t, ok, "error content should be text") +} diff --git a/internal/integration_tests/mcp_test.go b/internal/integration_tests/mcp_test.go new file mode 100644 index 00000000..17a634eb --- /dev/null +++ b/internal/integration_tests/mcp_test.go @@ -0,0 +1,89 @@ +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(), authmcp.Options{Name: "authorizer-test", Version: "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 three proto-annotated MCP tools: + // meta, profile, permissions. (Session was DROPPED from MCP exposure + // in the security pass; its response carries credentials that + // shouldn't land in an LLM transcript — audit finding C1.) + 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", "permissions"} { + require.True(t, gotNames[want], "expected MCP tool %q to be exposed; got %v", want, gotNames) + } + require.False(t, gotNames["session"], + "session tool MUST NOT be exposed via MCP (carries access_token/refresh_token/etc.)") + + // 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..2b16391b 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,20 @@ func initTestSetup(t *testing.T, cfg *config.Config) *testSetup { StorageProvider: storageProvider, }) + // Transport-agnostic service layer for migrated public ops. + serviceProvider, err := service.New(cfg, &service.Dependencies{ + Log: &logger, + AuditProvider: auditProvider, + AuthorizationProvider: authzProvider, + 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 +234,7 @@ func initTestSetup(t *testing.T, cfg *config.Config) *testSetup { SMSProvider: smsProvider, StorageProvider: storageProvider, TokenProvider: tokenProvider, + ServiceProvider: serviceProvider, } // Create dependencies struct @@ -234,6 +250,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..8d151463 --- /dev/null +++ b/internal/mcp/server.go @@ -0,0 +1,217 @@ +// Package mcp serves a curated subset of Authorizer's gRPC methods to +// LLM clients via the Model Context Protocol. Stdio is the ONLY supported +// transport — see the deliberate design note on Server below. +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/metadata" + "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. +// +// Design constraint: stdio is the ONLY supported transport. The MCP server +// has no auth/rate-limit/audit interceptors of its own — it relies entirely +// on the OS-level trust boundary of the subprocess (Claude Code spawns +// `authorizer mcp` as a child; only that process can write to its stdin). +// Exposing the MCP server over TCP / HTTP / SSE would invalidate that +// assumption and is intentionally NOT implementable: there is no RunHTTP / +// RunTCP / RunSSE method, and adding one without first implementing an +// auth layer is a security regression. The stdio-only contract is also +// enforced by TestServer_StdioOnly. +type Server struct { + log *zerolog.Logger + mcpSrv *mcp.Server + gwConn *grpc.ClientConn + lis *bufconn.Listener + grpcSrv *grpc.Server + + // bearer is the value of the Authorization header stamped on every + // outgoing gRPC call. Set via Options.Bearer at construction time + // (the cmd/mcp.go subcommand exposes --mcp-bearer). When empty, calls + // flow without auth — fine for public methods like Meta, but anything + // requiring identity (Profile, Permissions, ...) will see an empty + // caller and return whatever its handler does in that case. + bearer string +} + +// Options configures the MCP server. +type Options struct { + // Name is the MCP server's reported implementation name. + Name string + // Version is the MCP server's reported implementation version. + Version string + // Bearer, when set, is propagated as `Authorization: Bearer ` + // metadata on every gRPC dispatch. This is how MCP-side identity + // reaches the gRPC handlers (security audit H1). The bearer should be + // a token issued for the user the MCP host is acting on behalf of. + Bearer string +} + +// 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, opts Options) (*Server, error) { + bindings, err := Scan(grpcSrv) + if err != nil { + return nil, fmt.Errorf("mcp: scan tools: %w", err) + } + log.Info(). + Int("tools", len(bindings)). + Bool("authenticated", opts.Bearer != ""). + 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: opts.Name, + Version: opts.Version, + }, nil) + + s := &Server{ + log: log, + mcpSrv: mcpSrv, + gwConn: conn, + lis: lis, + grpcSrv: grpcSrv, + bearer: opts.Bearer, + } + for _, b := range bindings { + s.registerTool(b) + } + return s, 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. +// +// This is the only `Run*` method on the Server. See the type comment for why +// adding a non-stdio transport is intentionally a code-level non-feature. +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() +} + +// stampAuth attaches the configured bearer to the outgoing gRPC call. A +// no-op when the bearer is unset. This is the bridge that lets gRPC handlers +// see "who is calling" when invoked from MCP (security audit H1). +func (s *Server) stampAuth(ctx context.Context) context.Context { + if s.bearer == "" { + return ctx + } + return metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer "+s.bearer) +} + +// 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 (with bearer) +// 4. Marshals the response back to JSON for the MCP client +func (s *Server) registerTool(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()} + } + + s.mcpSrv.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 := s.gwConn.Invoke(s.stampAuth(ctx), b.FullMethod, reqMsg, respMsg); err != nil { + s.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/mcp/transport_test.go b/internal/mcp/transport_test.go new file mode 100644 index 00000000..5941918f --- /dev/null +++ b/internal/mcp/transport_test.go @@ -0,0 +1,42 @@ +package mcp + +import ( + "reflect" + "strings" + "testing" +) + +// TestServer_StdioOnly is a guard against accidentally adding a non-stdio +// transport to the MCP server. Stdio is the only supported transport — the +// security model relies on the OS-level trust boundary of the subprocess +// (Claude Code spawns `authorizer mcp` as a child; only that process can +// write to its stdin). Exposing MCP over TCP/HTTP/SSE without an auth +// interceptor would be a security regression, so this test fails the build +// if anyone adds RunHTTP / RunTCP / RunSSE / Listen* / Serve* etc. +// +// To deliberately add a new transport: implement an auth+rate-limit +// interceptor for MCP first, then update this test's allow-list. +func TestServer_StdioOnly(t *testing.T) { + allowed := map[string]struct{}{ + "RunStdio": {}, + "MCPServer": {}, // test accessor — not a transport + } + t.Logf("MCP Server exported methods allow-list: %v (anything outside this set indicates a new transport)", allowed) + + st := reflect.TypeOf((*Server)(nil)) + for i := 0; i < st.NumMethod(); i++ { + name := st.Method(i).Name + if _, ok := allowed[name]; ok { + continue + } + // Heuristic: any method whose name suggests serving / running / + // listening over a different transport is a red flag. + lower := strings.ToLower(name) + for _, banned := range []string{"http", "tcp", "sse", "websocket", "listen", "serve", "run"} { + if strings.Contains(lower, banned) { + t.Errorf("disallowed transport method %q on *Server: stdio is the only supported MCP transport. "+ + "Adding a network transport requires an MCP-side auth interceptor first; see Server type comment.", name) + } + } + } +} 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