Separate web UI into standalone metacrypt-web binary
The vault server holds in-memory unsealed state (KEK, engine keys) that is lost on restart, requiring a full unseal ceremony. Previously the web UI ran inside the vault process, so any UI change forced a restart and re-unseal. This change extracts the web UI into a separate metacrypt-web binary that communicates with the vault over an authenticated gRPC connection. The web server carries no sealed state and can be restarted freely. - gen/metacrypt/v1/: generated Go bindings from proto/metacrypt/v1/ - internal/grpcserver/: full gRPC server implementation (System, Auth, Engine, PKI, Policy, ACME services) with seal/auth/admin interceptors - internal/webserver/: web server with gRPC vault client; templates embedded via web/embed.go (no runtime web/ directory needed) - cmd/metacrypt-web/: standalone binary entry point - internal/config: added [web] section (listen_addr, vault_grpc, etc.) - internal/server/routes.go: removed all web UI routes and handlers - cmd/metacrypt/server.go: starts gRPC server alongside HTTP server - Deploy: Dockerfile builds both binaries, docker-compose adds metacrypt-web service, new metacrypt-web.service systemd unit, Makefile gains proto/metacrypt-web targets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ RUN go mod download
|
||||
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /metacrypt ./cmd/metacrypt
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /metacrypt-web ./cmd/metacrypt-web
|
||||
|
||||
FROM alpine:3.21
|
||||
|
||||
@@ -17,7 +18,7 @@ RUN apk add --no-cache ca-certificates tzdata \
|
||||
&& mkdir -p /srv/metacrypt && chown metacrypt:metacrypt /srv/metacrypt
|
||||
|
||||
COPY --from=builder /metacrypt /usr/local/bin/metacrypt
|
||||
COPY web/ /srv/metacrypt/web/
|
||||
COPY --from=builder /metacrypt-web /usr/local/bin/metacrypt-web
|
||||
|
||||
# /srv/metacrypt is the single volume mount point.
|
||||
# It must contain:
|
||||
|
||||
23
Makefile
23
Makefile
@@ -1,7 +1,17 @@
|
||||
.PHONY: build test vet clean docker all devserver metacrypt
|
||||
.PHONY: build test vet clean docker all devserver metacrypt metacrypt-web proto
|
||||
|
||||
LDFLAGS := -trimpath -ldflags="-s -w -X main.version=$(shell git describe --tags --always --dirty 2>/dev/null || echo dev)"
|
||||
|
||||
proto:
|
||||
protoc --go_out=. --go_opt=paths=source_relative \
|
||||
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
|
||||
proto/metacrypt/v1/*.proto
|
||||
|
||||
metacrypt:
|
||||
go build -trimpath -ldflags="-s -w -X main.version=$(shell git describe --tags --always --dirty 2>/dev/null || echo dev)" -o metacrypt ./cmd/metacrypt
|
||||
go build $(LDFLAGS) -o metacrypt ./cmd/metacrypt
|
||||
|
||||
metacrypt-web:
|
||||
go build $(LDFLAGS) -o metacrypt-web ./cmd/metacrypt-web
|
||||
|
||||
build:
|
||||
go build ./...
|
||||
@@ -13,7 +23,7 @@ vet:
|
||||
go vet ./...
|
||||
|
||||
clean:
|
||||
rm -f metacrypt
|
||||
rm -f metacrypt metacrypt-web
|
||||
|
||||
docker:
|
||||
docker build -t metacrypt .
|
||||
@@ -21,7 +31,8 @@ docker:
|
||||
docker-compose:
|
||||
docker compose -f deploy/docker/docker-compose.yml up --build
|
||||
|
||||
devserver: metacrypt
|
||||
./metacrypt server --config srv/metacrypt.toml
|
||||
devserver: metacrypt metacrypt-web
|
||||
./metacrypt server --config srv/metacrypt.toml &
|
||||
./metacrypt-web --config srv/metacrypt.toml
|
||||
|
||||
all: vet test metacrypt
|
||||
all: vet test metacrypt metacrypt-web
|
||||
|
||||
75
cmd/metacrypt-web/main.go
Normal file
75
cmd/metacrypt-web/main.go
Normal file
@@ -0,0 +1,75 @@
|
||||
// metacrypt-web is the standalone web UI server for Metacrypt.
|
||||
// It communicates with the vault over gRPC and can be restarted independently
|
||||
// without requiring the vault to be re-unsealed.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/config"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/webserver"
|
||||
)
|
||||
|
||||
var cfgFile string
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "metacrypt-web",
|
||||
Short: "Metacrypt web UI server",
|
||||
Long: "Standalone web UI server for Metacrypt. Communicates with the vault over gRPC.",
|
||||
RunE: run,
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default /srv/metacrypt/metacrypt.toml)")
|
||||
}
|
||||
|
||||
func run(cmd *cobra.Command, args []string) error {
|
||||
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
|
||||
|
||||
configPath := cfgFile
|
||||
if configPath == "" {
|
||||
configPath = "/srv/metacrypt/metacrypt.toml"
|
||||
}
|
||||
|
||||
cfg, err := config.Load(configPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cfg.Web.VaultGRPC == "" {
|
||||
return fmt.Errorf("web.vault_grpc is required in config")
|
||||
}
|
||||
|
||||
ws, err := webserver.New(cfg, logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
go func() {
|
||||
if err := ws.Start(); err != nil {
|
||||
logger.Error("web server error", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
|
||||
<-ctx.Done()
|
||||
logger.Info("shutting down web server")
|
||||
return ws.Shutdown(context.Background())
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/db"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/engine"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/engine/ca"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/grpcserver"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/policy"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/seal"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/server"
|
||||
@@ -75,10 +76,18 @@ func runServer(cmd *cobra.Command, args []string) error {
|
||||
engineRegistry.RegisterFactory(engine.EngineTypeCA, ca.NewCAEngine)
|
||||
|
||||
srv := server.New(cfg, sealMgr, authenticator, policyEngine, engineRegistry, logger, version)
|
||||
grpcSrv := grpcserver.New(cfg, sealMgr, authenticator, policyEngine, engineRegistry, logger)
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
go func() {
|
||||
if err := grpcSrv.Start(); err != nil {
|
||||
logger.Error("gRPC server error", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
if err := srv.Start(); err != nil {
|
||||
logger.Error("server error", "error", err)
|
||||
@@ -97,6 +106,7 @@ func runServer(cmd *cobra.Command, args []string) error {
|
||||
|
||||
<-ctx.Done()
|
||||
logger.Info("shutting down")
|
||||
grpcSrv.Shutdown()
|
||||
srv.ShutdownGRPC()
|
||||
return srv.Shutdown(context.Background())
|
||||
}
|
||||
|
||||
@@ -7,12 +7,9 @@ services:
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8443:8443"
|
||||
- "9443:9443"
|
||||
volumes:
|
||||
- metacrypt-data:/srv/metacrypt
|
||||
# To populate /srv/metacrypt before first run, use an init container or
|
||||
# bind-mount a host directory instead of a named volume:
|
||||
# volumes:
|
||||
# - ./data:/srv/metacrypt
|
||||
healthcheck:
|
||||
test: ["CMD", "metacrypt", "status", "--addr", "https://localhost:8443", "--ca-cert", "/srv/metacrypt/certs/ca.crt"]
|
||||
interval: 30s
|
||||
@@ -20,5 +17,19 @@ services:
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
metacrypt-web:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: Dockerfile
|
||||
container_name: metacrypt-web
|
||||
command: ["/usr/local/bin/metacrypt-web", "--config", "/srv/metacrypt/metacrypt.toml"]
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- metacrypt-data:/srv/metacrypt
|
||||
depends_on:
|
||||
- metacrypt
|
||||
|
||||
volumes:
|
||||
metacrypt-data:
|
||||
|
||||
46
deploy/systemd/metacrypt-web.service
Normal file
46
deploy/systemd/metacrypt-web.service
Normal file
@@ -0,0 +1,46 @@
|
||||
[Unit]
|
||||
Description=Metacrypt web UI server
|
||||
Documentation=https://git.wntrmute.dev/kyle/metacrypt
|
||||
After=network-online.target metacrypt.service
|
||||
Wants=network-online.target
|
||||
Requires=metacrypt.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=metacrypt
|
||||
Group=metacrypt
|
||||
|
||||
ExecStart=/usr/local/bin/metacrypt-web --config /srv/metacrypt/metacrypt.toml
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
# Security hardening
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
PrivateTmp=true
|
||||
PrivateDevices=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectControlGroups=true
|
||||
RestrictSUIDSGID=true
|
||||
RestrictNamespaces=true
|
||||
LockPersonality=true
|
||||
MemoryDenyWriteExecute=true
|
||||
RestrictRealtime=true
|
||||
|
||||
# Allow read access to config and certs
|
||||
ReadOnlyPaths=/srv/metacrypt
|
||||
|
||||
# Limit file descriptor count
|
||||
LimitNOFILE=65535
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=metacrypt-web
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
670
gen/metacrypt/v1/acme.pb.go
Normal file
670
gen/metacrypt/v1/acme.pb.go
Normal file
@@ -0,0 +1,670 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v3.20.3
|
||||
// source: metacrypt/v1/acme.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
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 CreateEABRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CreateEABRequest) Reset() {
|
||||
*x = CreateEABRequest{}
|
||||
mi := &file_metacrypt_v1_acme_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *CreateEABRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CreateEABRequest) ProtoMessage() {}
|
||||
|
||||
func (x *CreateEABRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_acme_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 CreateEABRequest.ProtoReflect.Descriptor instead.
|
||||
func (*CreateEABRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_acme_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *CreateEABRequest) GetMount() string {
|
||||
if x != nil {
|
||||
return x.Mount
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type CreateEABResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// kid is the key identifier to pass to the ACME client.
|
||||
Kid string `protobuf:"bytes,1,opt,name=kid,proto3" json:"kid,omitempty"`
|
||||
// hmac_key is the raw 32-byte HMAC-SHA256 key.
|
||||
// Base64url-encode this value when configuring an ACME client.
|
||||
HmacKey []byte `protobuf:"bytes,2,opt,name=hmac_key,json=hmacKey,proto3" json:"hmac_key,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CreateEABResponse) Reset() {
|
||||
*x = CreateEABResponse{}
|
||||
mi := &file_metacrypt_v1_acme_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *CreateEABResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CreateEABResponse) ProtoMessage() {}
|
||||
|
||||
func (x *CreateEABResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_acme_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 CreateEABResponse.ProtoReflect.Descriptor instead.
|
||||
func (*CreateEABResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_acme_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *CreateEABResponse) GetKid() string {
|
||||
if x != nil {
|
||||
return x.Kid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *CreateEABResponse) GetHmacKey() []byte {
|
||||
if x != nil {
|
||||
return x.HmacKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SetACMEConfigRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"`
|
||||
// default_issuer is the name of the CA issuer to use for ACME certificates.
|
||||
// The issuer must already exist on the CA mount.
|
||||
DefaultIssuer string `protobuf:"bytes,2,opt,name=default_issuer,json=defaultIssuer,proto3" json:"default_issuer,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetACMEConfigRequest) Reset() {
|
||||
*x = SetACMEConfigRequest{}
|
||||
mi := &file_metacrypt_v1_acme_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SetACMEConfigRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SetACMEConfigRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SetACMEConfigRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_acme_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 SetACMEConfigRequest.ProtoReflect.Descriptor instead.
|
||||
func (*SetACMEConfigRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_acme_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *SetACMEConfigRequest) GetMount() string {
|
||||
if x != nil {
|
||||
return x.Mount
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SetACMEConfigRequest) GetDefaultIssuer() string {
|
||||
if x != nil {
|
||||
return x.DefaultIssuer
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type SetACMEConfigResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetACMEConfigResponse) Reset() {
|
||||
*x = SetACMEConfigResponse{}
|
||||
mi := &file_metacrypt_v1_acme_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SetACMEConfigResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SetACMEConfigResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SetACMEConfigResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_acme_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 SetACMEConfigResponse.ProtoReflect.Descriptor instead.
|
||||
func (*SetACMEConfigResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_acme_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *SetACMEConfigResponse) GetOk() bool {
|
||||
if x != nil {
|
||||
return x.Ok
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type ListACMEAccountsRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListACMEAccountsRequest) Reset() {
|
||||
*x = ListACMEAccountsRequest{}
|
||||
mi := &file_metacrypt_v1_acme_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListACMEAccountsRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListACMEAccountsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListACMEAccountsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_acme_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 ListACMEAccountsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListACMEAccountsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_acme_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *ListACMEAccountsRequest) GetMount() string {
|
||||
if x != nil {
|
||||
return x.Mount
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ListACMEAccountsResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Accounts []*ACMEAccount `protobuf:"bytes,1,rep,name=accounts,proto3" json:"accounts,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListACMEAccountsResponse) Reset() {
|
||||
*x = ListACMEAccountsResponse{}
|
||||
mi := &file_metacrypt_v1_acme_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListACMEAccountsResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListACMEAccountsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListACMEAccountsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_acme_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 ListACMEAccountsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListACMEAccountsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_acme_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *ListACMEAccountsResponse) GetAccounts() []*ACMEAccount {
|
||||
if x != nil {
|
||||
return x.Accounts
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ACMEAccount struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
|
||||
Contact []string `protobuf:"bytes,3,rep,name=contact,proto3" json:"contact,omitempty"`
|
||||
MciasUsername string `protobuf:"bytes,4,opt,name=mcias_username,json=mciasUsername,proto3" json:"mcias_username,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ACMEAccount) Reset() {
|
||||
*x = ACMEAccount{}
|
||||
mi := &file_metacrypt_v1_acme_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ACMEAccount) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ACMEAccount) ProtoMessage() {}
|
||||
|
||||
func (x *ACMEAccount) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_acme_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 ACMEAccount.ProtoReflect.Descriptor instead.
|
||||
func (*ACMEAccount) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_acme_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *ACMEAccount) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ACMEAccount) GetStatus() string {
|
||||
if x != nil {
|
||||
return x.Status
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ACMEAccount) GetContact() []string {
|
||||
if x != nil {
|
||||
return x.Contact
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ACMEAccount) GetMciasUsername() string {
|
||||
if x != nil {
|
||||
return x.MciasUsername
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ACMEAccount) GetCreatedAt() string {
|
||||
if x != nil {
|
||||
return x.CreatedAt
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ListACMEOrdersRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListACMEOrdersRequest) Reset() {
|
||||
*x = ListACMEOrdersRequest{}
|
||||
mi := &file_metacrypt_v1_acme_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListACMEOrdersRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListACMEOrdersRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListACMEOrdersRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_acme_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 ListACMEOrdersRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListACMEOrdersRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_acme_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *ListACMEOrdersRequest) GetMount() string {
|
||||
if x != nil {
|
||||
return x.Mount
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ListACMEOrdersResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Orders []*ACMEOrder `protobuf:"bytes,1,rep,name=orders,proto3" json:"orders,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListACMEOrdersResponse) Reset() {
|
||||
*x = ListACMEOrdersResponse{}
|
||||
mi := &file_metacrypt_v1_acme_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListACMEOrdersResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListACMEOrdersResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListACMEOrdersResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_acme_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 ListACMEOrdersResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListACMEOrdersResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_acme_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *ListACMEOrdersResponse) GetOrders() []*ACMEOrder {
|
||||
if x != nil {
|
||||
return x.Orders
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ACMEOrder struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
AccountId string `protobuf:"bytes,2,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"`
|
||||
Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
|
||||
// identifiers are in "type:value" format, e.g. "dns:example.com".
|
||||
Identifiers []string `protobuf:"bytes,4,rep,name=identifiers,proto3" json:"identifiers,omitempty"`
|
||||
CreatedAt string `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
ExpiresAt string `protobuf:"bytes,6,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ACMEOrder) Reset() {
|
||||
*x = ACMEOrder{}
|
||||
mi := &file_metacrypt_v1_acme_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ACMEOrder) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ACMEOrder) ProtoMessage() {}
|
||||
|
||||
func (x *ACMEOrder) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_acme_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 ACMEOrder.ProtoReflect.Descriptor instead.
|
||||
func (*ACMEOrder) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_acme_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *ACMEOrder) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ACMEOrder) GetAccountId() string {
|
||||
if x != nil {
|
||||
return x.AccountId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ACMEOrder) GetStatus() string {
|
||||
if x != nil {
|
||||
return x.Status
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ACMEOrder) GetIdentifiers() []string {
|
||||
if x != nil {
|
||||
return x.Identifiers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ACMEOrder) GetCreatedAt() string {
|
||||
if x != nil {
|
||||
return x.CreatedAt
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ACMEOrder) GetExpiresAt() string {
|
||||
if x != nil {
|
||||
return x.ExpiresAt
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_metacrypt_v1_acme_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_metacrypt_v1_acme_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x17metacrypt/v1/acme.proto\x12\fmetacrypt.v1\"(\n" +
|
||||
"\x10CreateEABRequest\x12\x14\n" +
|
||||
"\x05mount\x18\x01 \x01(\tR\x05mount\"@\n" +
|
||||
"\x11CreateEABResponse\x12\x10\n" +
|
||||
"\x03kid\x18\x01 \x01(\tR\x03kid\x12\x19\n" +
|
||||
"\bhmac_key\x18\x02 \x01(\fR\ahmacKey\"S\n" +
|
||||
"\x14SetACMEConfigRequest\x12\x14\n" +
|
||||
"\x05mount\x18\x01 \x01(\tR\x05mount\x12%\n" +
|
||||
"\x0edefault_issuer\x18\x02 \x01(\tR\rdefaultIssuer\"'\n" +
|
||||
"\x15SetACMEConfigResponse\x12\x0e\n" +
|
||||
"\x02ok\x18\x01 \x01(\bR\x02ok\"/\n" +
|
||||
"\x17ListACMEAccountsRequest\x12\x14\n" +
|
||||
"\x05mount\x18\x01 \x01(\tR\x05mount\"Q\n" +
|
||||
"\x18ListACMEAccountsResponse\x125\n" +
|
||||
"\baccounts\x18\x01 \x03(\v2\x19.metacrypt.v1.ACMEAccountR\baccounts\"\x95\x01\n" +
|
||||
"\vACMEAccount\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" +
|
||||
"\x06status\x18\x02 \x01(\tR\x06status\x12\x18\n" +
|
||||
"\acontact\x18\x03 \x03(\tR\acontact\x12%\n" +
|
||||
"\x0emcias_username\x18\x04 \x01(\tR\rmciasUsername\x12\x1d\n" +
|
||||
"\n" +
|
||||
"created_at\x18\x05 \x01(\tR\tcreatedAt\"-\n" +
|
||||
"\x15ListACMEOrdersRequest\x12\x14\n" +
|
||||
"\x05mount\x18\x01 \x01(\tR\x05mount\"I\n" +
|
||||
"\x16ListACMEOrdersResponse\x12/\n" +
|
||||
"\x06orders\x18\x01 \x03(\v2\x17.metacrypt.v1.ACMEOrderR\x06orders\"\xb2\x01\n" +
|
||||
"\tACMEOrder\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x1d\n" +
|
||||
"\n" +
|
||||
"account_id\x18\x02 \x01(\tR\taccountId\x12\x16\n" +
|
||||
"\x06status\x18\x03 \x01(\tR\x06status\x12 \n" +
|
||||
"\videntifiers\x18\x04 \x03(\tR\videntifiers\x12\x1d\n" +
|
||||
"\n" +
|
||||
"created_at\x18\x05 \x01(\tR\tcreatedAt\x12\x1d\n" +
|
||||
"\n" +
|
||||
"expires_at\x18\x06 \x01(\tR\texpiresAt2\xe9\x02\n" +
|
||||
"\vACMEService\x12L\n" +
|
||||
"\tCreateEAB\x12\x1e.metacrypt.v1.CreateEABRequest\x1a\x1f.metacrypt.v1.CreateEABResponse\x12T\n" +
|
||||
"\tSetConfig\x12\".metacrypt.v1.SetACMEConfigRequest\x1a#.metacrypt.v1.SetACMEConfigResponse\x12]\n" +
|
||||
"\fListAccounts\x12%.metacrypt.v1.ListACMEAccountsRequest\x1a&.metacrypt.v1.ListACMEAccountsResponse\x12W\n" +
|
||||
"\n" +
|
||||
"ListOrders\x12#.metacrypt.v1.ListACMEOrdersRequest\x1a$.metacrypt.v1.ListACMEOrdersResponseB>Z<git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1;metacryptv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_metacrypt_v1_acme_proto_rawDescOnce sync.Once
|
||||
file_metacrypt_v1_acme_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_metacrypt_v1_acme_proto_rawDescGZIP() []byte {
|
||||
file_metacrypt_v1_acme_proto_rawDescOnce.Do(func() {
|
||||
file_metacrypt_v1_acme_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metacrypt_v1_acme_proto_rawDesc), len(file_metacrypt_v1_acme_proto_rawDesc)))
|
||||
})
|
||||
return file_metacrypt_v1_acme_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_metacrypt_v1_acme_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
|
||||
var file_metacrypt_v1_acme_proto_goTypes = []any{
|
||||
(*CreateEABRequest)(nil), // 0: metacrypt.v1.CreateEABRequest
|
||||
(*CreateEABResponse)(nil), // 1: metacrypt.v1.CreateEABResponse
|
||||
(*SetACMEConfigRequest)(nil), // 2: metacrypt.v1.SetACMEConfigRequest
|
||||
(*SetACMEConfigResponse)(nil), // 3: metacrypt.v1.SetACMEConfigResponse
|
||||
(*ListACMEAccountsRequest)(nil), // 4: metacrypt.v1.ListACMEAccountsRequest
|
||||
(*ListACMEAccountsResponse)(nil), // 5: metacrypt.v1.ListACMEAccountsResponse
|
||||
(*ACMEAccount)(nil), // 6: metacrypt.v1.ACMEAccount
|
||||
(*ListACMEOrdersRequest)(nil), // 7: metacrypt.v1.ListACMEOrdersRequest
|
||||
(*ListACMEOrdersResponse)(nil), // 8: metacrypt.v1.ListACMEOrdersResponse
|
||||
(*ACMEOrder)(nil), // 9: metacrypt.v1.ACMEOrder
|
||||
}
|
||||
var file_metacrypt_v1_acme_proto_depIdxs = []int32{
|
||||
6, // 0: metacrypt.v1.ListACMEAccountsResponse.accounts:type_name -> metacrypt.v1.ACMEAccount
|
||||
9, // 1: metacrypt.v1.ListACMEOrdersResponse.orders:type_name -> metacrypt.v1.ACMEOrder
|
||||
0, // 2: metacrypt.v1.ACMEService.CreateEAB:input_type -> metacrypt.v1.CreateEABRequest
|
||||
2, // 3: metacrypt.v1.ACMEService.SetConfig:input_type -> metacrypt.v1.SetACMEConfigRequest
|
||||
4, // 4: metacrypt.v1.ACMEService.ListAccounts:input_type -> metacrypt.v1.ListACMEAccountsRequest
|
||||
7, // 5: metacrypt.v1.ACMEService.ListOrders:input_type -> metacrypt.v1.ListACMEOrdersRequest
|
||||
1, // 6: metacrypt.v1.ACMEService.CreateEAB:output_type -> metacrypt.v1.CreateEABResponse
|
||||
3, // 7: metacrypt.v1.ACMEService.SetConfig:output_type -> metacrypt.v1.SetACMEConfigResponse
|
||||
5, // 8: metacrypt.v1.ACMEService.ListAccounts:output_type -> metacrypt.v1.ListACMEAccountsResponse
|
||||
8, // 9: metacrypt.v1.ACMEService.ListOrders:output_type -> metacrypt.v1.ListACMEOrdersResponse
|
||||
6, // [6:10] is the sub-list for method output_type
|
||||
2, // [2:6] 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_metacrypt_v1_acme_proto_init() }
|
||||
func file_metacrypt_v1_acme_proto_init() {
|
||||
if File_metacrypt_v1_acme_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_metacrypt_v1_acme_proto_rawDesc), len(file_metacrypt_v1_acme_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 10,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_metacrypt_v1_acme_proto_goTypes,
|
||||
DependencyIndexes: file_metacrypt_v1_acme_proto_depIdxs,
|
||||
MessageInfos: file_metacrypt_v1_acme_proto_msgTypes,
|
||||
}.Build()
|
||||
File_metacrypt_v1_acme_proto = out.File
|
||||
file_metacrypt_v1_acme_proto_goTypes = nil
|
||||
file_metacrypt_v1_acme_proto_depIdxs = nil
|
||||
}
|
||||
259
gen/metacrypt/v1/acme_grpc.pb.go
Normal file
259
gen/metacrypt/v1/acme_grpc.pb.go
Normal file
@@ -0,0 +1,259 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v3.20.3
|
||||
// source: metacrypt/v1/acme.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
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 (
|
||||
ACMEService_CreateEAB_FullMethodName = "/metacrypt.v1.ACMEService/CreateEAB"
|
||||
ACMEService_SetConfig_FullMethodName = "/metacrypt.v1.ACMEService/SetConfig"
|
||||
ACMEService_ListAccounts_FullMethodName = "/metacrypt.v1.ACMEService/ListAccounts"
|
||||
ACMEService_ListOrders_FullMethodName = "/metacrypt.v1.ACMEService/ListOrders"
|
||||
)
|
||||
|
||||
// ACMEServiceClient is the client API for ACMEService 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.
|
||||
//
|
||||
// ACMEService provides authenticated management of ACME state.
|
||||
// These RPCs correspond to the REST management endpoints at /v1/acme/{mount}/.
|
||||
// The ACME protocol endpoints themselves (/acme/{mount}/...) are HTTP-only
|
||||
// per RFC 8555 and have no gRPC equivalents.
|
||||
type ACMEServiceClient interface {
|
||||
// CreateEAB creates External Account Binding credentials for the
|
||||
// authenticated MCIAS user. The returned kid and hmac_key are used
|
||||
// with any RFC 8555-compliant ACME client to register an account.
|
||||
CreateEAB(ctx context.Context, in *CreateEABRequest, opts ...grpc.CallOption) (*CreateEABResponse, error)
|
||||
// SetConfig sets the ACME configuration for a CA mount.
|
||||
// Currently configures the default issuer used for ACME certificate issuance.
|
||||
SetConfig(ctx context.Context, in *SetACMEConfigRequest, opts ...grpc.CallOption) (*SetACMEConfigResponse, error)
|
||||
// ListAccounts returns all ACME accounts for a CA mount. Admin only.
|
||||
ListAccounts(ctx context.Context, in *ListACMEAccountsRequest, opts ...grpc.CallOption) (*ListACMEAccountsResponse, error)
|
||||
// ListOrders returns all ACME orders for a CA mount. Admin only.
|
||||
ListOrders(ctx context.Context, in *ListACMEOrdersRequest, opts ...grpc.CallOption) (*ListACMEOrdersResponse, error)
|
||||
}
|
||||
|
||||
type aCMEServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewACMEServiceClient(cc grpc.ClientConnInterface) ACMEServiceClient {
|
||||
return &aCMEServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *aCMEServiceClient) CreateEAB(ctx context.Context, in *CreateEABRequest, opts ...grpc.CallOption) (*CreateEABResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(CreateEABResponse)
|
||||
err := c.cc.Invoke(ctx, ACMEService_CreateEAB_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *aCMEServiceClient) SetConfig(ctx context.Context, in *SetACMEConfigRequest, opts ...grpc.CallOption) (*SetACMEConfigResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(SetACMEConfigResponse)
|
||||
err := c.cc.Invoke(ctx, ACMEService_SetConfig_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *aCMEServiceClient) ListAccounts(ctx context.Context, in *ListACMEAccountsRequest, opts ...grpc.CallOption) (*ListACMEAccountsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListACMEAccountsResponse)
|
||||
err := c.cc.Invoke(ctx, ACMEService_ListAccounts_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *aCMEServiceClient) ListOrders(ctx context.Context, in *ListACMEOrdersRequest, opts ...grpc.CallOption) (*ListACMEOrdersResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListACMEOrdersResponse)
|
||||
err := c.cc.Invoke(ctx, ACMEService_ListOrders_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ACMEServiceServer is the server API for ACMEService service.
|
||||
// All implementations must embed UnimplementedACMEServiceServer
|
||||
// for forward compatibility.
|
||||
//
|
||||
// ACMEService provides authenticated management of ACME state.
|
||||
// These RPCs correspond to the REST management endpoints at /v1/acme/{mount}/.
|
||||
// The ACME protocol endpoints themselves (/acme/{mount}/...) are HTTP-only
|
||||
// per RFC 8555 and have no gRPC equivalents.
|
||||
type ACMEServiceServer interface {
|
||||
// CreateEAB creates External Account Binding credentials for the
|
||||
// authenticated MCIAS user. The returned kid and hmac_key are used
|
||||
// with any RFC 8555-compliant ACME client to register an account.
|
||||
CreateEAB(context.Context, *CreateEABRequest) (*CreateEABResponse, error)
|
||||
// SetConfig sets the ACME configuration for a CA mount.
|
||||
// Currently configures the default issuer used for ACME certificate issuance.
|
||||
SetConfig(context.Context, *SetACMEConfigRequest) (*SetACMEConfigResponse, error)
|
||||
// ListAccounts returns all ACME accounts for a CA mount. Admin only.
|
||||
ListAccounts(context.Context, *ListACMEAccountsRequest) (*ListACMEAccountsResponse, error)
|
||||
// ListOrders returns all ACME orders for a CA mount. Admin only.
|
||||
ListOrders(context.Context, *ListACMEOrdersRequest) (*ListACMEOrdersResponse, error)
|
||||
mustEmbedUnimplementedACMEServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedACMEServiceServer must 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 UnimplementedACMEServiceServer struct{}
|
||||
|
||||
func (UnimplementedACMEServiceServer) CreateEAB(context.Context, *CreateEABRequest) (*CreateEABResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method CreateEAB not implemented")
|
||||
}
|
||||
func (UnimplementedACMEServiceServer) SetConfig(context.Context, *SetACMEConfigRequest) (*SetACMEConfigResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method SetConfig not implemented")
|
||||
}
|
||||
func (UnimplementedACMEServiceServer) ListAccounts(context.Context, *ListACMEAccountsRequest) (*ListACMEAccountsResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ListAccounts not implemented")
|
||||
}
|
||||
func (UnimplementedACMEServiceServer) ListOrders(context.Context, *ListACMEOrdersRequest) (*ListACMEOrdersResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ListOrders not implemented")
|
||||
}
|
||||
func (UnimplementedACMEServiceServer) mustEmbedUnimplementedACMEServiceServer() {}
|
||||
func (UnimplementedACMEServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeACMEServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ACMEServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeACMEServiceServer interface {
|
||||
mustEmbedUnimplementedACMEServiceServer()
|
||||
}
|
||||
|
||||
func RegisterACMEServiceServer(s grpc.ServiceRegistrar, srv ACMEServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedACMEServiceServer 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(&ACMEService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _ACMEService_CreateEAB_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateEABRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ACMEServiceServer).CreateEAB(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ACMEService_CreateEAB_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ACMEServiceServer).CreateEAB(ctx, req.(*CreateEABRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ACMEService_SetConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SetACMEConfigRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ACMEServiceServer).SetConfig(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ACMEService_SetConfig_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ACMEServiceServer).SetConfig(ctx, req.(*SetACMEConfigRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ACMEService_ListAccounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListACMEAccountsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ACMEServiceServer).ListAccounts(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ACMEService_ListAccounts_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ACMEServiceServer).ListAccounts(ctx, req.(*ListACMEAccountsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ACMEService_ListOrders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListACMEOrdersRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ACMEServiceServer).ListOrders(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ACMEService_ListOrders_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ACMEServiceServer).ListOrders(ctx, req.(*ListACMEOrdersRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// ACMEService_ServiceDesc is the grpc.ServiceDesc for ACMEService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var ACMEService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "metacrypt.v1.ACMEService",
|
||||
HandlerType: (*ACMEServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "CreateEAB",
|
||||
Handler: _ACMEService_CreateEAB_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SetConfig",
|
||||
Handler: _ACMEService_SetConfig_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListAccounts",
|
||||
Handler: _ACMEService_ListAccounts_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListOrders",
|
||||
Handler: _ACMEService_ListOrders_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "metacrypt/v1/acme.proto",
|
||||
}
|
||||
386
gen/metacrypt/v1/auth.pb.go
Normal file
386
gen/metacrypt/v1/auth.pb.go
Normal file
@@ -0,0 +1,386 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v3.20.3
|
||||
// source: metacrypt/v1/auth.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
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 LoginRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
|
||||
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
|
||||
TotpCode string `protobuf:"bytes,3,opt,name=totp_code,json=totpCode,proto3" json:"totp_code,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *LoginRequest) Reset() {
|
||||
*x = LoginRequest{}
|
||||
mi := &file_metacrypt_v1_auth_proto_msgTypes[0]
|
||||
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_metacrypt_v1_auth_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 LoginRequest.ProtoReflect.Descriptor instead.
|
||||
func (*LoginRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_auth_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *LoginRequest) GetUsername() string {
|
||||
if x != nil {
|
||||
return x.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *LoginRequest) GetPassword() string {
|
||||
if x != nil {
|
||||
return x.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *LoginRequest) GetTotpCode() string {
|
||||
if x != nil {
|
||||
return x.TotpCode
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
|
||||
ExpiresAt string `protobuf:"bytes,2,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *LoginResponse) Reset() {
|
||||
*x = LoginResponse{}
|
||||
mi := &file_metacrypt_v1_auth_proto_msgTypes[1]
|
||||
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_metacrypt_v1_auth_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 LoginResponse.ProtoReflect.Descriptor instead.
|
||||
func (*LoginResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_auth_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *LoginResponse) GetToken() string {
|
||||
if x != nil {
|
||||
return x.Token
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *LoginResponse) GetExpiresAt() string {
|
||||
if x != nil {
|
||||
return x.ExpiresAt
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type LogoutRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *LogoutRequest) Reset() {
|
||||
*x = LogoutRequest{}
|
||||
mi := &file_metacrypt_v1_auth_proto_msgTypes[2]
|
||||
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_metacrypt_v1_auth_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 LogoutRequest.ProtoReflect.Descriptor instead.
|
||||
func (*LogoutRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_auth_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type LogoutResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *LogoutResponse) Reset() {
|
||||
*x = LogoutResponse{}
|
||||
mi := &file_metacrypt_v1_auth_proto_msgTypes[3]
|
||||
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_metacrypt_v1_auth_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 LogoutResponse.ProtoReflect.Descriptor instead.
|
||||
func (*LogoutResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_auth_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type TokenInfoRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *TokenInfoRequest) Reset() {
|
||||
*x = TokenInfoRequest{}
|
||||
mi := &file_metacrypt_v1_auth_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *TokenInfoRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TokenInfoRequest) ProtoMessage() {}
|
||||
|
||||
func (x *TokenInfoRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_auth_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 TokenInfoRequest.ProtoReflect.Descriptor instead.
|
||||
func (*TokenInfoRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_auth_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
type TokenInfoResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
|
||||
Roles []string `protobuf:"bytes,2,rep,name=roles,proto3" json:"roles,omitempty"`
|
||||
IsAdmin bool `protobuf:"varint,3,opt,name=is_admin,json=isAdmin,proto3" json:"is_admin,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *TokenInfoResponse) Reset() {
|
||||
*x = TokenInfoResponse{}
|
||||
mi := &file_metacrypt_v1_auth_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *TokenInfoResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TokenInfoResponse) ProtoMessage() {}
|
||||
|
||||
func (x *TokenInfoResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_auth_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 TokenInfoResponse.ProtoReflect.Descriptor instead.
|
||||
func (*TokenInfoResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_auth_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *TokenInfoResponse) GetUsername() string {
|
||||
if x != nil {
|
||||
return x.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *TokenInfoResponse) GetRoles() []string {
|
||||
if x != nil {
|
||||
return x.Roles
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *TokenInfoResponse) GetIsAdmin() bool {
|
||||
if x != nil {
|
||||
return x.IsAdmin
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_metacrypt_v1_auth_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_metacrypt_v1_auth_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x17metacrypt/v1/auth.proto\x12\fmetacrypt.v1\"c\n" +
|
||||
"\fLoginRequest\x12\x1a\n" +
|
||||
"\busername\x18\x01 \x01(\tR\busername\x12\x1a\n" +
|
||||
"\bpassword\x18\x02 \x01(\tR\bpassword\x12\x1b\n" +
|
||||
"\ttotp_code\x18\x03 \x01(\tR\btotpCode\"D\n" +
|
||||
"\rLoginResponse\x12\x14\n" +
|
||||
"\x05token\x18\x01 \x01(\tR\x05token\x12\x1d\n" +
|
||||
"\n" +
|
||||
"expires_at\x18\x02 \x01(\tR\texpiresAt\"\x0f\n" +
|
||||
"\rLogoutRequest\"\x10\n" +
|
||||
"\x0eLogoutResponse\"\x12\n" +
|
||||
"\x10TokenInfoRequest\"`\n" +
|
||||
"\x11TokenInfoResponse\x12\x1a\n" +
|
||||
"\busername\x18\x01 \x01(\tR\busername\x12\x14\n" +
|
||||
"\x05roles\x18\x02 \x03(\tR\x05roles\x12\x19\n" +
|
||||
"\bis_admin\x18\x03 \x01(\bR\aisAdmin2\xe2\x01\n" +
|
||||
"\vAuthService\x12@\n" +
|
||||
"\x05Login\x12\x1a.metacrypt.v1.LoginRequest\x1a\x1b.metacrypt.v1.LoginResponse\x12C\n" +
|
||||
"\x06Logout\x12\x1b.metacrypt.v1.LogoutRequest\x1a\x1c.metacrypt.v1.LogoutResponse\x12L\n" +
|
||||
"\tTokenInfo\x12\x1e.metacrypt.v1.TokenInfoRequest\x1a\x1f.metacrypt.v1.TokenInfoResponseB>Z<git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1;metacryptv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_metacrypt_v1_auth_proto_rawDescOnce sync.Once
|
||||
file_metacrypt_v1_auth_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_metacrypt_v1_auth_proto_rawDescGZIP() []byte {
|
||||
file_metacrypt_v1_auth_proto_rawDescOnce.Do(func() {
|
||||
file_metacrypt_v1_auth_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metacrypt_v1_auth_proto_rawDesc), len(file_metacrypt_v1_auth_proto_rawDesc)))
|
||||
})
|
||||
return file_metacrypt_v1_auth_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_metacrypt_v1_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_metacrypt_v1_auth_proto_goTypes = []any{
|
||||
(*LoginRequest)(nil), // 0: metacrypt.v1.LoginRequest
|
||||
(*LoginResponse)(nil), // 1: metacrypt.v1.LoginResponse
|
||||
(*LogoutRequest)(nil), // 2: metacrypt.v1.LogoutRequest
|
||||
(*LogoutResponse)(nil), // 3: metacrypt.v1.LogoutResponse
|
||||
(*TokenInfoRequest)(nil), // 4: metacrypt.v1.TokenInfoRequest
|
||||
(*TokenInfoResponse)(nil), // 5: metacrypt.v1.TokenInfoResponse
|
||||
}
|
||||
var file_metacrypt_v1_auth_proto_depIdxs = []int32{
|
||||
0, // 0: metacrypt.v1.AuthService.Login:input_type -> metacrypt.v1.LoginRequest
|
||||
2, // 1: metacrypt.v1.AuthService.Logout:input_type -> metacrypt.v1.LogoutRequest
|
||||
4, // 2: metacrypt.v1.AuthService.TokenInfo:input_type -> metacrypt.v1.TokenInfoRequest
|
||||
1, // 3: metacrypt.v1.AuthService.Login:output_type -> metacrypt.v1.LoginResponse
|
||||
3, // 4: metacrypt.v1.AuthService.Logout:output_type -> metacrypt.v1.LogoutResponse
|
||||
5, // 5: metacrypt.v1.AuthService.TokenInfo:output_type -> metacrypt.v1.TokenInfoResponse
|
||||
3, // [3:6] is the sub-list for method output_type
|
||||
0, // [0:3] 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_metacrypt_v1_auth_proto_init() }
|
||||
func file_metacrypt_v1_auth_proto_init() {
|
||||
if File_metacrypt_v1_auth_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_metacrypt_v1_auth_proto_rawDesc), len(file_metacrypt_v1_auth_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_metacrypt_v1_auth_proto_goTypes,
|
||||
DependencyIndexes: file_metacrypt_v1_auth_proto_depIdxs,
|
||||
MessageInfos: file_metacrypt_v1_auth_proto_msgTypes,
|
||||
}.Build()
|
||||
File_metacrypt_v1_auth_proto = out.File
|
||||
file_metacrypt_v1_auth_proto_goTypes = nil
|
||||
file_metacrypt_v1_auth_proto_depIdxs = nil
|
||||
}
|
||||
197
gen/metacrypt/v1/auth_grpc.pb.go
Normal file
197
gen/metacrypt/v1/auth_grpc.pb.go
Normal file
@@ -0,0 +1,197 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v3.20.3
|
||||
// source: metacrypt/v1/auth.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
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 (
|
||||
AuthService_Login_FullMethodName = "/metacrypt.v1.AuthService/Login"
|
||||
AuthService_Logout_FullMethodName = "/metacrypt.v1.AuthService/Logout"
|
||||
AuthService_TokenInfo_FullMethodName = "/metacrypt.v1.AuthService/TokenInfo"
|
||||
)
|
||||
|
||||
// AuthServiceClient is the client API for AuthService 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 AuthServiceClient interface {
|
||||
Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error)
|
||||
Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*LogoutResponse, error)
|
||||
TokenInfo(ctx context.Context, in *TokenInfoRequest, opts ...grpc.CallOption) (*TokenInfoResponse, error)
|
||||
}
|
||||
|
||||
type authServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient {
|
||||
return &authServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *authServiceClient) 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, AuthService_Login_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *authServiceClient) 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, AuthService_Logout_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *authServiceClient) TokenInfo(ctx context.Context, in *TokenInfoRequest, opts ...grpc.CallOption) (*TokenInfoResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(TokenInfoResponse)
|
||||
err := c.cc.Invoke(ctx, AuthService_TokenInfo_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AuthServiceServer is the server API for AuthService service.
|
||||
// All implementations must embed UnimplementedAuthServiceServer
|
||||
// for forward compatibility.
|
||||
type AuthServiceServer interface {
|
||||
Login(context.Context, *LoginRequest) (*LoginResponse, error)
|
||||
Logout(context.Context, *LogoutRequest) (*LogoutResponse, error)
|
||||
TokenInfo(context.Context, *TokenInfoRequest) (*TokenInfoResponse, error)
|
||||
mustEmbedUnimplementedAuthServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedAuthServiceServer must 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 UnimplementedAuthServiceServer struct{}
|
||||
|
||||
func (UnimplementedAuthServiceServer) Login(context.Context, *LoginRequest) (*LoginResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Login not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) Logout(context.Context, *LogoutRequest) (*LogoutResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Logout not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) TokenInfo(context.Context, *TokenInfoRequest) (*TokenInfoResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method TokenInfo not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {}
|
||||
func (UnimplementedAuthServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeAuthServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to AuthServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeAuthServiceServer interface {
|
||||
mustEmbedUnimplementedAuthServiceServer()
|
||||
}
|
||||
|
||||
func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedAuthServiceServer 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(&AuthService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _AuthService_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.(AuthServiceServer).Login(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AuthService_Login_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).Login(ctx, req.(*LoginRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _AuthService_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.(AuthServiceServer).Logout(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AuthService_Logout_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).Logout(ctx, req.(*LogoutRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _AuthService_TokenInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(TokenInfoRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AuthServiceServer).TokenInfo(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AuthService_TokenInfo_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).TokenInfo(ctx, req.(*TokenInfoRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var AuthService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "metacrypt.v1.AuthService",
|
||||
HandlerType: (*AuthServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Login",
|
||||
Handler: _AuthService_Login_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Logout",
|
||||
Handler: _AuthService_Logout_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "TokenInfo",
|
||||
Handler: _AuthService_TokenInfo_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "metacrypt/v1/auth.proto",
|
||||
}
|
||||
59
gen/metacrypt/v1/common.pb.go
Normal file
59
gen/metacrypt/v1/common.pb.go
Normal file
@@ -0,0 +1,59 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v3.20.3
|
||||
// source: metacrypt/v1/common.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
var File_metacrypt_v1_common_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_metacrypt_v1_common_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x19metacrypt/v1/common.proto\x12\fmetacrypt.v1B>Z<git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1;metacryptv1b\x06proto3"
|
||||
|
||||
var file_metacrypt_v1_common_proto_goTypes = []any{}
|
||||
var file_metacrypt_v1_common_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_metacrypt_v1_common_proto_init() }
|
||||
func file_metacrypt_v1_common_proto_init() {
|
||||
if File_metacrypt_v1_common_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_metacrypt_v1_common_proto_rawDesc), len(file_metacrypt_v1_common_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_metacrypt_v1_common_proto_goTypes,
|
||||
DependencyIndexes: file_metacrypt_v1_common_proto_depIdxs,
|
||||
}.Build()
|
||||
File_metacrypt_v1_common_proto = out.File
|
||||
file_metacrypt_v1_common_proto_goTypes = nil
|
||||
file_metacrypt_v1_common_proto_depIdxs = nil
|
||||
}
|
||||
555
gen/metacrypt/v1/engine.pb.go
Normal file
555
gen/metacrypt/v1/engine.pb.go
Normal file
@@ -0,0 +1,555 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v3.20.3
|
||||
// source: metacrypt/v1/engine.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
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"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
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 MountRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Config *structpb.Struct `protobuf:"bytes,3,opt,name=config,proto3" json:"config,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *MountRequest) Reset() {
|
||||
*x = MountRequest{}
|
||||
mi := &file_metacrypt_v1_engine_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *MountRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MountRequest) ProtoMessage() {}
|
||||
|
||||
func (x *MountRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_engine_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 MountRequest.ProtoReflect.Descriptor instead.
|
||||
func (*MountRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_engine_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *MountRequest) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *MountRequest) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *MountRequest) GetConfig() *structpb.Struct {
|
||||
if x != nil {
|
||||
return x.Config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MountResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *MountResponse) Reset() {
|
||||
*x = MountResponse{}
|
||||
mi := &file_metacrypt_v1_engine_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *MountResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MountResponse) ProtoMessage() {}
|
||||
|
||||
func (x *MountResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_engine_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 MountResponse.ProtoReflect.Descriptor instead.
|
||||
func (*MountResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_engine_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type UnmountRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *UnmountRequest) Reset() {
|
||||
*x = UnmountRequest{}
|
||||
mi := &file_metacrypt_v1_engine_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *UnmountRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UnmountRequest) ProtoMessage() {}
|
||||
|
||||
func (x *UnmountRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_engine_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 UnmountRequest.ProtoReflect.Descriptor instead.
|
||||
func (*UnmountRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_engine_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *UnmountRequest) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type UnmountResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *UnmountResponse) Reset() {
|
||||
*x = UnmountResponse{}
|
||||
mi := &file_metacrypt_v1_engine_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *UnmountResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UnmountResponse) ProtoMessage() {}
|
||||
|
||||
func (x *UnmountResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_engine_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 UnmountResponse.ProtoReflect.Descriptor instead.
|
||||
func (*UnmountResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_engine_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type ListMountsRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListMountsRequest) Reset() {
|
||||
*x = ListMountsRequest{}
|
||||
mi := &file_metacrypt_v1_engine_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListMountsRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListMountsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListMountsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_engine_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 ListMountsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListMountsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_engine_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
type ListMountsResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Mounts []*MountInfo `protobuf:"bytes,1,rep,name=mounts,proto3" json:"mounts,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListMountsResponse) Reset() {
|
||||
*x = ListMountsResponse{}
|
||||
mi := &file_metacrypt_v1_engine_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListMountsResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListMountsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListMountsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_engine_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 ListMountsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListMountsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_engine_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *ListMountsResponse) GetMounts() []*MountInfo {
|
||||
if x != nil {
|
||||
return x.Mounts
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MountInfo struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
|
||||
MountPath string `protobuf:"bytes,3,opt,name=mount_path,json=mountPath,proto3" json:"mount_path,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *MountInfo) Reset() {
|
||||
*x = MountInfo{}
|
||||
mi := &file_metacrypt_v1_engine_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *MountInfo) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MountInfo) ProtoMessage() {}
|
||||
|
||||
func (x *MountInfo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_engine_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 MountInfo.ProtoReflect.Descriptor instead.
|
||||
func (*MountInfo) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_engine_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *MountInfo) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *MountInfo) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *MountInfo) GetMountPath() string {
|
||||
if x != nil {
|
||||
return x.MountPath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type EngineRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"`
|
||||
Operation string `protobuf:"bytes,2,opt,name=operation,proto3" json:"operation,omitempty"`
|
||||
Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"`
|
||||
Data *structpb.Struct `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EngineRequest) Reset() {
|
||||
*x = EngineRequest{}
|
||||
mi := &file_metacrypt_v1_engine_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EngineRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EngineRequest) ProtoMessage() {}
|
||||
|
||||
func (x *EngineRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_engine_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 EngineRequest.ProtoReflect.Descriptor instead.
|
||||
func (*EngineRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_engine_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *EngineRequest) GetMount() string {
|
||||
if x != nil {
|
||||
return x.Mount
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EngineRequest) GetOperation() string {
|
||||
if x != nil {
|
||||
return x.Operation
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EngineRequest) GetPath() string {
|
||||
if x != nil {
|
||||
return x.Path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EngineRequest) GetData() *structpb.Struct {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type EngineResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Data *structpb.Struct `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EngineResponse) Reset() {
|
||||
*x = EngineResponse{}
|
||||
mi := &file_metacrypt_v1_engine_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EngineResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EngineResponse) ProtoMessage() {}
|
||||
|
||||
func (x *EngineResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_engine_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 EngineResponse.ProtoReflect.Descriptor instead.
|
||||
func (*EngineResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_engine_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *EngineResponse) GetData() *structpb.Struct {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_metacrypt_v1_engine_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_metacrypt_v1_engine_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x19metacrypt/v1/engine.proto\x12\fmetacrypt.v1\x1a\x1cgoogle/protobuf/struct.proto\"g\n" +
|
||||
"\fMountRequest\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" +
|
||||
"\x04type\x18\x02 \x01(\tR\x04type\x12/\n" +
|
||||
"\x06config\x18\x03 \x01(\v2\x17.google.protobuf.StructR\x06config\"\x0f\n" +
|
||||
"\rMountResponse\"$\n" +
|
||||
"\x0eUnmountRequest\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\"\x11\n" +
|
||||
"\x0fUnmountResponse\"\x13\n" +
|
||||
"\x11ListMountsRequest\"E\n" +
|
||||
"\x12ListMountsResponse\x12/\n" +
|
||||
"\x06mounts\x18\x01 \x03(\v2\x17.metacrypt.v1.MountInfoR\x06mounts\"R\n" +
|
||||
"\tMountInfo\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" +
|
||||
"\x04type\x18\x02 \x01(\tR\x04type\x12\x1d\n" +
|
||||
"\n" +
|
||||
"mount_path\x18\x03 \x01(\tR\tmountPath\"\x84\x01\n" +
|
||||
"\rEngineRequest\x12\x14\n" +
|
||||
"\x05mount\x18\x01 \x01(\tR\x05mount\x12\x1c\n" +
|
||||
"\toperation\x18\x02 \x01(\tR\toperation\x12\x12\n" +
|
||||
"\x04path\x18\x03 \x01(\tR\x04path\x12+\n" +
|
||||
"\x04data\x18\x04 \x01(\v2\x17.google.protobuf.StructR\x04data\"=\n" +
|
||||
"\x0eEngineResponse\x12+\n" +
|
||||
"\x04data\x18\x01 \x01(\v2\x17.google.protobuf.StructR\x04data2\xb0\x02\n" +
|
||||
"\rEngineService\x12@\n" +
|
||||
"\x05Mount\x12\x1a.metacrypt.v1.MountRequest\x1a\x1b.metacrypt.v1.MountResponse\x12F\n" +
|
||||
"\aUnmount\x12\x1c.metacrypt.v1.UnmountRequest\x1a\x1d.metacrypt.v1.UnmountResponse\x12O\n" +
|
||||
"\n" +
|
||||
"ListMounts\x12\x1f.metacrypt.v1.ListMountsRequest\x1a .metacrypt.v1.ListMountsResponse\x12D\n" +
|
||||
"\aRequest\x12\x1b.metacrypt.v1.EngineRequest\x1a\x1c.metacrypt.v1.EngineResponseB>Z<git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1;metacryptv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_metacrypt_v1_engine_proto_rawDescOnce sync.Once
|
||||
file_metacrypt_v1_engine_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_metacrypt_v1_engine_proto_rawDescGZIP() []byte {
|
||||
file_metacrypt_v1_engine_proto_rawDescOnce.Do(func() {
|
||||
file_metacrypt_v1_engine_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metacrypt_v1_engine_proto_rawDesc), len(file_metacrypt_v1_engine_proto_rawDesc)))
|
||||
})
|
||||
return file_metacrypt_v1_engine_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_metacrypt_v1_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
|
||||
var file_metacrypt_v1_engine_proto_goTypes = []any{
|
||||
(*MountRequest)(nil), // 0: metacrypt.v1.MountRequest
|
||||
(*MountResponse)(nil), // 1: metacrypt.v1.MountResponse
|
||||
(*UnmountRequest)(nil), // 2: metacrypt.v1.UnmountRequest
|
||||
(*UnmountResponse)(nil), // 3: metacrypt.v1.UnmountResponse
|
||||
(*ListMountsRequest)(nil), // 4: metacrypt.v1.ListMountsRequest
|
||||
(*ListMountsResponse)(nil), // 5: metacrypt.v1.ListMountsResponse
|
||||
(*MountInfo)(nil), // 6: metacrypt.v1.MountInfo
|
||||
(*EngineRequest)(nil), // 7: metacrypt.v1.EngineRequest
|
||||
(*EngineResponse)(nil), // 8: metacrypt.v1.EngineResponse
|
||||
(*structpb.Struct)(nil), // 9: google.protobuf.Struct
|
||||
}
|
||||
var file_metacrypt_v1_engine_proto_depIdxs = []int32{
|
||||
9, // 0: metacrypt.v1.MountRequest.config:type_name -> google.protobuf.Struct
|
||||
6, // 1: metacrypt.v1.ListMountsResponse.mounts:type_name -> metacrypt.v1.MountInfo
|
||||
9, // 2: metacrypt.v1.EngineRequest.data:type_name -> google.protobuf.Struct
|
||||
9, // 3: metacrypt.v1.EngineResponse.data:type_name -> google.protobuf.Struct
|
||||
0, // 4: metacrypt.v1.EngineService.Mount:input_type -> metacrypt.v1.MountRequest
|
||||
2, // 5: metacrypt.v1.EngineService.Unmount:input_type -> metacrypt.v1.UnmountRequest
|
||||
4, // 6: metacrypt.v1.EngineService.ListMounts:input_type -> metacrypt.v1.ListMountsRequest
|
||||
7, // 7: metacrypt.v1.EngineService.Request:input_type -> metacrypt.v1.EngineRequest
|
||||
1, // 8: metacrypt.v1.EngineService.Mount:output_type -> metacrypt.v1.MountResponse
|
||||
3, // 9: metacrypt.v1.EngineService.Unmount:output_type -> metacrypt.v1.UnmountResponse
|
||||
5, // 10: metacrypt.v1.EngineService.ListMounts:output_type -> metacrypt.v1.ListMountsResponse
|
||||
8, // 11: metacrypt.v1.EngineService.Request:output_type -> metacrypt.v1.EngineResponse
|
||||
8, // [8:12] is the sub-list for method output_type
|
||||
4, // [4:8] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_metacrypt_v1_engine_proto_init() }
|
||||
func file_metacrypt_v1_engine_proto_init() {
|
||||
if File_metacrypt_v1_engine_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_metacrypt_v1_engine_proto_rawDesc), len(file_metacrypt_v1_engine_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 9,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_metacrypt_v1_engine_proto_goTypes,
|
||||
DependencyIndexes: file_metacrypt_v1_engine_proto_depIdxs,
|
||||
MessageInfos: file_metacrypt_v1_engine_proto_msgTypes,
|
||||
}.Build()
|
||||
File_metacrypt_v1_engine_proto = out.File
|
||||
file_metacrypt_v1_engine_proto_goTypes = nil
|
||||
file_metacrypt_v1_engine_proto_depIdxs = nil
|
||||
}
|
||||
235
gen/metacrypt/v1/engine_grpc.pb.go
Normal file
235
gen/metacrypt/v1/engine_grpc.pb.go
Normal file
@@ -0,0 +1,235 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v3.20.3
|
||||
// source: metacrypt/v1/engine.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
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 (
|
||||
EngineService_Mount_FullMethodName = "/metacrypt.v1.EngineService/Mount"
|
||||
EngineService_Unmount_FullMethodName = "/metacrypt.v1.EngineService/Unmount"
|
||||
EngineService_ListMounts_FullMethodName = "/metacrypt.v1.EngineService/ListMounts"
|
||||
EngineService_Request_FullMethodName = "/metacrypt.v1.EngineService/Request"
|
||||
)
|
||||
|
||||
// EngineServiceClient is the client API for EngineService 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 EngineServiceClient interface {
|
||||
Mount(ctx context.Context, in *MountRequest, opts ...grpc.CallOption) (*MountResponse, error)
|
||||
Unmount(ctx context.Context, in *UnmountRequest, opts ...grpc.CallOption) (*UnmountResponse, error)
|
||||
ListMounts(ctx context.Context, in *ListMountsRequest, opts ...grpc.CallOption) (*ListMountsResponse, error)
|
||||
Request(ctx context.Context, in *EngineRequest, opts ...grpc.CallOption) (*EngineResponse, error)
|
||||
}
|
||||
|
||||
type engineServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewEngineServiceClient(cc grpc.ClientConnInterface) EngineServiceClient {
|
||||
return &engineServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *engineServiceClient) Mount(ctx context.Context, in *MountRequest, opts ...grpc.CallOption) (*MountResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(MountResponse)
|
||||
err := c.cc.Invoke(ctx, EngineService_Mount_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *engineServiceClient) Unmount(ctx context.Context, in *UnmountRequest, opts ...grpc.CallOption) (*UnmountResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(UnmountResponse)
|
||||
err := c.cc.Invoke(ctx, EngineService_Unmount_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *engineServiceClient) ListMounts(ctx context.Context, in *ListMountsRequest, opts ...grpc.CallOption) (*ListMountsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListMountsResponse)
|
||||
err := c.cc.Invoke(ctx, EngineService_ListMounts_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *engineServiceClient) Request(ctx context.Context, in *EngineRequest, opts ...grpc.CallOption) (*EngineResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(EngineResponse)
|
||||
err := c.cc.Invoke(ctx, EngineService_Request_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// EngineServiceServer is the server API for EngineService service.
|
||||
// All implementations must embed UnimplementedEngineServiceServer
|
||||
// for forward compatibility.
|
||||
type EngineServiceServer interface {
|
||||
Mount(context.Context, *MountRequest) (*MountResponse, error)
|
||||
Unmount(context.Context, *UnmountRequest) (*UnmountResponse, error)
|
||||
ListMounts(context.Context, *ListMountsRequest) (*ListMountsResponse, error)
|
||||
Request(context.Context, *EngineRequest) (*EngineResponse, error)
|
||||
mustEmbedUnimplementedEngineServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedEngineServiceServer must 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 UnimplementedEngineServiceServer struct{}
|
||||
|
||||
func (UnimplementedEngineServiceServer) Mount(context.Context, *MountRequest) (*MountResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Mount not implemented")
|
||||
}
|
||||
func (UnimplementedEngineServiceServer) Unmount(context.Context, *UnmountRequest) (*UnmountResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Unmount not implemented")
|
||||
}
|
||||
func (UnimplementedEngineServiceServer) ListMounts(context.Context, *ListMountsRequest) (*ListMountsResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ListMounts not implemented")
|
||||
}
|
||||
func (UnimplementedEngineServiceServer) Request(context.Context, *EngineRequest) (*EngineResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Request not implemented")
|
||||
}
|
||||
func (UnimplementedEngineServiceServer) mustEmbedUnimplementedEngineServiceServer() {}
|
||||
func (UnimplementedEngineServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeEngineServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to EngineServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeEngineServiceServer interface {
|
||||
mustEmbedUnimplementedEngineServiceServer()
|
||||
}
|
||||
|
||||
func RegisterEngineServiceServer(s grpc.ServiceRegistrar, srv EngineServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedEngineServiceServer 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(&EngineService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _EngineService_Mount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(MountRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(EngineServiceServer).Mount(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: EngineService_Mount_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(EngineServiceServer).Mount(ctx, req.(*MountRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _EngineService_Unmount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UnmountRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(EngineServiceServer).Unmount(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: EngineService_Unmount_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(EngineServiceServer).Unmount(ctx, req.(*UnmountRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _EngineService_ListMounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListMountsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(EngineServiceServer).ListMounts(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: EngineService_ListMounts_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(EngineServiceServer).ListMounts(ctx, req.(*ListMountsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _EngineService_Request_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(EngineRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(EngineServiceServer).Request(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: EngineService_Request_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(EngineServiceServer).Request(ctx, req.(*EngineRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// EngineService_ServiceDesc is the grpc.ServiceDesc for EngineService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var EngineService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "metacrypt.v1.EngineService",
|
||||
HandlerType: (*EngineServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Mount",
|
||||
Handler: _EngineService_Mount_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Unmount",
|
||||
Handler: _EngineService_Unmount_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListMounts",
|
||||
Handler: _EngineService_ListMounts_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Request",
|
||||
Handler: _EngineService_Request_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "metacrypt/v1/engine.proto",
|
||||
}
|
||||
386
gen/metacrypt/v1/pki.pb.go
Normal file
386
gen/metacrypt/v1/pki.pb.go
Normal file
@@ -0,0 +1,386 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v3.20.3
|
||||
// source: metacrypt/v1/pki.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
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 GetRootCertRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetRootCertRequest) Reset() {
|
||||
*x = GetRootCertRequest{}
|
||||
mi := &file_metacrypt_v1_pki_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetRootCertRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetRootCertRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetRootCertRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_pki_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 GetRootCertRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetRootCertRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_pki_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *GetRootCertRequest) GetMount() string {
|
||||
if x != nil {
|
||||
return x.Mount
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetRootCertResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
CertPem []byte `protobuf:"bytes,1,opt,name=cert_pem,json=certPem,proto3" json:"cert_pem,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetRootCertResponse) Reset() {
|
||||
*x = GetRootCertResponse{}
|
||||
mi := &file_metacrypt_v1_pki_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetRootCertResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetRootCertResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetRootCertResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_pki_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 GetRootCertResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetRootCertResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_pki_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *GetRootCertResponse) GetCertPem() []byte {
|
||||
if x != nil {
|
||||
return x.CertPem
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetChainRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"`
|
||||
Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetChainRequest) Reset() {
|
||||
*x = GetChainRequest{}
|
||||
mi := &file_metacrypt_v1_pki_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetChainRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetChainRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetChainRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_pki_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 GetChainRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetChainRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_pki_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *GetChainRequest) GetMount() string {
|
||||
if x != nil {
|
||||
return x.Mount
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetChainRequest) GetIssuer() string {
|
||||
if x != nil {
|
||||
return x.Issuer
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetChainResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ChainPem []byte `protobuf:"bytes,1,opt,name=chain_pem,json=chainPem,proto3" json:"chain_pem,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetChainResponse) Reset() {
|
||||
*x = GetChainResponse{}
|
||||
mi := &file_metacrypt_v1_pki_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetChainResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetChainResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetChainResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_pki_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 GetChainResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetChainResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_pki_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *GetChainResponse) GetChainPem() []byte {
|
||||
if x != nil {
|
||||
return x.ChainPem
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetIssuerCertRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"`
|
||||
Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetIssuerCertRequest) Reset() {
|
||||
*x = GetIssuerCertRequest{}
|
||||
mi := &file_metacrypt_v1_pki_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetIssuerCertRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetIssuerCertRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetIssuerCertRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_pki_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 GetIssuerCertRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetIssuerCertRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_pki_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *GetIssuerCertRequest) GetMount() string {
|
||||
if x != nil {
|
||||
return x.Mount
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetIssuerCertRequest) GetIssuer() string {
|
||||
if x != nil {
|
||||
return x.Issuer
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetIssuerCertResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
CertPem []byte `protobuf:"bytes,1,opt,name=cert_pem,json=certPem,proto3" json:"cert_pem,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetIssuerCertResponse) Reset() {
|
||||
*x = GetIssuerCertResponse{}
|
||||
mi := &file_metacrypt_v1_pki_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetIssuerCertResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetIssuerCertResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetIssuerCertResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_pki_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 GetIssuerCertResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetIssuerCertResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_pki_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *GetIssuerCertResponse) GetCertPem() []byte {
|
||||
if x != nil {
|
||||
return x.CertPem
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_metacrypt_v1_pki_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_metacrypt_v1_pki_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x16metacrypt/v1/pki.proto\x12\fmetacrypt.v1\"*\n" +
|
||||
"\x12GetRootCertRequest\x12\x14\n" +
|
||||
"\x05mount\x18\x01 \x01(\tR\x05mount\"0\n" +
|
||||
"\x13GetRootCertResponse\x12\x19\n" +
|
||||
"\bcert_pem\x18\x01 \x01(\fR\acertPem\"?\n" +
|
||||
"\x0fGetChainRequest\x12\x14\n" +
|
||||
"\x05mount\x18\x01 \x01(\tR\x05mount\x12\x16\n" +
|
||||
"\x06issuer\x18\x02 \x01(\tR\x06issuer\"/\n" +
|
||||
"\x10GetChainResponse\x12\x1b\n" +
|
||||
"\tchain_pem\x18\x01 \x01(\fR\bchainPem\"D\n" +
|
||||
"\x14GetIssuerCertRequest\x12\x14\n" +
|
||||
"\x05mount\x18\x01 \x01(\tR\x05mount\x12\x16\n" +
|
||||
"\x06issuer\x18\x02 \x01(\tR\x06issuer\"2\n" +
|
||||
"\x15GetIssuerCertResponse\x12\x19\n" +
|
||||
"\bcert_pem\x18\x01 \x01(\fR\acertPem2\x85\x02\n" +
|
||||
"\n" +
|
||||
"PKIService\x12R\n" +
|
||||
"\vGetRootCert\x12 .metacrypt.v1.GetRootCertRequest\x1a!.metacrypt.v1.GetRootCertResponse\x12I\n" +
|
||||
"\bGetChain\x12\x1d.metacrypt.v1.GetChainRequest\x1a\x1e.metacrypt.v1.GetChainResponse\x12X\n" +
|
||||
"\rGetIssuerCert\x12\".metacrypt.v1.GetIssuerCertRequest\x1a#.metacrypt.v1.GetIssuerCertResponseB>Z<git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1;metacryptv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_metacrypt_v1_pki_proto_rawDescOnce sync.Once
|
||||
file_metacrypt_v1_pki_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_metacrypt_v1_pki_proto_rawDescGZIP() []byte {
|
||||
file_metacrypt_v1_pki_proto_rawDescOnce.Do(func() {
|
||||
file_metacrypt_v1_pki_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metacrypt_v1_pki_proto_rawDesc), len(file_metacrypt_v1_pki_proto_rawDesc)))
|
||||
})
|
||||
return file_metacrypt_v1_pki_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_metacrypt_v1_pki_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_metacrypt_v1_pki_proto_goTypes = []any{
|
||||
(*GetRootCertRequest)(nil), // 0: metacrypt.v1.GetRootCertRequest
|
||||
(*GetRootCertResponse)(nil), // 1: metacrypt.v1.GetRootCertResponse
|
||||
(*GetChainRequest)(nil), // 2: metacrypt.v1.GetChainRequest
|
||||
(*GetChainResponse)(nil), // 3: metacrypt.v1.GetChainResponse
|
||||
(*GetIssuerCertRequest)(nil), // 4: metacrypt.v1.GetIssuerCertRequest
|
||||
(*GetIssuerCertResponse)(nil), // 5: metacrypt.v1.GetIssuerCertResponse
|
||||
}
|
||||
var file_metacrypt_v1_pki_proto_depIdxs = []int32{
|
||||
0, // 0: metacrypt.v1.PKIService.GetRootCert:input_type -> metacrypt.v1.GetRootCertRequest
|
||||
2, // 1: metacrypt.v1.PKIService.GetChain:input_type -> metacrypt.v1.GetChainRequest
|
||||
4, // 2: metacrypt.v1.PKIService.GetIssuerCert:input_type -> metacrypt.v1.GetIssuerCertRequest
|
||||
1, // 3: metacrypt.v1.PKIService.GetRootCert:output_type -> metacrypt.v1.GetRootCertResponse
|
||||
3, // 4: metacrypt.v1.PKIService.GetChain:output_type -> metacrypt.v1.GetChainResponse
|
||||
5, // 5: metacrypt.v1.PKIService.GetIssuerCert:output_type -> metacrypt.v1.GetIssuerCertResponse
|
||||
3, // [3:6] is the sub-list for method output_type
|
||||
0, // [0:3] 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_metacrypt_v1_pki_proto_init() }
|
||||
func file_metacrypt_v1_pki_proto_init() {
|
||||
if File_metacrypt_v1_pki_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_metacrypt_v1_pki_proto_rawDesc), len(file_metacrypt_v1_pki_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_metacrypt_v1_pki_proto_goTypes,
|
||||
DependencyIndexes: file_metacrypt_v1_pki_proto_depIdxs,
|
||||
MessageInfos: file_metacrypt_v1_pki_proto_msgTypes,
|
||||
}.Build()
|
||||
File_metacrypt_v1_pki_proto = out.File
|
||||
file_metacrypt_v1_pki_proto_goTypes = nil
|
||||
file_metacrypt_v1_pki_proto_depIdxs = nil
|
||||
}
|
||||
203
gen/metacrypt/v1/pki_grpc.pb.go
Normal file
203
gen/metacrypt/v1/pki_grpc.pb.go
Normal file
@@ -0,0 +1,203 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v3.20.3
|
||||
// source: metacrypt/v1/pki.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
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 (
|
||||
PKIService_GetRootCert_FullMethodName = "/metacrypt.v1.PKIService/GetRootCert"
|
||||
PKIService_GetChain_FullMethodName = "/metacrypt.v1.PKIService/GetChain"
|
||||
PKIService_GetIssuerCert_FullMethodName = "/metacrypt.v1.PKIService/GetIssuerCert"
|
||||
)
|
||||
|
||||
// PKIServiceClient is the client API for PKIService 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.
|
||||
//
|
||||
// PKIService provides unauthenticated access to public CA certificates.
|
||||
// These endpoints only require the service to be unsealed.
|
||||
type PKIServiceClient interface {
|
||||
GetRootCert(ctx context.Context, in *GetRootCertRequest, opts ...grpc.CallOption) (*GetRootCertResponse, error)
|
||||
GetChain(ctx context.Context, in *GetChainRequest, opts ...grpc.CallOption) (*GetChainResponse, error)
|
||||
GetIssuerCert(ctx context.Context, in *GetIssuerCertRequest, opts ...grpc.CallOption) (*GetIssuerCertResponse, error)
|
||||
}
|
||||
|
||||
type pKIServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewPKIServiceClient(cc grpc.ClientConnInterface) PKIServiceClient {
|
||||
return &pKIServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *pKIServiceClient) GetRootCert(ctx context.Context, in *GetRootCertRequest, opts ...grpc.CallOption) (*GetRootCertResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetRootCertResponse)
|
||||
err := c.cc.Invoke(ctx, PKIService_GetRootCert_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *pKIServiceClient) GetChain(ctx context.Context, in *GetChainRequest, opts ...grpc.CallOption) (*GetChainResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetChainResponse)
|
||||
err := c.cc.Invoke(ctx, PKIService_GetChain_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *pKIServiceClient) GetIssuerCert(ctx context.Context, in *GetIssuerCertRequest, opts ...grpc.CallOption) (*GetIssuerCertResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetIssuerCertResponse)
|
||||
err := c.cc.Invoke(ctx, PKIService_GetIssuerCert_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// PKIServiceServer is the server API for PKIService service.
|
||||
// All implementations must embed UnimplementedPKIServiceServer
|
||||
// for forward compatibility.
|
||||
//
|
||||
// PKIService provides unauthenticated access to public CA certificates.
|
||||
// These endpoints only require the service to be unsealed.
|
||||
type PKIServiceServer interface {
|
||||
GetRootCert(context.Context, *GetRootCertRequest) (*GetRootCertResponse, error)
|
||||
GetChain(context.Context, *GetChainRequest) (*GetChainResponse, error)
|
||||
GetIssuerCert(context.Context, *GetIssuerCertRequest) (*GetIssuerCertResponse, error)
|
||||
mustEmbedUnimplementedPKIServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedPKIServiceServer must 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 UnimplementedPKIServiceServer struct{}
|
||||
|
||||
func (UnimplementedPKIServiceServer) GetRootCert(context.Context, *GetRootCertRequest) (*GetRootCertResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetRootCert not implemented")
|
||||
}
|
||||
func (UnimplementedPKIServiceServer) GetChain(context.Context, *GetChainRequest) (*GetChainResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetChain not implemented")
|
||||
}
|
||||
func (UnimplementedPKIServiceServer) GetIssuerCert(context.Context, *GetIssuerCertRequest) (*GetIssuerCertResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetIssuerCert not implemented")
|
||||
}
|
||||
func (UnimplementedPKIServiceServer) mustEmbedUnimplementedPKIServiceServer() {}
|
||||
func (UnimplementedPKIServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafePKIServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to PKIServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafePKIServiceServer interface {
|
||||
mustEmbedUnimplementedPKIServiceServer()
|
||||
}
|
||||
|
||||
func RegisterPKIServiceServer(s grpc.ServiceRegistrar, srv PKIServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedPKIServiceServer 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(&PKIService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _PKIService_GetRootCert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetRootCertRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PKIServiceServer).GetRootCert(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PKIService_GetRootCert_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PKIServiceServer).GetRootCert(ctx, req.(*GetRootCertRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _PKIService_GetChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetChainRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PKIServiceServer).GetChain(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PKIService_GetChain_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PKIServiceServer).GetChain(ctx, req.(*GetChainRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _PKIService_GetIssuerCert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetIssuerCertRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PKIServiceServer).GetIssuerCert(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PKIService_GetIssuerCert_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PKIServiceServer).GetIssuerCert(ctx, req.(*GetIssuerCertRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// PKIService_ServiceDesc is the grpc.ServiceDesc for PKIService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var PKIService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "metacrypt.v1.PKIService",
|
||||
HandlerType: (*PKIServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetRootCert",
|
||||
Handler: _PKIService_GetRootCert_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetChain",
|
||||
Handler: _PKIService_GetChain_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetIssuerCert",
|
||||
Handler: _PKIService_GetIssuerCert_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "metacrypt/v1/pki.proto",
|
||||
}
|
||||
456
gen/metacrypt/v1/policy.pb.go
Normal file
456
gen/metacrypt/v1/policy.pb.go
Normal file
@@ -0,0 +1,456 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v3.20.3
|
||||
// source: metacrypt/v1/policy.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
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 PolicyRule struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Priority int32 `protobuf:"varint,2,opt,name=priority,proto3" json:"priority,omitempty"`
|
||||
Effect string `protobuf:"bytes,3,opt,name=effect,proto3" json:"effect,omitempty"`
|
||||
Usernames []string `protobuf:"bytes,4,rep,name=usernames,proto3" json:"usernames,omitempty"`
|
||||
Roles []string `protobuf:"bytes,5,rep,name=roles,proto3" json:"roles,omitempty"`
|
||||
Resources []string `protobuf:"bytes,6,rep,name=resources,proto3" json:"resources,omitempty"`
|
||||
Actions []string `protobuf:"bytes,7,rep,name=actions,proto3" json:"actions,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PolicyRule) Reset() {
|
||||
*x = PolicyRule{}
|
||||
mi := &file_metacrypt_v1_policy_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *PolicyRule) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PolicyRule) ProtoMessage() {}
|
||||
|
||||
func (x *PolicyRule) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_policy_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 PolicyRule.ProtoReflect.Descriptor instead.
|
||||
func (*PolicyRule) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_policy_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PolicyRule) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PolicyRule) GetPriority() int32 {
|
||||
if x != nil {
|
||||
return x.Priority
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PolicyRule) GetEffect() string {
|
||||
if x != nil {
|
||||
return x.Effect
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PolicyRule) GetUsernames() []string {
|
||||
if x != nil {
|
||||
return x.Usernames
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *PolicyRule) GetRoles() []string {
|
||||
if x != nil {
|
||||
return x.Roles
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *PolicyRule) GetResources() []string {
|
||||
if x != nil {
|
||||
return x.Resources
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *PolicyRule) GetActions() []string {
|
||||
if x != nil {
|
||||
return x.Actions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreatePolicyRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Rule *PolicyRule `protobuf:"bytes,1,opt,name=rule,proto3" json:"rule,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CreatePolicyRequest) Reset() {
|
||||
*x = CreatePolicyRequest{}
|
||||
mi := &file_metacrypt_v1_policy_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *CreatePolicyRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CreatePolicyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *CreatePolicyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_policy_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 CreatePolicyRequest.ProtoReflect.Descriptor instead.
|
||||
func (*CreatePolicyRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_policy_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *CreatePolicyRequest) GetRule() *PolicyRule {
|
||||
if x != nil {
|
||||
return x.Rule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ListPoliciesRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListPoliciesRequest) Reset() {
|
||||
*x = ListPoliciesRequest{}
|
||||
mi := &file_metacrypt_v1_policy_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListPoliciesRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListPoliciesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListPoliciesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_policy_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 ListPoliciesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListPoliciesRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_policy_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type ListPoliciesResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Rules []*PolicyRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListPoliciesResponse) Reset() {
|
||||
*x = ListPoliciesResponse{}
|
||||
mi := &file_metacrypt_v1_policy_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListPoliciesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListPoliciesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListPoliciesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_policy_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 ListPoliciesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListPoliciesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_policy_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *ListPoliciesResponse) GetRules() []*PolicyRule {
|
||||
if x != nil {
|
||||
return x.Rules
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetPolicyRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetPolicyRequest) Reset() {
|
||||
*x = GetPolicyRequest{}
|
||||
mi := &file_metacrypt_v1_policy_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetPolicyRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetPolicyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetPolicyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_policy_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 GetPolicyRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetPolicyRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_policy_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *GetPolicyRequest) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DeletePolicyRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeletePolicyRequest) Reset() {
|
||||
*x = DeletePolicyRequest{}
|
||||
mi := &file_metacrypt_v1_policy_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *DeletePolicyRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeletePolicyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeletePolicyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_policy_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 DeletePolicyRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DeletePolicyRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_policy_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *DeletePolicyRequest) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DeletePolicyResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeletePolicyResponse) Reset() {
|
||||
*x = DeletePolicyResponse{}
|
||||
mi := &file_metacrypt_v1_policy_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *DeletePolicyResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeletePolicyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DeletePolicyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_metacrypt_v1_policy_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 DeletePolicyResponse.ProtoReflect.Descriptor instead.
|
||||
func (*DeletePolicyResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_policy_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
var File_metacrypt_v1_policy_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_metacrypt_v1_policy_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x19metacrypt/v1/policy.proto\x12\fmetacrypt.v1\"\xbc\x01\n" +
|
||||
"\n" +
|
||||
"PolicyRule\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x1a\n" +
|
||||
"\bpriority\x18\x02 \x01(\x05R\bpriority\x12\x16\n" +
|
||||
"\x06effect\x18\x03 \x01(\tR\x06effect\x12\x1c\n" +
|
||||
"\tusernames\x18\x04 \x03(\tR\tusernames\x12\x14\n" +
|
||||
"\x05roles\x18\x05 \x03(\tR\x05roles\x12\x1c\n" +
|
||||
"\tresources\x18\x06 \x03(\tR\tresources\x12\x18\n" +
|
||||
"\aactions\x18\a \x03(\tR\aactions\"C\n" +
|
||||
"\x13CreatePolicyRequest\x12,\n" +
|
||||
"\x04rule\x18\x01 \x01(\v2\x18.metacrypt.v1.PolicyRuleR\x04rule\"\x15\n" +
|
||||
"\x13ListPoliciesRequest\"F\n" +
|
||||
"\x14ListPoliciesResponse\x12.\n" +
|
||||
"\x05rules\x18\x01 \x03(\v2\x18.metacrypt.v1.PolicyRuleR\x05rules\"\"\n" +
|
||||
"\x10GetPolicyRequest\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\"%\n" +
|
||||
"\x13DeletePolicyRequest\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\"\x16\n" +
|
||||
"\x14DeletePolicyResponse2\xd1\x02\n" +
|
||||
"\rPolicyService\x12K\n" +
|
||||
"\fCreatePolicy\x12!.metacrypt.v1.CreatePolicyRequest\x1a\x18.metacrypt.v1.PolicyRule\x12U\n" +
|
||||
"\fListPolicies\x12!.metacrypt.v1.ListPoliciesRequest\x1a\".metacrypt.v1.ListPoliciesResponse\x12E\n" +
|
||||
"\tGetPolicy\x12\x1e.metacrypt.v1.GetPolicyRequest\x1a\x18.metacrypt.v1.PolicyRule\x12U\n" +
|
||||
"\fDeletePolicy\x12!.metacrypt.v1.DeletePolicyRequest\x1a\".metacrypt.v1.DeletePolicyResponseB>Z<git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1;metacryptv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_metacrypt_v1_policy_proto_rawDescOnce sync.Once
|
||||
file_metacrypt_v1_policy_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_metacrypt_v1_policy_proto_rawDescGZIP() []byte {
|
||||
file_metacrypt_v1_policy_proto_rawDescOnce.Do(func() {
|
||||
file_metacrypt_v1_policy_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metacrypt_v1_policy_proto_rawDesc), len(file_metacrypt_v1_policy_proto_rawDesc)))
|
||||
})
|
||||
return file_metacrypt_v1_policy_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_metacrypt_v1_policy_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_metacrypt_v1_policy_proto_goTypes = []any{
|
||||
(*PolicyRule)(nil), // 0: metacrypt.v1.PolicyRule
|
||||
(*CreatePolicyRequest)(nil), // 1: metacrypt.v1.CreatePolicyRequest
|
||||
(*ListPoliciesRequest)(nil), // 2: metacrypt.v1.ListPoliciesRequest
|
||||
(*ListPoliciesResponse)(nil), // 3: metacrypt.v1.ListPoliciesResponse
|
||||
(*GetPolicyRequest)(nil), // 4: metacrypt.v1.GetPolicyRequest
|
||||
(*DeletePolicyRequest)(nil), // 5: metacrypt.v1.DeletePolicyRequest
|
||||
(*DeletePolicyResponse)(nil), // 6: metacrypt.v1.DeletePolicyResponse
|
||||
}
|
||||
var file_metacrypt_v1_policy_proto_depIdxs = []int32{
|
||||
0, // 0: metacrypt.v1.CreatePolicyRequest.rule:type_name -> metacrypt.v1.PolicyRule
|
||||
0, // 1: metacrypt.v1.ListPoliciesResponse.rules:type_name -> metacrypt.v1.PolicyRule
|
||||
1, // 2: metacrypt.v1.PolicyService.CreatePolicy:input_type -> metacrypt.v1.CreatePolicyRequest
|
||||
2, // 3: metacrypt.v1.PolicyService.ListPolicies:input_type -> metacrypt.v1.ListPoliciesRequest
|
||||
4, // 4: metacrypt.v1.PolicyService.GetPolicy:input_type -> metacrypt.v1.GetPolicyRequest
|
||||
5, // 5: metacrypt.v1.PolicyService.DeletePolicy:input_type -> metacrypt.v1.DeletePolicyRequest
|
||||
0, // 6: metacrypt.v1.PolicyService.CreatePolicy:output_type -> metacrypt.v1.PolicyRule
|
||||
3, // 7: metacrypt.v1.PolicyService.ListPolicies:output_type -> metacrypt.v1.ListPoliciesResponse
|
||||
0, // 8: metacrypt.v1.PolicyService.GetPolicy:output_type -> metacrypt.v1.PolicyRule
|
||||
6, // 9: metacrypt.v1.PolicyService.DeletePolicy:output_type -> metacrypt.v1.DeletePolicyResponse
|
||||
6, // [6:10] is the sub-list for method output_type
|
||||
2, // [2:6] 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_metacrypt_v1_policy_proto_init() }
|
||||
func file_metacrypt_v1_policy_proto_init() {
|
||||
if File_metacrypt_v1_policy_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_metacrypt_v1_policy_proto_rawDesc), len(file_metacrypt_v1_policy_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 7,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_metacrypt_v1_policy_proto_goTypes,
|
||||
DependencyIndexes: file_metacrypt_v1_policy_proto_depIdxs,
|
||||
MessageInfos: file_metacrypt_v1_policy_proto_msgTypes,
|
||||
}.Build()
|
||||
File_metacrypt_v1_policy_proto = out.File
|
||||
file_metacrypt_v1_policy_proto_goTypes = nil
|
||||
file_metacrypt_v1_policy_proto_depIdxs = nil
|
||||
}
|
||||
235
gen/metacrypt/v1/policy_grpc.pb.go
Normal file
235
gen/metacrypt/v1/policy_grpc.pb.go
Normal file
@@ -0,0 +1,235 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v3.20.3
|
||||
// source: metacrypt/v1/policy.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
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 (
|
||||
PolicyService_CreatePolicy_FullMethodName = "/metacrypt.v1.PolicyService/CreatePolicy"
|
||||
PolicyService_ListPolicies_FullMethodName = "/metacrypt.v1.PolicyService/ListPolicies"
|
||||
PolicyService_GetPolicy_FullMethodName = "/metacrypt.v1.PolicyService/GetPolicy"
|
||||
PolicyService_DeletePolicy_FullMethodName = "/metacrypt.v1.PolicyService/DeletePolicy"
|
||||
)
|
||||
|
||||
// PolicyServiceClient is the client API for PolicyService 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 PolicyServiceClient interface {
|
||||
CreatePolicy(ctx context.Context, in *CreatePolicyRequest, opts ...grpc.CallOption) (*PolicyRule, error)
|
||||
ListPolicies(ctx context.Context, in *ListPoliciesRequest, opts ...grpc.CallOption) (*ListPoliciesResponse, error)
|
||||
GetPolicy(ctx context.Context, in *GetPolicyRequest, opts ...grpc.CallOption) (*PolicyRule, error)
|
||||
DeletePolicy(ctx context.Context, in *DeletePolicyRequest, opts ...grpc.CallOption) (*DeletePolicyResponse, error)
|
||||
}
|
||||
|
||||
type policyServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewPolicyServiceClient(cc grpc.ClientConnInterface) PolicyServiceClient {
|
||||
return &policyServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *policyServiceClient) CreatePolicy(ctx context.Context, in *CreatePolicyRequest, opts ...grpc.CallOption) (*PolicyRule, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(PolicyRule)
|
||||
err := c.cc.Invoke(ctx, PolicyService_CreatePolicy_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *policyServiceClient) ListPolicies(ctx context.Context, in *ListPoliciesRequest, opts ...grpc.CallOption) (*ListPoliciesResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListPoliciesResponse)
|
||||
err := c.cc.Invoke(ctx, PolicyService_ListPolicies_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *policyServiceClient) GetPolicy(ctx context.Context, in *GetPolicyRequest, opts ...grpc.CallOption) (*PolicyRule, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(PolicyRule)
|
||||
err := c.cc.Invoke(ctx, PolicyService_GetPolicy_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *policyServiceClient) DeletePolicy(ctx context.Context, in *DeletePolicyRequest, opts ...grpc.CallOption) (*DeletePolicyResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(DeletePolicyResponse)
|
||||
err := c.cc.Invoke(ctx, PolicyService_DeletePolicy_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// PolicyServiceServer is the server API for PolicyService service.
|
||||
// All implementations must embed UnimplementedPolicyServiceServer
|
||||
// for forward compatibility.
|
||||
type PolicyServiceServer interface {
|
||||
CreatePolicy(context.Context, *CreatePolicyRequest) (*PolicyRule, error)
|
||||
ListPolicies(context.Context, *ListPoliciesRequest) (*ListPoliciesResponse, error)
|
||||
GetPolicy(context.Context, *GetPolicyRequest) (*PolicyRule, error)
|
||||
DeletePolicy(context.Context, *DeletePolicyRequest) (*DeletePolicyResponse, error)
|
||||
mustEmbedUnimplementedPolicyServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedPolicyServiceServer must 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 UnimplementedPolicyServiceServer struct{}
|
||||
|
||||
func (UnimplementedPolicyServiceServer) CreatePolicy(context.Context, *CreatePolicyRequest) (*PolicyRule, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method CreatePolicy not implemented")
|
||||
}
|
||||
func (UnimplementedPolicyServiceServer) ListPolicies(context.Context, *ListPoliciesRequest) (*ListPoliciesResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ListPolicies not implemented")
|
||||
}
|
||||
func (UnimplementedPolicyServiceServer) GetPolicy(context.Context, *GetPolicyRequest) (*PolicyRule, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetPolicy not implemented")
|
||||
}
|
||||
func (UnimplementedPolicyServiceServer) DeletePolicy(context.Context, *DeletePolicyRequest) (*DeletePolicyResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method DeletePolicy not implemented")
|
||||
}
|
||||
func (UnimplementedPolicyServiceServer) mustEmbedUnimplementedPolicyServiceServer() {}
|
||||
func (UnimplementedPolicyServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafePolicyServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to PolicyServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafePolicyServiceServer interface {
|
||||
mustEmbedUnimplementedPolicyServiceServer()
|
||||
}
|
||||
|
||||
func RegisterPolicyServiceServer(s grpc.ServiceRegistrar, srv PolicyServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedPolicyServiceServer 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(&PolicyService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _PolicyService_CreatePolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreatePolicyRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).CreatePolicy(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PolicyService_CreatePolicy_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PolicyServiceServer).CreatePolicy(ctx, req.(*CreatePolicyRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _PolicyService_ListPolicies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListPoliciesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).ListPolicies(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PolicyService_ListPolicies_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PolicyServiceServer).ListPolicies(ctx, req.(*ListPoliciesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _PolicyService_GetPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPolicyRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).GetPolicy(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PolicyService_GetPolicy_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PolicyServiceServer).GetPolicy(ctx, req.(*GetPolicyRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _PolicyService_DeletePolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeletePolicyRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(PolicyServiceServer).DeletePolicy(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: PolicyService_DeletePolicy_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(PolicyServiceServer).DeletePolicy(ctx, req.(*DeletePolicyRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// PolicyService_ServiceDesc is the grpc.ServiceDesc for PolicyService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var PolicyService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "metacrypt.v1.PolicyService",
|
||||
HandlerType: (*PolicyServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "CreatePolicy",
|
||||
Handler: _PolicyService_CreatePolicy_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListPolicies",
|
||||
Handler: _PolicyService_ListPolicies_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPolicy",
|
||||
Handler: _PolicyService_GetPolicy_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeletePolicy",
|
||||
Handler: _PolicyService_DeletePolicy_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "metacrypt/v1/policy.proto",
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: proto/metacrypt/v1/system.proto
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v3.20.3
|
||||
// source: metacrypt/v1/system.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
@@ -8,10 +11,13 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
@@ -23,14 +29,19 @@ type StatusRequest struct {
|
||||
|
||||
func (x *StatusRequest) Reset() {
|
||||
*x = StatusRequest{}
|
||||
mi := &file_system_proto_msgTypes[0]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
func (x *StatusRequest) String() string { return protoimpl.X.MessageStringOf(x) }
|
||||
func (*StatusRequest) ProtoMessage() {}
|
||||
|
||||
func (x *StatusRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*StatusRequest) ProtoMessage() {}
|
||||
|
||||
func (x *StatusRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_system_proto_msgTypes[0]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -41,6 +52,11 @@ func (x *StatusRequest) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead.
|
||||
func (*StatusRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_system_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type StatusResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
State string `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"`
|
||||
@@ -50,14 +66,19 @@ type StatusResponse struct {
|
||||
|
||||
func (x *StatusResponse) Reset() {
|
||||
*x = StatusResponse{}
|
||||
mi := &file_system_proto_msgTypes[1]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
func (x *StatusResponse) String() string { return protoimpl.X.MessageStringOf(x) }
|
||||
func (*StatusResponse) ProtoMessage() {}
|
||||
|
||||
func (x *StatusResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*StatusResponse) ProtoMessage() {}
|
||||
|
||||
func (x *StatusResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_system_proto_msgTypes[1]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -67,6 +88,12 @@ func (x *StatusResponse) ProtoReflect() protoreflect.Message {
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead.
|
||||
func (*StatusResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_system_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *StatusResponse) GetState() string {
|
||||
if x != nil {
|
||||
return x.State
|
||||
@@ -83,14 +110,19 @@ type InitRequest struct {
|
||||
|
||||
func (x *InitRequest) Reset() {
|
||||
*x = InitRequest{}
|
||||
mi := &file_system_proto_msgTypes[2]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
func (x *InitRequest) String() string { return protoimpl.X.MessageStringOf(x) }
|
||||
func (*InitRequest) ProtoMessage() {}
|
||||
|
||||
func (x *InitRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*InitRequest) ProtoMessage() {}
|
||||
|
||||
func (x *InitRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_system_proto_msgTypes[2]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -100,6 +132,12 @@ func (x *InitRequest) ProtoReflect() protoreflect.Message {
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use InitRequest.ProtoReflect.Descriptor instead.
|
||||
func (*InitRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_system_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *InitRequest) GetPassword() string {
|
||||
if x != nil {
|
||||
return x.Password
|
||||
@@ -116,14 +154,19 @@ type InitResponse struct {
|
||||
|
||||
func (x *InitResponse) Reset() {
|
||||
*x = InitResponse{}
|
||||
mi := &file_system_proto_msgTypes[3]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
func (x *InitResponse) String() string { return protoimpl.X.MessageStringOf(x) }
|
||||
func (*InitResponse) ProtoMessage() {}
|
||||
|
||||
func (x *InitResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*InitResponse) ProtoMessage() {}
|
||||
|
||||
func (x *InitResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_system_proto_msgTypes[3]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -133,6 +176,12 @@ func (x *InitResponse) ProtoReflect() protoreflect.Message {
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use InitResponse.ProtoReflect.Descriptor instead.
|
||||
func (*InitResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_system_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *InitResponse) GetState() string {
|
||||
if x != nil {
|
||||
return x.State
|
||||
@@ -149,14 +198,19 @@ type UnsealRequest struct {
|
||||
|
||||
func (x *UnsealRequest) Reset() {
|
||||
*x = UnsealRequest{}
|
||||
mi := &file_system_proto_msgTypes[4]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
func (x *UnsealRequest) String() string { return protoimpl.X.MessageStringOf(x) }
|
||||
func (*UnsealRequest) ProtoMessage() {}
|
||||
|
||||
func (x *UnsealRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UnsealRequest) ProtoMessage() {}
|
||||
|
||||
func (x *UnsealRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_system_proto_msgTypes[4]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -166,6 +220,12 @@ func (x *UnsealRequest) ProtoReflect() protoreflect.Message {
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UnsealRequest.ProtoReflect.Descriptor instead.
|
||||
func (*UnsealRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_system_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *UnsealRequest) GetPassword() string {
|
||||
if x != nil {
|
||||
return x.Password
|
||||
@@ -182,14 +242,19 @@ type UnsealResponse struct {
|
||||
|
||||
func (x *UnsealResponse) Reset() {
|
||||
*x = UnsealResponse{}
|
||||
mi := &file_system_proto_msgTypes[5]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
func (x *UnsealResponse) String() string { return protoimpl.X.MessageStringOf(x) }
|
||||
func (*UnsealResponse) ProtoMessage() {}
|
||||
|
||||
func (x *UnsealResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UnsealResponse) ProtoMessage() {}
|
||||
|
||||
func (x *UnsealResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_system_proto_msgTypes[5]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -199,6 +264,12 @@ func (x *UnsealResponse) ProtoReflect() protoreflect.Message {
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UnsealResponse.ProtoReflect.Descriptor instead.
|
||||
func (*UnsealResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_system_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *UnsealResponse) GetState() string {
|
||||
if x != nil {
|
||||
return x.State
|
||||
@@ -214,14 +285,19 @@ type SealRequest struct {
|
||||
|
||||
func (x *SealRequest) Reset() {
|
||||
*x = SealRequest{}
|
||||
mi := &file_system_proto_msgTypes[6]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
func (x *SealRequest) String() string { return protoimpl.X.MessageStringOf(x) }
|
||||
func (*SealRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SealRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SealRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SealRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_system_proto_msgTypes[6]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -232,6 +308,11 @@ func (x *SealRequest) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SealRequest.ProtoReflect.Descriptor instead.
|
||||
func (*SealRequest) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_system_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
type SealResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
State string `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"`
|
||||
@@ -241,14 +322,19 @@ type SealResponse struct {
|
||||
|
||||
func (x *SealResponse) Reset() {
|
||||
*x = SealResponse{}
|
||||
mi := &file_system_proto_msgTypes[7]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
func (x *SealResponse) String() string { return protoimpl.X.MessageStringOf(x) }
|
||||
func (*SealResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SealResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SealResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SealResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_system_proto_msgTypes[7]
|
||||
mi := &file_metacrypt_v1_system_proto_msgTypes[7]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -258,6 +344,12 @@ func (x *SealResponse) ProtoReflect() protoreflect.Message {
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SealResponse.ProtoReflect.Descriptor instead.
|
||||
func (*SealResponse) Descriptor() ([]byte, []int) {
|
||||
return file_metacrypt_v1_system_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *SealResponse) GetState() string {
|
||||
if x != nil {
|
||||
return x.State
|
||||
@@ -265,77 +357,55 @@ func (x *SealResponse) GetState() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// file descriptor compiled from proto/metacrypt/v1/system.proto
|
||||
var file_system_proto_rawDesc = []byte{
|
||||
0x0a, 0x1e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70,
|
||||
0x74, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x76, 0x31, 0x22,
|
||||
0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x22, 0x27, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x15, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x28, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77,
|
||||
0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77,
|
||||
0x6f, 0x72, 0x64, 0x22, 0x25, 0x0a, 0x0c, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2a, 0x0a, 0x0d, 0x55, 0x6e, 0x73,
|
||||
0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x61,
|
||||
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61,
|
||||
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x27, 0x0a, 0x0e, 0x55, 0x6e, 0x73, 0x65, 0x61, 0x6c,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x0d,
|
||||
0x0a, 0x0b, 0x53, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x25, 0x0a,
|
||||
0x0c, 0x53, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a,
|
||||
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74,
|
||||
0x61, 0x74, 0x65, 0x32, 0xc7, 0x01, 0x0a, 0x0d, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
|
||||
0x1b, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6d,
|
||||
0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x04, 0x49, 0x6e,
|
||||
0x69, 0x74, 0x12, 0x19, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x69,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x55, 0x6e, 0x73,
|
||||
0x65, 0x61, 0x6c, 0x12, 0x1b, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1c, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x55, 0x6e, 0x73, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e,
|
||||
0x0a, 0x04, 0x53, 0x65, 0x61, 0x6c, 0x12, 0x19, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79,
|
||||
0x70, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x53, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x44, 0x5a,
|
||||
0x42, 0x67, 0x69, 0x74, 0x2e, 0x77, 0x6e, 0x74, 0x72, 0x6d, 0x75, 0x74, 0x65, 0x2e, 0x64, 0x65,
|
||||
0x76, 0x2f, 0x6b, 0x79, 0x6c, 0x65, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74,
|
||||
0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2f, 0x76,
|
||||
0x31, 0x3b, 0x6d, 0x65, 0x74, 0x61, 0x63, 0x72, 0x79, 0x70, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
var File_metacrypt_v1_system_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_metacrypt_v1_system_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x19metacrypt/v1/system.proto\x12\fmetacrypt.v1\"\x0f\n" +
|
||||
"\rStatusRequest\"&\n" +
|
||||
"\x0eStatusResponse\x12\x14\n" +
|
||||
"\x05state\x18\x01 \x01(\tR\x05state\")\n" +
|
||||
"\vInitRequest\x12\x1a\n" +
|
||||
"\bpassword\x18\x01 \x01(\tR\bpassword\"$\n" +
|
||||
"\fInitResponse\x12\x14\n" +
|
||||
"\x05state\x18\x01 \x01(\tR\x05state\"+\n" +
|
||||
"\rUnsealRequest\x12\x1a\n" +
|
||||
"\bpassword\x18\x01 \x01(\tR\bpassword\"&\n" +
|
||||
"\x0eUnsealResponse\x12\x14\n" +
|
||||
"\x05state\x18\x01 \x01(\tR\x05state\"\r\n" +
|
||||
"\vSealRequest\"$\n" +
|
||||
"\fSealResponse\x12\x14\n" +
|
||||
"\x05state\x18\x01 \x01(\tR\x05state2\x97\x02\n" +
|
||||
"\rSystemService\x12C\n" +
|
||||
"\x06Status\x12\x1b.metacrypt.v1.StatusRequest\x1a\x1c.metacrypt.v1.StatusResponse\x12=\n" +
|
||||
"\x04Init\x12\x19.metacrypt.v1.InitRequest\x1a\x1a.metacrypt.v1.InitResponse\x12C\n" +
|
||||
"\x06Unseal\x12\x1b.metacrypt.v1.UnsealRequest\x1a\x1c.metacrypt.v1.UnsealResponse\x12=\n" +
|
||||
"\x04Seal\x12\x19.metacrypt.v1.SealRequest\x1a\x1a.metacrypt.v1.SealResponseB>Z<git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1;metacryptv1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_system_proto_rawDescOnce sync.Once
|
||||
file_system_proto_rawDescData []byte
|
||||
file_metacrypt_v1_system_proto_rawDescOnce sync.Once
|
||||
file_metacrypt_v1_system_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_system_proto_rawDescGZIP() []byte {
|
||||
file_system_proto_rawDescOnce.Do(func() {
|
||||
file_system_proto_rawDescData = file_system_proto_rawDesc
|
||||
func file_metacrypt_v1_system_proto_rawDescGZIP() []byte {
|
||||
file_metacrypt_v1_system_proto_rawDescOnce.Do(func() {
|
||||
file_metacrypt_v1_system_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metacrypt_v1_system_proto_rawDesc), len(file_metacrypt_v1_system_proto_rawDesc)))
|
||||
})
|
||||
return file_system_proto_rawDescData
|
||||
return file_metacrypt_v1_system_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_system_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
||||
var file_system_proto_goTypes = []any{
|
||||
(*StatusRequest)(nil), // 0
|
||||
(*StatusResponse)(nil), // 1
|
||||
(*InitRequest)(nil), // 2
|
||||
(*InitResponse)(nil), // 3
|
||||
(*UnsealRequest)(nil), // 4
|
||||
(*UnsealResponse)(nil), // 5
|
||||
(*SealRequest)(nil), // 6
|
||||
(*SealResponse)(nil), // 7
|
||||
var file_metacrypt_v1_system_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
||||
var file_metacrypt_v1_system_proto_goTypes = []any{
|
||||
(*StatusRequest)(nil), // 0: metacrypt.v1.StatusRequest
|
||||
(*StatusResponse)(nil), // 1: metacrypt.v1.StatusResponse
|
||||
(*InitRequest)(nil), // 2: metacrypt.v1.InitRequest
|
||||
(*InitResponse)(nil), // 3: metacrypt.v1.InitResponse
|
||||
(*UnsealRequest)(nil), // 4: metacrypt.v1.UnsealRequest
|
||||
(*UnsealResponse)(nil), // 5: metacrypt.v1.UnsealResponse
|
||||
(*SealRequest)(nil), // 6: metacrypt.v1.SealRequest
|
||||
(*SealResponse)(nil), // 7: metacrypt.v1.SealResponse
|
||||
}
|
||||
var file_system_proto_depIdxs = []int32{
|
||||
var file_metacrypt_v1_system_proto_depIdxs = []int32{
|
||||
0, // 0: metacrypt.v1.SystemService.Status:input_type -> metacrypt.v1.StatusRequest
|
||||
2, // 1: metacrypt.v1.SystemService.Init:input_type -> metacrypt.v1.InitRequest
|
||||
4, // 2: metacrypt.v1.SystemService.Unseal:input_type -> metacrypt.v1.UnsealRequest
|
||||
@@ -351,31 +421,26 @@ var file_system_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_system_proto_init() }
|
||||
|
||||
func file_system_proto_init() {
|
||||
if File_system_proto != nil {
|
||||
func init() { file_metacrypt_v1_system_proto_init() }
|
||||
func file_metacrypt_v1_system_proto_init() {
|
||||
if File_metacrypt_v1_system_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_system_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_metacrypt_v1_system_proto_rawDesc), len(file_metacrypt_v1_system_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 8,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_system_proto_goTypes,
|
||||
DependencyIndexes: file_system_proto_depIdxs,
|
||||
MessageInfos: file_system_proto_msgTypes,
|
||||
GoTypes: file_metacrypt_v1_system_proto_goTypes,
|
||||
DependencyIndexes: file_metacrypt_v1_system_proto_depIdxs,
|
||||
MessageInfos: file_metacrypt_v1_system_proto_msgTypes,
|
||||
}.Build()
|
||||
File_system_proto = out.File
|
||||
file_system_proto_rawDescData = nil
|
||||
file_system_proto_goTypes = nil
|
||||
file_system_proto_depIdxs = nil
|
||||
File_metacrypt_v1_system_proto = out.File
|
||||
file_metacrypt_v1_system_proto_goTypes = nil
|
||||
file_metacrypt_v1_system_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
// File_system_proto is the protoreflect.FileDescriptor for proto/metacrypt/v1/system.proto.
|
||||
var File_system_proto protoreflect.FileDescriptor
|
||||
|
||||
@@ -1,17 +1,33 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// source: proto/metacrypt/v1/system.proto
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc v3.20.3
|
||||
// source: metacrypt/v1/system.proto
|
||||
|
||||
package metacryptv1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// SystemServiceClient is the client API for SystemService.
|
||||
// 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 (
|
||||
SystemService_Status_FullMethodName = "/metacrypt.v1.SystemService/Status"
|
||||
SystemService_Init_FullMethodName = "/metacrypt.v1.SystemService/Init"
|
||||
SystemService_Unseal_FullMethodName = "/metacrypt.v1.SystemService/Unseal"
|
||||
SystemService_Seal_FullMethodName = "/metacrypt.v1.SystemService/Seal"
|
||||
)
|
||||
|
||||
// SystemServiceClient is the client API for SystemService 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 SystemServiceClient interface {
|
||||
Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error)
|
||||
Init(ctx context.Context, in *InitRequest, opts ...grpc.CallOption) (*InitResponse, error)
|
||||
@@ -67,7 +83,9 @@ func (c *systemServiceClient) Seal(ctx context.Context, in *SealRequest, opts ..
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// SystemServiceServer is the server API for SystemService.
|
||||
// SystemServiceServer is the server API for SystemService service.
|
||||
// All implementations must embed UnimplementedSystemServiceServer
|
||||
// for forward compatibility.
|
||||
type SystemServiceServer interface {
|
||||
Status(context.Context, *StatusRequest) (*StatusResponse, error)
|
||||
Init(context.Context, *InitRequest) (*InitResponse, error)
|
||||
@@ -76,36 +94,43 @@ type SystemServiceServer interface {
|
||||
mustEmbedUnimplementedSystemServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedSystemServiceServer must be embedded to have forward-compatible implementations.
|
||||
// UnimplementedSystemServiceServer must 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 UnimplementedSystemServiceServer struct{}
|
||||
|
||||
func (UnimplementedSystemServiceServer) Status(context.Context, *StatusRequest) (*StatusResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Status not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method Status not implemented")
|
||||
}
|
||||
func (UnimplementedSystemServiceServer) Init(context.Context, *InitRequest) (*InitResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Init not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method Init not implemented")
|
||||
}
|
||||
func (UnimplementedSystemServiceServer) Unseal(context.Context, *UnsealRequest) (*UnsealResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Unseal not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method Unseal not implemented")
|
||||
}
|
||||
func (UnimplementedSystemServiceServer) Seal(context.Context, *SealRequest) (*SealResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Seal not implemented")
|
||||
return nil, status.Error(codes.Unimplemented, "method Seal not implemented")
|
||||
}
|
||||
func (UnimplementedSystemServiceServer) mustEmbedUnimplementedSystemServiceServer() {}
|
||||
func (UnimplementedSystemServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeSystemServiceServer may be embedded to opt out of forward compatibility.
|
||||
// UnsafeSystemServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to SystemServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeSystemServiceServer interface {
|
||||
mustEmbedUnimplementedSystemServiceServer()
|
||||
}
|
||||
|
||||
const (
|
||||
SystemService_Status_FullMethodName = "/metacrypt.v1.SystemService/Status"
|
||||
SystemService_Init_FullMethodName = "/metacrypt.v1.SystemService/Init"
|
||||
SystemService_Unseal_FullMethodName = "/metacrypt.v1.SystemService/Unseal"
|
||||
SystemService_Seal_FullMethodName = "/metacrypt.v1.SystemService/Seal"
|
||||
)
|
||||
|
||||
func RegisterSystemServiceServer(s grpc.ServiceRegistrar, srv SystemServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedSystemServiceServer 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(&SystemService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
@@ -182,6 +207,8 @@ func _SystemService_Seal_Handler(srv interface{}, ctx context.Context, dec func(
|
||||
}
|
||||
|
||||
// SystemService_ServiceDesc is the grpc.ServiceDesc for SystemService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var SystemService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "metacrypt.v1.SystemService",
|
||||
HandlerType: (*SystemServiceServer)(nil),
|
||||
@@ -204,5 +231,5 @@ var SystemService_ServiceDesc = grpc.ServiceDesc{
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "proto/metacrypt/v1/system.proto",
|
||||
Metadata: "metacrypt/v1/system.proto",
|
||||
}
|
||||
|
||||
8
go.mod
8
go.mod
@@ -15,8 +15,8 @@ require (
|
||||
github.com/spf13/viper v1.21.0
|
||||
golang.org/x/crypto v0.49.0
|
||||
golang.org/x/term v0.41.0
|
||||
google.golang.org/grpc v1.71.1
|
||||
google.golang.org/protobuf v1.36.5
|
||||
google.golang.org/grpc v1.79.2
|
||||
google.golang.org/protobuf v1.36.11
|
||||
modernc.org/sqlite v1.46.1
|
||||
)
|
||||
|
||||
@@ -37,10 +37,10 @@ require (
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
|
||||
golang.org/x/net v0.40.0 // indirect
|
||||
golang.org/x/net v0.51.0 // indirect
|
||||
golang.org/x/sys v0.42.0 // indirect
|
||||
golang.org/x/text v0.35.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||
modernc.org/libc v1.67.6 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
|
||||
9
go.sum
9
go.sum
@@ -13,6 +13,7 @@ github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9L
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
@@ -65,6 +66,8 @@ golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2
|
||||
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=
|
||||
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
|
||||
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -76,6 +79,12 @@ golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||
google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU=
|
||||
google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
// Config is the top-level configuration for Metacrypt.
|
||||
type Config struct {
|
||||
Server ServerConfig `toml:"server"`
|
||||
Web WebConfig `toml:"web"`
|
||||
Database DatabaseConfig `toml:"database"`
|
||||
MCIAS MCIASConfig `toml:"mcias"`
|
||||
Seal SealConfig `toml:"seal"`
|
||||
@@ -26,6 +27,20 @@ type ServerConfig struct {
|
||||
ExternalURL string `toml:"external_url"` // public base URL for ACME directory, e.g. "https://metacrypt.example.com"
|
||||
}
|
||||
|
||||
// WebConfig holds settings for the standalone web UI server (metacrypt-web).
|
||||
type WebConfig struct {
|
||||
// ListenAddr is the address the web server listens on (default: 127.0.0.1:8080).
|
||||
ListenAddr string `toml:"listen_addr"`
|
||||
// VaultGRPC is the gRPC address of the vault server (e.g. "127.0.0.1:9443").
|
||||
VaultGRPC string `toml:"vault_grpc"`
|
||||
// VaultCACert is the path to the CA certificate used to verify the vault's TLS cert.
|
||||
VaultCACert string `toml:"vault_ca_cert"`
|
||||
// TLSCert and TLSKey are optional. If empty, the web server uses plain HTTP
|
||||
// (suitable for deployment behind a TLS-terminating reverse proxy).
|
||||
TLSCert string `toml:"tls_cert"`
|
||||
TLSKey string `toml:"tls_key"`
|
||||
}
|
||||
|
||||
// DatabaseConfig holds SQLite database settings.
|
||||
type DatabaseConfig struct {
|
||||
Path string `toml:"path"`
|
||||
@@ -98,5 +113,10 @@ func (c *Config) Validate() error {
|
||||
c.Log.Level = "info"
|
||||
}
|
||||
|
||||
// Apply defaults for web server.
|
||||
if c.Web.ListenAddr == "" {
|
||||
c.Web.ListenAddr = "127.0.0.1:8080"
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
130
internal/grpcserver/acme.go
Normal file
130
internal/grpcserver/acme.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1"
|
||||
internacme "git.wntrmute.dev/kyle/metacrypt/internal/acme"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/engine"
|
||||
)
|
||||
|
||||
type acmeServer struct {
|
||||
pb.UnimplementedACMEServiceServer
|
||||
s *GRPCServer
|
||||
}
|
||||
|
||||
func (as *acmeServer) CreateEAB(ctx context.Context, req *pb.CreateEABRequest) (*pb.CreateEABResponse, error) {
|
||||
ti := tokenInfoFromContext(ctx)
|
||||
h, err := as.getOrCreateHandler(req.Mount)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.NotFound, "mount not found")
|
||||
}
|
||||
cred, err := h.CreateEAB(ctx, ti.Username)
|
||||
if err != nil {
|
||||
as.s.logger.Error("grpc: acme create EAB", "error", err)
|
||||
return nil, status.Error(codes.Internal, "failed to create EAB credentials")
|
||||
}
|
||||
return &pb.CreateEABResponse{Kid: cred.KID, HmacKey: cred.HMACKey}, nil
|
||||
}
|
||||
|
||||
func (as *acmeServer) SetConfig(ctx context.Context, req *pb.SetACMEConfigRequest) (*pb.SetACMEConfigResponse, error) {
|
||||
if req.DefaultIssuer == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "default_issuer is required")
|
||||
}
|
||||
// Verify mount exists.
|
||||
if _, err := as.getOrCreateHandler(req.Mount); err != nil {
|
||||
return nil, status.Error(codes.NotFound, "mount not found")
|
||||
}
|
||||
cfg := &internacme.ACMEConfig{DefaultIssuer: req.DefaultIssuer}
|
||||
data, _ := json.Marshal(cfg)
|
||||
barrierPath := "acme/" + req.Mount + "/config.json"
|
||||
if err := as.s.sealMgr.Barrier().Put(ctx, barrierPath, data); err != nil {
|
||||
as.s.logger.Error("grpc: acme set config", "error", err)
|
||||
return nil, status.Error(codes.Internal, "failed to save config")
|
||||
}
|
||||
return &pb.SetACMEConfigResponse{Ok: true}, nil
|
||||
}
|
||||
|
||||
func (as *acmeServer) ListAccounts(ctx context.Context, req *pb.ListACMEAccountsRequest) (*pb.ListACMEAccountsResponse, error) {
|
||||
h, err := as.getOrCreateHandler(req.Mount)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.NotFound, "mount not found")
|
||||
}
|
||||
accounts, err := h.ListAccounts(ctx)
|
||||
if err != nil {
|
||||
as.s.logger.Error("grpc: acme list accounts", "error", err)
|
||||
return nil, status.Error(codes.Internal, "internal error")
|
||||
}
|
||||
pbAccounts := make([]*pb.ACMEAccount, 0, len(accounts))
|
||||
for _, a := range accounts {
|
||||
contacts := make([]string, len(a.Contact))
|
||||
copy(contacts, a.Contact)
|
||||
pbAccounts = append(pbAccounts, &pb.ACMEAccount{
|
||||
Id: a.ID,
|
||||
Status: a.Status,
|
||||
Contact: contacts,
|
||||
MciasUsername: a.MCIASUsername,
|
||||
CreatedAt: a.CreatedAt.String(),
|
||||
})
|
||||
}
|
||||
return &pb.ListACMEAccountsResponse{Accounts: pbAccounts}, nil
|
||||
}
|
||||
|
||||
func (as *acmeServer) ListOrders(ctx context.Context, req *pb.ListACMEOrdersRequest) (*pb.ListACMEOrdersResponse, error) {
|
||||
h, err := as.getOrCreateHandler(req.Mount)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.NotFound, "mount not found")
|
||||
}
|
||||
orders, err := h.ListOrders(ctx)
|
||||
if err != nil {
|
||||
as.s.logger.Error("grpc: acme list orders", "error", err)
|
||||
return nil, status.Error(codes.Internal, "internal error")
|
||||
}
|
||||
pbOrders := make([]*pb.ACMEOrder, 0, len(orders))
|
||||
for _, o := range orders {
|
||||
identifiers := make([]string, 0, len(o.Identifiers))
|
||||
for _, id := range o.Identifiers {
|
||||
identifiers = append(identifiers, id.Type+":"+id.Value)
|
||||
}
|
||||
pbOrders = append(pbOrders, &pb.ACMEOrder{
|
||||
Id: o.ID,
|
||||
AccountId: o.AccountID,
|
||||
Status: o.Status,
|
||||
Identifiers: identifiers,
|
||||
CreatedAt: o.CreatedAt.String(),
|
||||
ExpiresAt: o.ExpiresAt.String(),
|
||||
})
|
||||
}
|
||||
return &pb.ListACMEOrdersResponse{Orders: pbOrders}, nil
|
||||
}
|
||||
|
||||
func (as *acmeServer) getOrCreateHandler(mountName string) (*internacme.Handler, error) {
|
||||
as.s.mu.Lock()
|
||||
defer as.s.mu.Unlock()
|
||||
|
||||
// Verify mount is a CA engine.
|
||||
mount, err := as.s.engines.GetMount(mountName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if mount.Type != engine.EngineTypeCA {
|
||||
return nil, engine.ErrMountNotFound
|
||||
}
|
||||
|
||||
// Check handler cache on GRPCServer.
|
||||
if h, ok := as.s.acmeHandlers[mountName]; ok {
|
||||
return h, nil
|
||||
}
|
||||
|
||||
baseURL := as.s.cfg.Server.ExternalURL
|
||||
if baseURL == "" {
|
||||
baseURL = "https://" + as.s.cfg.Server.ListenAddr
|
||||
}
|
||||
h := internacme.NewHandler(mountName, as.s.sealMgr.Barrier(), as.s.engines, baseURL, as.s.logger)
|
||||
as.s.acmeHandlers[mountName] = h
|
||||
return h, nil
|
||||
}
|
||||
56
internal/grpcserver/auth.go
Normal file
56
internal/grpcserver/auth.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
mcias "git.wntrmute.dev/kyle/mcias/clients/go"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1"
|
||||
)
|
||||
|
||||
type authServer struct {
|
||||
pb.UnimplementedAuthServiceServer
|
||||
s *GRPCServer
|
||||
}
|
||||
|
||||
func (as *authServer) Login(_ context.Context, req *pb.LoginRequest) (*pb.LoginResponse, error) {
|
||||
token, expiresAt, err := as.s.auth.Login(req.Username, req.Password, req.TotpCode)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid credentials")
|
||||
}
|
||||
return &pb.LoginResponse{Token: token, ExpiresAt: expiresAt}, nil
|
||||
}
|
||||
|
||||
func (as *authServer) Logout(ctx context.Context, _ *pb.LogoutRequest) (*pb.LogoutResponse, error) {
|
||||
token := extractToken(ctx)
|
||||
client, err := mcias.New(as.s.cfg.MCIAS.ServerURL, mcias.Options{
|
||||
CACertPath: as.s.cfg.MCIAS.CACert,
|
||||
Token: token,
|
||||
})
|
||||
if err == nil {
|
||||
as.s.auth.Logout(client)
|
||||
}
|
||||
return &pb.LogoutResponse{}, nil
|
||||
}
|
||||
|
||||
func (as *authServer) TokenInfo(ctx context.Context, _ *pb.TokenInfoRequest) (*pb.TokenInfoResponse, error) {
|
||||
ti := tokenInfoFromContext(ctx)
|
||||
if ti == nil {
|
||||
// Shouldn't happen — authInterceptor runs first — but guard anyway.
|
||||
token := extractToken(ctx)
|
||||
var err error
|
||||
ti, err = as.s.auth.ValidateToken(token)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid token")
|
||||
}
|
||||
}
|
||||
return &pb.TokenInfoResponse{
|
||||
Username: ti.Username,
|
||||
Roles: ti.Roles,
|
||||
IsAdmin: ti.IsAdmin,
|
||||
}, nil
|
||||
}
|
||||
|
||||
112
internal/grpcserver/engine.go
Normal file
112
internal/grpcserver/engine.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/engine"
|
||||
)
|
||||
|
||||
type engineServer struct {
|
||||
pb.UnimplementedEngineServiceServer
|
||||
s *GRPCServer
|
||||
}
|
||||
|
||||
func (es *engineServer) Mount(ctx context.Context, req *pb.MountRequest) (*pb.MountResponse, error) {
|
||||
if req.Name == "" || req.Type == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "name and type are required")
|
||||
}
|
||||
|
||||
var config map[string]interface{}
|
||||
if req.Config != nil {
|
||||
config = req.Config.AsMap()
|
||||
}
|
||||
|
||||
if err := es.s.engines.Mount(ctx, req.Name, engine.EngineType(req.Type), config); err != nil {
|
||||
es.s.logger.Error("grpc: mount engine", "name", req.Name, "type", req.Type, "error", err)
|
||||
switch {
|
||||
case errors.Is(err, engine.ErrMountExists):
|
||||
return nil, status.Error(codes.AlreadyExists, err.Error())
|
||||
case errors.Is(err, engine.ErrUnknownType):
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
default:
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
return &pb.MountResponse{}, nil
|
||||
}
|
||||
|
||||
func (es *engineServer) Unmount(ctx context.Context, req *pb.UnmountRequest) (*pb.UnmountResponse, error) {
|
||||
if req.Name == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "name is required")
|
||||
}
|
||||
if err := es.s.engines.Unmount(ctx, req.Name); err != nil {
|
||||
if errors.Is(err, engine.ErrMountNotFound) {
|
||||
return nil, status.Error(codes.NotFound, err.Error())
|
||||
}
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
return &pb.UnmountResponse{}, nil
|
||||
}
|
||||
|
||||
func (es *engineServer) ListMounts(_ context.Context, _ *pb.ListMountsRequest) (*pb.ListMountsResponse, error) {
|
||||
mounts := es.s.engines.ListMounts()
|
||||
pbMounts := make([]*pb.MountInfo, 0, len(mounts))
|
||||
for _, m := range mounts {
|
||||
pbMounts = append(pbMounts, &pb.MountInfo{
|
||||
Name: m.Name,
|
||||
Type: string(m.Type),
|
||||
MountPath: m.MountPath,
|
||||
})
|
||||
}
|
||||
return &pb.ListMountsResponse{Mounts: pbMounts}, nil
|
||||
}
|
||||
|
||||
func (es *engineServer) Request(ctx context.Context, req *pb.EngineRequest) (*pb.EngineResponse, error) {
|
||||
if req.Mount == "" || req.Operation == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "mount and operation are required")
|
||||
}
|
||||
|
||||
ti := tokenInfoFromContext(ctx)
|
||||
engReq := &engine.Request{
|
||||
Operation: req.Operation,
|
||||
Path: req.Path,
|
||||
Data: nil,
|
||||
}
|
||||
if req.Data != nil {
|
||||
engReq.Data = req.Data.AsMap()
|
||||
}
|
||||
if ti != nil {
|
||||
engReq.CallerInfo = &engine.CallerInfo{
|
||||
Username: ti.Username,
|
||||
Roles: ti.Roles,
|
||||
IsAdmin: ti.IsAdmin,
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := es.s.engines.HandleRequest(ctx, req.Mount, engReq)
|
||||
if err != nil {
|
||||
st := codes.Internal
|
||||
switch {
|
||||
case errors.Is(err, engine.ErrMountNotFound):
|
||||
st = codes.NotFound
|
||||
case strings.Contains(err.Error(), "forbidden"):
|
||||
st = codes.PermissionDenied
|
||||
case strings.Contains(err.Error(), "not found"):
|
||||
st = codes.NotFound
|
||||
}
|
||||
return nil, status.Error(st, err.Error())
|
||||
}
|
||||
|
||||
pbData, err := structpb.NewStruct(resp.Data)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "failed to encode response")
|
||||
}
|
||||
return &pb.EngineResponse{Data: pbData}, nil
|
||||
}
|
||||
107
internal/grpcserver/interceptors.go
Normal file
107
internal/grpcserver/interceptors.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/auth"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/seal"
|
||||
)
|
||||
|
||||
type contextKey int
|
||||
|
||||
const tokenInfoKey contextKey = iota
|
||||
|
||||
func tokenInfoFromContext(ctx context.Context) *auth.TokenInfo {
|
||||
v, _ := ctx.Value(tokenInfoKey).(*auth.TokenInfo)
|
||||
return v
|
||||
}
|
||||
|
||||
// authInterceptor validates the Bearer token from gRPC metadata and injects
|
||||
// *auth.TokenInfo into the context. The set of method full names that require
|
||||
// auth is passed in; all others pass through without validation.
|
||||
func authInterceptor(authenticator *auth.Authenticator, methods map[string]bool) grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
if !methods[info.FullMethod] {
|
||||
return handler(ctx, req)
|
||||
}
|
||||
|
||||
token := extractToken(ctx)
|
||||
if token == "" {
|
||||
return nil, status.Error(codes.Unauthenticated, "missing authorization token")
|
||||
}
|
||||
|
||||
tokenInfo, err := authenticator.ValidateToken(token)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid token")
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, tokenInfoKey, tokenInfo)
|
||||
return handler(ctx, req)
|
||||
}
|
||||
}
|
||||
|
||||
// adminInterceptor requires IsAdmin on the token info for the listed methods.
|
||||
// Must run after authInterceptor.
|
||||
func adminInterceptor(methods map[string]bool) grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
if !methods[info.FullMethod] {
|
||||
return handler(ctx, req)
|
||||
}
|
||||
ti := tokenInfoFromContext(ctx)
|
||||
if ti == nil || !ti.IsAdmin {
|
||||
return nil, status.Error(codes.PermissionDenied, "admin required")
|
||||
}
|
||||
return handler(ctx, req)
|
||||
}
|
||||
}
|
||||
|
||||
// sealInterceptor rejects calls with FailedPrecondition when the vault is
|
||||
// sealed, for the listed methods.
|
||||
func sealInterceptor(sealMgr *seal.Manager, methods map[string]bool) grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
if !methods[info.FullMethod] {
|
||||
return handler(ctx, req)
|
||||
}
|
||||
if sealMgr.State() != seal.StateUnsealed {
|
||||
return nil, status.Error(codes.FailedPrecondition, "vault is sealed")
|
||||
}
|
||||
return handler(ctx, req)
|
||||
}
|
||||
}
|
||||
|
||||
// chainInterceptors reduces a slice of interceptors into a single one.
|
||||
func chainInterceptors(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
chain := handler
|
||||
for i := len(interceptors) - 1; i >= 0; i-- {
|
||||
next := chain
|
||||
ic := interceptors[i]
|
||||
chain = func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return ic(ctx, req, info, next)
|
||||
}
|
||||
}
|
||||
return chain(ctx, req)
|
||||
}
|
||||
}
|
||||
|
||||
func extractToken(ctx context.Context) string {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
vals := md.Get("authorization")
|
||||
if len(vals) == 0 {
|
||||
return ""
|
||||
}
|
||||
v := vals[0]
|
||||
if strings.HasPrefix(v, "Bearer ") {
|
||||
return strings.TrimPrefix(v, "Bearer ")
|
||||
}
|
||||
return v
|
||||
}
|
||||
81
internal/grpcserver/pki.go
Normal file
81
internal/grpcserver/pki.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/engine"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/engine/ca"
|
||||
)
|
||||
|
||||
type pkiServer struct {
|
||||
pb.UnimplementedPKIServiceServer
|
||||
s *GRPCServer
|
||||
}
|
||||
|
||||
func (ps *pkiServer) GetRootCert(_ context.Context, req *pb.GetRootCertRequest) (*pb.GetRootCertResponse, error) {
|
||||
caEng, err := ps.getCAEngine(req.Mount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certPEM, err := caEng.GetRootCertPEM()
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Unavailable, "sealed")
|
||||
}
|
||||
return &pb.GetRootCertResponse{CertPem: certPEM}, nil
|
||||
}
|
||||
|
||||
func (ps *pkiServer) GetChain(_ context.Context, req *pb.GetChainRequest) (*pb.GetChainResponse, error) {
|
||||
if req.Issuer == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "issuer is required")
|
||||
}
|
||||
caEng, err := ps.getCAEngine(req.Mount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
chainPEM, err := caEng.GetChainPEM(req.Issuer)
|
||||
if err != nil {
|
||||
if errors.Is(err, ca.ErrIssuerNotFound) {
|
||||
return nil, status.Error(codes.NotFound, "issuer not found")
|
||||
}
|
||||
return nil, status.Error(codes.Unavailable, "sealed")
|
||||
}
|
||||
return &pb.GetChainResponse{ChainPem: chainPEM}, nil
|
||||
}
|
||||
|
||||
func (ps *pkiServer) GetIssuerCert(_ context.Context, req *pb.GetIssuerCertRequest) (*pb.GetIssuerCertResponse, error) {
|
||||
if req.Issuer == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "issuer is required")
|
||||
}
|
||||
caEng, err := ps.getCAEngine(req.Mount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certPEM, err := caEng.GetIssuerCertPEM(req.Issuer)
|
||||
if err != nil {
|
||||
if errors.Is(err, ca.ErrIssuerNotFound) {
|
||||
return nil, status.Error(codes.NotFound, "issuer not found")
|
||||
}
|
||||
return nil, status.Error(codes.Unavailable, "sealed")
|
||||
}
|
||||
return &pb.GetIssuerCertResponse{CertPem: certPEM}, nil
|
||||
}
|
||||
|
||||
func (ps *pkiServer) getCAEngine(mountName string) (*ca.CAEngine, error) {
|
||||
mount, err := ps.s.engines.GetMount(mountName)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.NotFound, err.Error())
|
||||
}
|
||||
if mount.Type != engine.EngineTypeCA {
|
||||
return nil, status.Error(codes.NotFound, "mount is not a CA engine")
|
||||
}
|
||||
caEng, ok := mount.Engine.(*ca.CAEngine)
|
||||
if !ok {
|
||||
return nil, status.Error(codes.NotFound, "mount is not a CA engine")
|
||||
}
|
||||
return caEng, nil
|
||||
}
|
||||
86
internal/grpcserver/policy.go
Normal file
86
internal/grpcserver/policy.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/policy"
|
||||
)
|
||||
|
||||
type policyServer struct {
|
||||
pb.UnimplementedPolicyServiceServer
|
||||
s *GRPCServer
|
||||
}
|
||||
|
||||
func (ps *policyServer) CreatePolicy(ctx context.Context, req *pb.CreatePolicyRequest) (*pb.PolicyRule, error) {
|
||||
if req.Rule == nil || req.Rule.Id == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "rule.id is required")
|
||||
}
|
||||
rule := pbToRule(req.Rule)
|
||||
if err := ps.s.policy.CreateRule(ctx, rule); err != nil {
|
||||
ps.s.logger.Error("grpc: create policy", "error", err)
|
||||
return nil, status.Error(codes.Internal, "internal error")
|
||||
}
|
||||
return ruleToPB(rule), nil
|
||||
}
|
||||
|
||||
func (ps *policyServer) ListPolicies(ctx context.Context, _ *pb.ListPoliciesRequest) (*pb.ListPoliciesResponse, error) {
|
||||
rules, err := ps.s.policy.ListRules(ctx)
|
||||
if err != nil {
|
||||
ps.s.logger.Error("grpc: list policies", "error", err)
|
||||
return nil, status.Error(codes.Internal, "internal error")
|
||||
}
|
||||
pbRules := make([]*pb.PolicyRule, 0, len(rules))
|
||||
for i := range rules {
|
||||
pbRules = append(pbRules, ruleToPB(&rules[i]))
|
||||
}
|
||||
return &pb.ListPoliciesResponse{Rules: pbRules}, nil
|
||||
}
|
||||
|
||||
func (ps *policyServer) GetPolicy(ctx context.Context, req *pb.GetPolicyRequest) (*pb.PolicyRule, error) {
|
||||
if req.Id == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "id is required")
|
||||
}
|
||||
rule, err := ps.s.policy.GetRule(ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.NotFound, "not found")
|
||||
}
|
||||
return ruleToPB(rule), nil
|
||||
}
|
||||
|
||||
func (ps *policyServer) DeletePolicy(ctx context.Context, req *pb.DeletePolicyRequest) (*pb.DeletePolicyResponse, error) {
|
||||
if req.Id == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "id is required")
|
||||
}
|
||||
if err := ps.s.policy.DeleteRule(ctx, req.Id); err != nil {
|
||||
return nil, status.Error(codes.NotFound, "not found")
|
||||
}
|
||||
return &pb.DeletePolicyResponse{}, nil
|
||||
}
|
||||
|
||||
func pbToRule(r *pb.PolicyRule) *policy.Rule {
|
||||
return &policy.Rule{
|
||||
ID: r.Id,
|
||||
Priority: int(r.Priority),
|
||||
Effect: policy.Effect(r.Effect),
|
||||
Usernames: r.Usernames,
|
||||
Roles: r.Roles,
|
||||
Resources: r.Resources,
|
||||
Actions: r.Actions,
|
||||
}
|
||||
}
|
||||
|
||||
func ruleToPB(r *policy.Rule) *pb.PolicyRule {
|
||||
return &pb.PolicyRule{
|
||||
Id: r.ID,
|
||||
Priority: int32(r.Priority),
|
||||
Effect: string(r.Effect),
|
||||
Usernames: r.Usernames,
|
||||
Roles: r.Roles,
|
||||
Resources: r.Resources,
|
||||
Actions: r.Actions,
|
||||
}
|
||||
}
|
||||
162
internal/grpcserver/server.go
Normal file
162
internal/grpcserver/server.go
Normal file
@@ -0,0 +1,162 @@
|
||||
// Package grpcserver implements the gRPC server for Metacrypt.
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1"
|
||||
internacme "git.wntrmute.dev/kyle/metacrypt/internal/acme"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/auth"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/config"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/engine"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/policy"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/seal"
|
||||
)
|
||||
|
||||
// GRPCServer wraps the gRPC server and all service implementations.
|
||||
type GRPCServer struct {
|
||||
cfg *config.Config
|
||||
sealMgr *seal.Manager
|
||||
auth *auth.Authenticator
|
||||
policy *policy.Engine
|
||||
engines *engine.Registry
|
||||
logger *slog.Logger
|
||||
|
||||
srv *grpc.Server
|
||||
mu sync.Mutex
|
||||
acmeHandlers map[string]*internacme.Handler
|
||||
}
|
||||
|
||||
// New creates a new GRPCServer.
|
||||
func New(cfg *config.Config, sealMgr *seal.Manager, authenticator *auth.Authenticator,
|
||||
policyEngine *policy.Engine, engineRegistry *engine.Registry, logger *slog.Logger) *GRPCServer {
|
||||
return &GRPCServer{
|
||||
cfg: cfg,
|
||||
sealMgr: sealMgr,
|
||||
auth: authenticator,
|
||||
policy: policyEngine,
|
||||
engines: engineRegistry,
|
||||
logger: logger,
|
||||
acmeHandlers: make(map[string]*internacme.Handler),
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts the gRPC server on cfg.Server.GRPCAddr.
|
||||
func (s *GRPCServer) Start() error {
|
||||
if s.cfg.Server.GRPCAddr == "" {
|
||||
s.logger.Info("grpc_addr not configured, gRPC server disabled")
|
||||
return nil
|
||||
}
|
||||
|
||||
tlsCert, err := tls.LoadX509KeyPair(s.cfg.Server.TLSCert, s.cfg.Server.TLSKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("grpc: load TLS cert: %w", err)
|
||||
}
|
||||
tlsCfg := &tls.Config{
|
||||
Certificates: []tls.Certificate{tlsCert},
|
||||
MinVersion: tls.VersionTLS12,
|
||||
}
|
||||
creds := credentials.NewTLS(tlsCfg)
|
||||
|
||||
interceptor := chainInterceptors(
|
||||
sealInterceptor(s.sealMgr, sealRequiredMethods()),
|
||||
authInterceptor(s.auth, authRequiredMethods()),
|
||||
adminInterceptor(adminRequiredMethods()),
|
||||
)
|
||||
|
||||
s.srv = grpc.NewServer(
|
||||
grpc.Creds(creds),
|
||||
grpc.UnaryInterceptor(interceptor),
|
||||
)
|
||||
|
||||
pb.RegisterSystemServiceServer(s.srv, &systemServer{s: s})
|
||||
pb.RegisterAuthServiceServer(s.srv, &authServer{s: s})
|
||||
pb.RegisterEngineServiceServer(s.srv, &engineServer{s: s})
|
||||
pb.RegisterPKIServiceServer(s.srv, &pkiServer{s: s})
|
||||
pb.RegisterPolicyServiceServer(s.srv, &policyServer{s: s})
|
||||
pb.RegisterACMEServiceServer(s.srv, &acmeServer{s: s})
|
||||
|
||||
lis, err := net.Listen("tcp", s.cfg.Server.GRPCAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("grpc: listen %s: %w", s.cfg.Server.GRPCAddr, err)
|
||||
}
|
||||
|
||||
s.logger.Info("starting gRPC server", "addr", s.cfg.Server.GRPCAddr)
|
||||
if err := s.srv.Serve(lis); err != nil {
|
||||
return fmt.Errorf("grpc: serve: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Shutdown gracefully stops the gRPC server.
|
||||
func (s *GRPCServer) Shutdown() {
|
||||
if s.srv != nil {
|
||||
s.srv.GracefulStop()
|
||||
}
|
||||
}
|
||||
|
||||
// sealRequiredMethods returns the set of RPC full names that require the vault
|
||||
// to be unsealed.
|
||||
func sealRequiredMethods() map[string]bool {
|
||||
return map[string]bool{
|
||||
"/metacrypt.v1.AuthService/Login": true,
|
||||
"/metacrypt.v1.AuthService/Logout": true,
|
||||
"/metacrypt.v1.AuthService/TokenInfo": true,
|
||||
"/metacrypt.v1.EngineService/Mount": true,
|
||||
"/metacrypt.v1.EngineService/Unmount": true,
|
||||
"/metacrypt.v1.EngineService/ListMounts": true,
|
||||
"/metacrypt.v1.EngineService/Request": true,
|
||||
"/metacrypt.v1.PKIService/GetRootCert": true,
|
||||
"/metacrypt.v1.PKIService/GetChain": true,
|
||||
"/metacrypt.v1.PKIService/GetIssuerCert": true,
|
||||
"/metacrypt.v1.PolicyService/CreatePolicy": true,
|
||||
"/metacrypt.v1.PolicyService/ListPolicies": true,
|
||||
"/metacrypt.v1.PolicyService/GetPolicy": true,
|
||||
"/metacrypt.v1.PolicyService/DeletePolicy": true,
|
||||
"/metacrypt.v1.ACMEService/CreateEAB": true,
|
||||
"/metacrypt.v1.ACMEService/SetConfig": true,
|
||||
"/metacrypt.v1.ACMEService/ListAccounts": true,
|
||||
"/metacrypt.v1.ACMEService/ListOrders": true,
|
||||
}
|
||||
}
|
||||
|
||||
// authRequiredMethods returns the set of RPC full names that require a valid token.
|
||||
func authRequiredMethods() map[string]bool {
|
||||
return map[string]bool{
|
||||
"/metacrypt.v1.AuthService/Logout": true,
|
||||
"/metacrypt.v1.AuthService/TokenInfo": true,
|
||||
"/metacrypt.v1.EngineService/Mount": true,
|
||||
"/metacrypt.v1.EngineService/Unmount": true,
|
||||
"/metacrypt.v1.EngineService/ListMounts": true,
|
||||
"/metacrypt.v1.EngineService/Request": true,
|
||||
"/metacrypt.v1.PolicyService/CreatePolicy": true,
|
||||
"/metacrypt.v1.PolicyService/ListPolicies": true,
|
||||
"/metacrypt.v1.PolicyService/GetPolicy": true,
|
||||
"/metacrypt.v1.PolicyService/DeletePolicy": true,
|
||||
"/metacrypt.v1.ACMEService/CreateEAB": true,
|
||||
"/metacrypt.v1.ACMEService/SetConfig": true,
|
||||
"/metacrypt.v1.ACMEService/ListAccounts": true,
|
||||
"/metacrypt.v1.ACMEService/ListOrders": true,
|
||||
}
|
||||
}
|
||||
|
||||
// adminRequiredMethods returns the set of RPC full names that require admin.
|
||||
func adminRequiredMethods() map[string]bool {
|
||||
return map[string]bool{
|
||||
"/metacrypt.v1.SystemService/Seal": true,
|
||||
"/metacrypt.v1.EngineService/Mount": true,
|
||||
"/metacrypt.v1.EngineService/Unmount": true,
|
||||
"/metacrypt.v1.PolicyService/CreatePolicy": true,
|
||||
"/metacrypt.v1.PolicyService/DeletePolicy": true,
|
||||
"/metacrypt.v1.ACMEService/SetConfig": true,
|
||||
"/metacrypt.v1.ACMEService/ListAccounts": true,
|
||||
"/metacrypt.v1.ACMEService/ListOrders": true,
|
||||
}
|
||||
}
|
||||
80
internal/grpcserver/system.go
Normal file
80
internal/grpcserver/system.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package grpcserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/crypto"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/seal"
|
||||
)
|
||||
|
||||
type systemServer struct {
|
||||
pb.UnimplementedSystemServiceServer
|
||||
s *GRPCServer
|
||||
}
|
||||
|
||||
func (ss *systemServer) Status(_ context.Context, _ *pb.StatusRequest) (*pb.StatusResponse, error) {
|
||||
return &pb.StatusResponse{State: ss.s.sealMgr.State().String()}, nil
|
||||
}
|
||||
|
||||
func (ss *systemServer) Init(ctx context.Context, req *pb.InitRequest) (*pb.InitResponse, error) {
|
||||
if req.Password == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "password is required")
|
||||
}
|
||||
|
||||
params := crypto.Argon2Params{
|
||||
Time: ss.s.cfg.Seal.Argon2Time,
|
||||
Memory: ss.s.cfg.Seal.Argon2Memory,
|
||||
Threads: ss.s.cfg.Seal.Argon2Threads,
|
||||
}
|
||||
if err := ss.s.sealMgr.Initialize(ctx, []byte(req.Password), params); err != nil {
|
||||
switch err {
|
||||
case seal.ErrAlreadyInitialized:
|
||||
return nil, status.Error(codes.AlreadyExists, "already initialized")
|
||||
default:
|
||||
ss.s.logger.Error("grpc: init failed", "error", err)
|
||||
return nil, status.Error(codes.Internal, "initialization failed")
|
||||
}
|
||||
}
|
||||
return &pb.InitResponse{State: ss.s.sealMgr.State().String()}, nil
|
||||
}
|
||||
|
||||
func (ss *systemServer) Unseal(ctx context.Context, req *pb.UnsealRequest) (*pb.UnsealResponse, error) {
|
||||
if err := ss.s.sealMgr.Unseal([]byte(req.Password)); err != nil {
|
||||
switch err {
|
||||
case seal.ErrNotInitialized:
|
||||
return nil, status.Error(codes.FailedPrecondition, "not initialized")
|
||||
case seal.ErrInvalidPassword:
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid password")
|
||||
case seal.ErrRateLimited:
|
||||
return nil, status.Error(codes.ResourceExhausted, "too many attempts, try again later")
|
||||
case seal.ErrNotSealed:
|
||||
return nil, status.Error(codes.FailedPrecondition, "already unsealed")
|
||||
default:
|
||||
ss.s.logger.Error("grpc: unseal failed", "error", err)
|
||||
return nil, status.Error(codes.Internal, "unseal failed")
|
||||
}
|
||||
}
|
||||
|
||||
if err := ss.s.engines.UnsealAll(ctx); err != nil {
|
||||
ss.s.logger.Error("grpc: engine unseal failed", "error", err)
|
||||
return nil, status.Error(codes.Internal, "engine unseal failed")
|
||||
}
|
||||
|
||||
return &pb.UnsealResponse{State: ss.s.sealMgr.State().String()}, nil
|
||||
}
|
||||
|
||||
func (ss *systemServer) Seal(_ context.Context, _ *pb.SealRequest) (*pb.SealResponse, error) {
|
||||
if err := ss.s.engines.SealAll(); err != nil {
|
||||
ss.s.logger.Error("grpc: seal engines failed", "error", err)
|
||||
}
|
||||
if err := ss.s.sealMgr.Seal(); err != nil {
|
||||
ss.s.logger.Error("grpc: seal failed", "error", err)
|
||||
return nil, status.Error(codes.Internal, "seal failed")
|
||||
}
|
||||
ss.s.auth.ClearCache()
|
||||
return &pb.SealResponse{State: ss.s.sealMgr.State().String()}, nil
|
||||
}
|
||||
@@ -1,24 +1,16 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
mcias "git.wntrmute.dev/kyle/mcias/clients/go"
|
||||
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/auth"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/crypto"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/engine"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/engine/ca"
|
||||
@@ -27,25 +19,7 @@ import (
|
||||
)
|
||||
|
||||
func (s *Server) registerRoutes(r chi.Router) {
|
||||
// Static files.
|
||||
r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.Dir("web/static"))))
|
||||
|
||||
// Web UI routes.
|
||||
r.Get("/", s.handleWebRoot)
|
||||
r.HandleFunc("/init", s.handleWebInit)
|
||||
r.HandleFunc("/unseal", s.handleWebUnseal)
|
||||
r.HandleFunc("/login", s.handleWebLogin)
|
||||
r.Get("/dashboard", s.requireAuthWeb(s.handleWebDashboard))
|
||||
r.Post("/dashboard/mount-ca", s.requireAuthWeb(s.handleWebDashboardMountCA))
|
||||
|
||||
r.Route("/pki", func(r chi.Router) {
|
||||
r.Get("/", s.requireAuthWeb(s.handleWebPKI))
|
||||
r.Post("/import-root", s.requireAuthWeb(s.handleWebImportRoot))
|
||||
r.Post("/create-issuer", s.requireAuthWeb(s.handleWebCreateIssuer))
|
||||
r.Get("/{issuer}", s.requireAuthWeb(s.handleWebPKIIssuer))
|
||||
})
|
||||
|
||||
// API routes.
|
||||
// REST API routes — web UI served by metacrypt-web.
|
||||
r.Get("/v1/status", s.handleStatus)
|
||||
r.Post("/v1/init", s.handleInit)
|
||||
r.Post("/v1/unseal", s.handleUnseal)
|
||||
@@ -67,7 +41,8 @@ func (s *Server) registerRoutes(r chi.Router) {
|
||||
|
||||
r.HandleFunc("/v1/policy/rules", s.requireAuth(s.handlePolicyRules))
|
||||
r.HandleFunc("/v1/policy/rule", s.requireAuth(s.handlePolicyRule))
|
||||
s.registerACMERoutes(r)}
|
||||
s.registerACMERoutes(r)
|
||||
}
|
||||
|
||||
// --- API Handlers ---
|
||||
|
||||
@@ -478,474 +453,6 @@ func (s *Server) getCAEngine(mountName string) (*ca.CAEngine, error) {
|
||||
return caEng, nil
|
||||
}
|
||||
|
||||
// findCAMount returns the name of the first CA engine mount.
|
||||
func (s *Server) findCAMount() (string, error) {
|
||||
for _, m := range s.engines.ListMounts() {
|
||||
if m.Type == engine.EngineTypeCA {
|
||||
return m.Name, nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("no CA engine mounted")
|
||||
}
|
||||
|
||||
// --- Web Handlers ---
|
||||
|
||||
func (s *Server) handleWebRoot(w http.ResponseWriter, r *http.Request) {
|
||||
state := s.seal.State()
|
||||
switch state {
|
||||
case seal.StateUninitialized:
|
||||
http.Redirect(w, r, "/init", http.StatusFound)
|
||||
case seal.StateSealed:
|
||||
http.Redirect(w, r, "/unseal", http.StatusFound)
|
||||
case seal.StateInitializing:
|
||||
http.Redirect(w, r, "/init", http.StatusFound)
|
||||
case seal.StateUnsealed:
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) handleWebInit(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
if s.seal.State() != seal.StateUninitialized {
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
return
|
||||
}
|
||||
s.renderTemplate(w, "init.html", nil)
|
||||
case http.MethodPost:
|
||||
r.ParseForm()
|
||||
password := r.FormValue("password")
|
||||
if password == "" {
|
||||
s.renderTemplate(w, "init.html", map[string]interface{}{"Error": "Password is required"})
|
||||
return
|
||||
}
|
||||
params := crypto.Argon2Params{
|
||||
Time: s.cfg.Seal.Argon2Time,
|
||||
Memory: s.cfg.Seal.Argon2Memory,
|
||||
Threads: s.cfg.Seal.Argon2Threads,
|
||||
}
|
||||
if err := s.seal.Initialize(r.Context(), []byte(password), params); err != nil {
|
||||
s.renderTemplate(w, "init.html", map[string]interface{}{"Error": err.Error()})
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
default:
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) handleWebUnseal(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
state := s.seal.State()
|
||||
if state == seal.StateUninitialized {
|
||||
http.Redirect(w, r, "/init", http.StatusFound)
|
||||
return
|
||||
}
|
||||
if state == seal.StateUnsealed {
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
return
|
||||
}
|
||||
s.renderTemplate(w, "unseal.html", nil)
|
||||
case http.MethodPost:
|
||||
r.ParseForm()
|
||||
password := r.FormValue("password")
|
||||
if err := s.seal.Unseal([]byte(password)); err != nil {
|
||||
msg := "Invalid password"
|
||||
if err == seal.ErrRateLimited {
|
||||
msg = "Too many attempts. Please wait 60 seconds."
|
||||
}
|
||||
s.renderTemplate(w, "unseal.html", map[string]interface{}{"Error": msg})
|
||||
return
|
||||
}
|
||||
if err := s.engines.UnsealAll(r.Context()); err != nil {
|
||||
s.logger.Error("engine unseal failed", "error", err)
|
||||
s.renderTemplate(w, "unseal.html", map[string]interface{}{"Error": "Engine reload failed: " + err.Error()})
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
default:
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) handleWebLogin(w http.ResponseWriter, r *http.Request) {
|
||||
if s.seal.State() != seal.StateUnsealed {
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
return
|
||||
}
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
s.renderTemplate(w, "login.html", nil)
|
||||
case http.MethodPost:
|
||||
r.ParseForm()
|
||||
username := r.FormValue("username")
|
||||
password := r.FormValue("password")
|
||||
totpCode := r.FormValue("totp_code")
|
||||
token, _, err := s.auth.Login(username, password, totpCode)
|
||||
if err != nil {
|
||||
s.renderTemplate(w, "login.html", map[string]interface{}{"Error": "Invalid credentials"})
|
||||
return
|
||||
}
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "metacrypt_token",
|
||||
Value: token,
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
Secure: true,
|
||||
SameSite: http.SameSiteStrictMode,
|
||||
})
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
default:
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) handleWebDashboard(w http.ResponseWriter, r *http.Request) {
|
||||
info := TokenInfoFromContext(r.Context())
|
||||
mounts := s.engines.ListMounts()
|
||||
s.renderTemplate(w, "dashboard.html", map[string]interface{}{
|
||||
"Username": info.Username,
|
||||
"IsAdmin": info.IsAdmin,
|
||||
"Roles": info.Roles,
|
||||
"Mounts": mounts,
|
||||
"State": s.seal.State().String(),
|
||||
"Version": s.version,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) handleWebDashboardMountCA(w http.ResponseWriter, r *http.Request) {
|
||||
info := TokenInfoFromContext(r.Context())
|
||||
if !info.IsAdmin {
|
||||
http.Error(w, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseMultipartForm(1 << 20); err != nil {
|
||||
r.ParseForm()
|
||||
}
|
||||
|
||||
mountName := r.FormValue("name")
|
||||
if mountName == "" {
|
||||
s.renderDashboardWithError(w, r, info, "Mount name is required")
|
||||
return
|
||||
}
|
||||
|
||||
config := map[string]interface{}{}
|
||||
if org := r.FormValue("organization"); org != "" {
|
||||
config["organization"] = org
|
||||
}
|
||||
|
||||
// Optional root CA import.
|
||||
var certPEM, keyPEM string
|
||||
if f, _, err := r.FormFile("cert_file"); err == nil {
|
||||
defer f.Close()
|
||||
data, _ := io.ReadAll(io.LimitReader(f, 1<<20))
|
||||
certPEM = string(data)
|
||||
}
|
||||
if f, _, err := r.FormFile("key_file"); err == nil {
|
||||
defer f.Close()
|
||||
data, _ := io.ReadAll(io.LimitReader(f, 1<<20))
|
||||
keyPEM = string(data)
|
||||
}
|
||||
if certPEM != "" && keyPEM != "" {
|
||||
config["root_cert_pem"] = certPEM
|
||||
config["root_key_pem"] = keyPEM
|
||||
}
|
||||
|
||||
if err := s.engines.Mount(r.Context(), mountName, engine.EngineTypeCA, config); err != nil {
|
||||
s.renderDashboardWithError(w, r, info, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/pki", http.StatusFound)
|
||||
}
|
||||
|
||||
func (s *Server) renderDashboardWithError(w http.ResponseWriter, _ *http.Request, info *auth.TokenInfo, errMsg string) {
|
||||
mounts := s.engines.ListMounts()
|
||||
s.renderTemplate(w, "dashboard.html", map[string]interface{}{
|
||||
"Username": info.Username,
|
||||
"IsAdmin": info.IsAdmin,
|
||||
"Roles": info.Roles,
|
||||
"Mounts": mounts,
|
||||
"State": s.seal.State().String(),
|
||||
"MountError": errMsg,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) handleWebPKI(w http.ResponseWriter, r *http.Request) {
|
||||
info := TokenInfoFromContext(r.Context())
|
||||
|
||||
mountName, err := s.findCAMount()
|
||||
if err != nil {
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
caEng, err := s.getCAEngine(mountName)
|
||||
if err != nil {
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]interface{}{
|
||||
"Username": info.Username,
|
||||
"IsAdmin": info.IsAdmin,
|
||||
"MountName": mountName,
|
||||
}
|
||||
|
||||
// Get root cert info.
|
||||
rootPEM, err := caEng.GetRootCertPEM()
|
||||
if err == nil && rootPEM != nil {
|
||||
if cert, err := parsePEMCert(rootPEM); err == nil {
|
||||
data["RootCN"] = cert.Subject.CommonName
|
||||
data["RootOrg"] = strings.Join(cert.Subject.Organization, ", ")
|
||||
data["RootNotBefore"] = cert.NotBefore.Format(time.RFC3339)
|
||||
data["RootNotAfter"] = cert.NotAfter.Format(time.RFC3339)
|
||||
data["RootExpired"] = time.Now().After(cert.NotAfter)
|
||||
data["HasRoot"] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Get issuers.
|
||||
callerInfo := &engine.CallerInfo{
|
||||
Username: info.Username,
|
||||
Roles: info.Roles,
|
||||
IsAdmin: info.IsAdmin,
|
||||
}
|
||||
resp, err := s.engines.HandleRequest(r.Context(), mountName, &engine.Request{
|
||||
Operation: "list-issuers",
|
||||
CallerInfo: callerInfo,
|
||||
})
|
||||
if err == nil {
|
||||
data["Issuers"] = resp.Data["issuers"]
|
||||
}
|
||||
|
||||
s.renderTemplate(w, "pki.html", data)
|
||||
}
|
||||
|
||||
func (s *Server) handleWebImportRoot(w http.ResponseWriter, r *http.Request) {
|
||||
info := TokenInfoFromContext(r.Context())
|
||||
if !info.IsAdmin {
|
||||
http.Error(w, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
mountName, err := s.findCAMount()
|
||||
if err != nil {
|
||||
http.Error(w, "no CA engine mounted", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseMultipartForm(1 << 20); err != nil {
|
||||
r.ParseForm()
|
||||
}
|
||||
|
||||
certPEM := r.FormValue("cert_pem")
|
||||
keyPEM := r.FormValue("key_pem")
|
||||
|
||||
// Also support file uploads.
|
||||
if certPEM == "" {
|
||||
if f, _, err := r.FormFile("cert_file"); err == nil {
|
||||
defer f.Close()
|
||||
data, _ := io.ReadAll(io.LimitReader(f, 1<<20))
|
||||
certPEM = string(data)
|
||||
}
|
||||
}
|
||||
if keyPEM == "" {
|
||||
if f, _, err := r.FormFile("key_file"); err == nil {
|
||||
defer f.Close()
|
||||
data, _ := io.ReadAll(io.LimitReader(f, 1<<20))
|
||||
keyPEM = string(data)
|
||||
}
|
||||
}
|
||||
|
||||
if certPEM == "" || keyPEM == "" {
|
||||
s.renderPKIWithError(w, r, mountName, info, "Certificate and private key are required")
|
||||
return
|
||||
}
|
||||
|
||||
callerInfo := &engine.CallerInfo{
|
||||
Username: info.Username,
|
||||
Roles: info.Roles,
|
||||
IsAdmin: info.IsAdmin,
|
||||
}
|
||||
_, err = s.engines.HandleRequest(r.Context(), mountName, &engine.Request{
|
||||
Operation: "import-root",
|
||||
CallerInfo: callerInfo,
|
||||
Data: map[string]interface{}{
|
||||
"cert_pem": certPEM,
|
||||
"key_pem": keyPEM,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
s.renderPKIWithError(w, r, mountName, info, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/pki", http.StatusFound)
|
||||
}
|
||||
|
||||
func (s *Server) handleWebCreateIssuer(w http.ResponseWriter, r *http.Request) {
|
||||
info := TokenInfoFromContext(r.Context())
|
||||
if !info.IsAdmin {
|
||||
http.Error(w, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
mountName, err := s.findCAMount()
|
||||
if err != nil {
|
||||
http.Error(w, "no CA engine mounted", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
|
||||
name := r.FormValue("name")
|
||||
if name == "" {
|
||||
s.renderPKIWithError(w, r, mountName, info, "Issuer name is required")
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]interface{}{
|
||||
"name": name,
|
||||
}
|
||||
if v := r.FormValue("expiry"); v != "" {
|
||||
data["expiry"] = v
|
||||
}
|
||||
if v := r.FormValue("max_ttl"); v != "" {
|
||||
data["max_ttl"] = v
|
||||
}
|
||||
if v := r.FormValue("key_algorithm"); v != "" {
|
||||
data["key_algorithm"] = v
|
||||
}
|
||||
if v := r.FormValue("key_size"); v != "" {
|
||||
// Parse as float64 to match JSON number convention used by the engine.
|
||||
var size float64
|
||||
if _, err := fmt.Sscanf(v, "%f", &size); err == nil {
|
||||
data["key_size"] = size
|
||||
}
|
||||
}
|
||||
|
||||
callerInfo := &engine.CallerInfo{
|
||||
Username: info.Username,
|
||||
Roles: info.Roles,
|
||||
IsAdmin: info.IsAdmin,
|
||||
}
|
||||
_, err = s.engines.HandleRequest(r.Context(), mountName, &engine.Request{
|
||||
Operation: "create-issuer",
|
||||
CallerInfo: callerInfo,
|
||||
Data: data,
|
||||
})
|
||||
if err != nil {
|
||||
s.renderPKIWithError(w, r, mountName, info, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/pki", http.StatusFound)
|
||||
}
|
||||
|
||||
func (s *Server) handleWebPKIIssuer(w http.ResponseWriter, r *http.Request) {
|
||||
mountName, err := s.findCAMount()
|
||||
if err != nil {
|
||||
http.Error(w, "no CA engine mounted", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
issuerName := chi.URLParam(r, "issuer")
|
||||
caEng, err := s.getCAEngine(mountName)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
certPEM, err := caEng.GetIssuerCertPEM(issuerName)
|
||||
if err != nil {
|
||||
http.Error(w, "issuer not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/x-pem-file")
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.pem", issuerName))
|
||||
w.Write(certPEM)
|
||||
}
|
||||
|
||||
func (s *Server) renderPKIWithError(w http.ResponseWriter, r *http.Request, mountName string, info *auth.TokenInfo, errMsg string) {
|
||||
data := map[string]interface{}{
|
||||
"Username": info.Username,
|
||||
"IsAdmin": info.IsAdmin,
|
||||
"MountName": mountName,
|
||||
"Error": errMsg,
|
||||
}
|
||||
|
||||
// Try to load existing root info.
|
||||
mount, merr := s.engines.GetMount(mountName)
|
||||
if merr == nil && mount.Type == engine.EngineTypeCA {
|
||||
if caEng, ok := mount.Engine.(*ca.CAEngine); ok {
|
||||
rootPEM, err := caEng.GetRootCertPEM()
|
||||
if err == nil && rootPEM != nil {
|
||||
if cert, err := parsePEMCert(rootPEM); err == nil {
|
||||
data["RootCN"] = cert.Subject.CommonName
|
||||
data["RootOrg"] = strings.Join(cert.Subject.Organization, ", ")
|
||||
data["RootNotBefore"] = cert.NotBefore.Format(time.RFC3339)
|
||||
data["RootNotAfter"] = cert.NotAfter.Format(time.RFC3339)
|
||||
data["RootExpired"] = time.Now().After(cert.NotAfter)
|
||||
data["HasRoot"] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.renderTemplate(w, "pki.html", data)
|
||||
}
|
||||
|
||||
func parsePEMCert(pemData []byte) (*x509.Certificate, error) {
|
||||
block, _ := pem.Decode(pemData)
|
||||
if block == nil {
|
||||
return nil, errors.New("no PEM block found")
|
||||
}
|
||||
return x509.ParseCertificate(block.Bytes)
|
||||
}
|
||||
|
||||
// requireAuthWeb redirects to login for web pages instead of returning 401.
|
||||
func (s *Server) requireAuthWeb(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if s.seal.State() != seal.StateUnsealed {
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
return
|
||||
}
|
||||
token := extractToken(r)
|
||||
if token == "" {
|
||||
http.Redirect(w, r, "/login", http.StatusFound)
|
||||
return
|
||||
}
|
||||
info, err := s.auth.ValidateToken(token)
|
||||
if err != nil {
|
||||
http.Redirect(w, r, "/login", http.StatusFound)
|
||||
return
|
||||
}
|
||||
ctx := r.Context()
|
||||
ctx = context.WithValue(ctx, tokenInfoKey, info)
|
||||
next(w, r.WithContext(ctx))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) renderTemplate(w http.ResponseWriter, name string, data interface{}) {
|
||||
tmpl, err := template.ParseFiles(
|
||||
filepath.Join("web", "templates", "layout.html"),
|
||||
filepath.Join("web", "templates", name),
|
||||
)
|
||||
if err != nil {
|
||||
s.logger.Error("parse template", "name", name, "error", err)
|
||||
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
if err := tmpl.ExecuteTemplate(w, "layout", data); err != nil {
|
||||
s.logger.Error("execute template", "name", name, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func writeJSON(w http.ResponseWriter, status int, v interface{}) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
|
||||
@@ -151,18 +151,15 @@ func TestStatusMethodNotAllowed(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRootRedirect(t *testing.T) {
|
||||
func TestRootNotFound(t *testing.T) {
|
||||
_, _, mux := setupTestServer(t)
|
||||
|
||||
// The vault server no longer serves a web UI at /; that is handled by metacrypt-web.
|
||||
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
w := httptest.NewRecorder()
|
||||
mux.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusFound {
|
||||
t.Errorf("root redirect: got %d, want %d", w.Code, http.StatusFound)
|
||||
}
|
||||
loc := w.Header().Get("Location")
|
||||
if loc != "/init" {
|
||||
t.Errorf("redirect location: got %q, want /init", loc)
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Errorf("root: got %d, want %d", w.Code, http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
199
internal/webserver/client.go
Normal file
199
internal/webserver/client.go
Normal file
@@ -0,0 +1,199 @@
|
||||
package webserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1"
|
||||
)
|
||||
|
||||
// VaultClient wraps the gRPC stubs for communicating with the vault.
|
||||
type VaultClient struct {
|
||||
conn *grpc.ClientConn
|
||||
system pb.SystemServiceClient
|
||||
auth pb.AuthServiceClient
|
||||
engine pb.EngineServiceClient
|
||||
pki pb.PKIServiceClient
|
||||
}
|
||||
|
||||
// NewVaultClient dials the vault gRPC server and returns a client.
|
||||
func NewVaultClient(addr, caCertPath string) (*VaultClient, error) {
|
||||
tlsCfg := &tls.Config{MinVersion: tls.VersionTLS12}
|
||||
if caCertPath != "" {
|
||||
pemData, err := os.ReadFile(caCertPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("webserver: read CA cert: %w", err)
|
||||
}
|
||||
pool := x509.NewCertPool()
|
||||
if !pool.AppendCertsFromPEM(pemData) {
|
||||
return nil, fmt.Errorf("webserver: parse CA cert")
|
||||
}
|
||||
tlsCfg.RootCAs = pool
|
||||
}
|
||||
|
||||
conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(credentials.NewTLS(tlsCfg)))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("webserver: dial vault: %w", err)
|
||||
}
|
||||
|
||||
return &VaultClient{
|
||||
conn: conn,
|
||||
system: pb.NewSystemServiceClient(conn),
|
||||
auth: pb.NewAuthServiceClient(conn),
|
||||
engine: pb.NewEngineServiceClient(conn),
|
||||
pki: pb.NewPKIServiceClient(conn),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Close closes the underlying connection.
|
||||
func (c *VaultClient) Close() error {
|
||||
return c.conn.Close()
|
||||
}
|
||||
|
||||
// withToken returns a context with the Bearer token in outgoing metadata.
|
||||
func withToken(ctx context.Context, token string) context.Context {
|
||||
return metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer "+token)
|
||||
}
|
||||
|
||||
// Status returns the current vault state string (e.g. "unsealed").
|
||||
func (c *VaultClient) Status(ctx context.Context) (string, error) {
|
||||
resp, err := c.system.Status(ctx, &pb.StatusRequest{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return resp.State, nil
|
||||
}
|
||||
|
||||
// Init initializes the vault with the given password.
|
||||
func (c *VaultClient) Init(ctx context.Context, password string) error {
|
||||
_, err := c.system.Init(ctx, &pb.InitRequest{Password: password})
|
||||
return err
|
||||
}
|
||||
|
||||
// Unseal unseals the vault with the given password.
|
||||
func (c *VaultClient) Unseal(ctx context.Context, password string) error {
|
||||
_, err := c.system.Unseal(ctx, &pb.UnsealRequest{Password: password})
|
||||
return err
|
||||
}
|
||||
|
||||
// TokenInfo holds validated token details returned by the vault.
|
||||
type TokenInfo struct {
|
||||
Username string
|
||||
Roles []string
|
||||
IsAdmin bool
|
||||
}
|
||||
|
||||
// Login authenticates against the vault and returns the session token.
|
||||
func (c *VaultClient) Login(ctx context.Context, username, password, totpCode string) (string, error) {
|
||||
resp, err := c.auth.Login(ctx, &pb.LoginRequest{
|
||||
Username: username,
|
||||
Password: password,
|
||||
TotpCode: totpCode,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return resp.Token, nil
|
||||
}
|
||||
|
||||
// ValidateToken validates a token against the vault and returns the token info.
|
||||
func (c *VaultClient) ValidateToken(ctx context.Context, token string) (*TokenInfo, error) {
|
||||
resp, err := c.auth.TokenInfo(withToken(ctx, token), &pb.TokenInfoRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &TokenInfo{
|
||||
Username: resp.Username,
|
||||
Roles: resp.Roles,
|
||||
IsAdmin: resp.IsAdmin,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MountInfo holds metadata about an engine mount.
|
||||
type MountInfo struct {
|
||||
Name string
|
||||
Type string
|
||||
MountPath string
|
||||
}
|
||||
|
||||
// ListMounts returns all engine mounts from the vault.
|
||||
func (c *VaultClient) ListMounts(ctx context.Context, token string) ([]MountInfo, error) {
|
||||
resp, err := c.engine.ListMounts(withToken(ctx, token), &pb.ListMountsRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mounts := make([]MountInfo, 0, len(resp.Mounts))
|
||||
for _, m := range resp.Mounts {
|
||||
mounts = append(mounts, MountInfo{
|
||||
Name: m.Name,
|
||||
Type: m.Type,
|
||||
MountPath: m.MountPath,
|
||||
})
|
||||
}
|
||||
return mounts, nil
|
||||
}
|
||||
|
||||
// Mount creates a new engine mount on the vault.
|
||||
func (c *VaultClient) Mount(ctx context.Context, token, name, engineType string, config map[string]interface{}) error {
|
||||
req := &pb.MountRequest{
|
||||
Name: name,
|
||||
Type: engineType,
|
||||
}
|
||||
if len(config) > 0 {
|
||||
s, err := structFromMap(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("webserver: encode mount config: %w", err)
|
||||
}
|
||||
req.Config = s
|
||||
}
|
||||
_, err := c.engine.Mount(withToken(ctx, token), req)
|
||||
return err
|
||||
}
|
||||
|
||||
// EngineRequest sends a generic engine operation to the vault.
|
||||
func (c *VaultClient) EngineRequest(ctx context.Context, token, mount, operation string, data map[string]interface{}) (map[string]interface{}, error) {
|
||||
req := &pb.EngineRequest{
|
||||
Mount: mount,
|
||||
Operation: operation,
|
||||
}
|
||||
if len(data) > 0 {
|
||||
s, err := structFromMap(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("webserver: encode engine request: %w", err)
|
||||
}
|
||||
req.Data = s
|
||||
}
|
||||
resp, err := c.engine.Request(withToken(ctx, token), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Data == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return resp.Data.AsMap(), nil
|
||||
}
|
||||
|
||||
// GetRootCert returns the root CA certificate PEM for the given mount.
|
||||
func (c *VaultClient) GetRootCert(ctx context.Context, mount string) ([]byte, error) {
|
||||
resp, err := c.pki.GetRootCert(ctx, &pb.GetRootCertRequest{Mount: mount})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.CertPem, nil
|
||||
}
|
||||
|
||||
// GetIssuerCert returns a named issuer certificate PEM for the given mount.
|
||||
func (c *VaultClient) GetIssuerCert(ctx context.Context, mount, issuer string) ([]byte, error) {
|
||||
resp, err := c.pki.GetIssuerCert(ctx, &pb.GetIssuerCertRequest{Mount: mount, Issuer: issuer})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.CertPem, nil
|
||||
}
|
||||
430
internal/webserver/routes.go
Normal file
430
internal/webserver/routes.go
Normal file
@@ -0,0 +1,430 @@
|
||||
package webserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func (ws *WebServer) registerRoutes(r chi.Router) {
|
||||
r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.FS(ws.staticFS))))
|
||||
|
||||
r.Get("/", ws.handleRoot)
|
||||
r.HandleFunc("/init", ws.handleInit)
|
||||
r.HandleFunc("/unseal", ws.handleUnseal)
|
||||
r.HandleFunc("/login", ws.handleLogin)
|
||||
r.Get("/dashboard", ws.requireAuth(ws.handleDashboard))
|
||||
r.Post("/dashboard/mount-ca", ws.requireAuth(ws.handleDashboardMountCA))
|
||||
|
||||
r.Route("/pki", func(r chi.Router) {
|
||||
r.Get("/", ws.requireAuth(ws.handlePKI))
|
||||
r.Post("/import-root", ws.requireAuth(ws.handleImportRoot))
|
||||
r.Post("/create-issuer", ws.requireAuth(ws.handleCreateIssuer))
|
||||
r.Get("/{issuer}", ws.requireAuth(ws.handlePKIIssuer))
|
||||
})
|
||||
}
|
||||
|
||||
// requireAuth validates the token cookie against the vault and injects TokenInfo.
|
||||
func (ws *WebServer) requireAuth(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
state, err := ws.vault.Status(r.Context())
|
||||
if err != nil || state != "unsealed" {
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
return
|
||||
}
|
||||
token := extractCookie(r)
|
||||
if token == "" {
|
||||
http.Redirect(w, r, "/login", http.StatusFound)
|
||||
return
|
||||
}
|
||||
info, err := ws.vault.ValidateToken(r.Context(), token)
|
||||
if err != nil {
|
||||
http.Redirect(w, r, "/login", http.StatusFound)
|
||||
return
|
||||
}
|
||||
r = r.WithContext(withTokenInfo(r.Context(), info))
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *WebServer) handleRoot(w http.ResponseWriter, r *http.Request) {
|
||||
state, err := ws.vault.Status(r.Context())
|
||||
if err != nil {
|
||||
ws.renderTemplate(w, "unseal.html", map[string]interface{}{"Error": "Cannot reach vault"})
|
||||
return
|
||||
}
|
||||
switch state {
|
||||
case "uninitialized", "initializing":
|
||||
http.Redirect(w, r, "/init", http.StatusFound)
|
||||
case "sealed":
|
||||
http.Redirect(w, r, "/unseal", http.StatusFound)
|
||||
case "unsealed":
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
default:
|
||||
http.Redirect(w, r, "/unseal", http.StatusFound)
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *WebServer) handleInit(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
state, _ := ws.vault.Status(r.Context())
|
||||
if state != "uninitialized" && state != "" {
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
return
|
||||
}
|
||||
ws.renderTemplate(w, "init.html", nil)
|
||||
case http.MethodPost:
|
||||
r.ParseForm()
|
||||
password := r.FormValue("password")
|
||||
if password == "" {
|
||||
ws.renderTemplate(w, "init.html", map[string]interface{}{"Error": "Password is required"})
|
||||
return
|
||||
}
|
||||
if err := ws.vault.Init(r.Context(), password); err != nil {
|
||||
ws.renderTemplate(w, "init.html", map[string]interface{}{"Error": grpcMessage(err)})
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
default:
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *WebServer) handleUnseal(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
state, _ := ws.vault.Status(r.Context())
|
||||
if state == "uninitialized" {
|
||||
http.Redirect(w, r, "/init", http.StatusFound)
|
||||
return
|
||||
}
|
||||
if state == "unsealed" {
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
return
|
||||
}
|
||||
ws.renderTemplate(w, "unseal.html", nil)
|
||||
case http.MethodPost:
|
||||
r.ParseForm()
|
||||
password := r.FormValue("password")
|
||||
if err := ws.vault.Unseal(r.Context(), password); err != nil {
|
||||
msg := "Invalid password"
|
||||
if st, ok := status.FromError(err); ok && st.Code() == codes.ResourceExhausted {
|
||||
msg = "Too many attempts. Please wait 60 seconds."
|
||||
}
|
||||
ws.renderTemplate(w, "unseal.html", map[string]interface{}{"Error": msg})
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
default:
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *WebServer) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
state, _ := ws.vault.Status(r.Context())
|
||||
if state != "unsealed" {
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
return
|
||||
}
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
ws.renderTemplate(w, "login.html", nil)
|
||||
case http.MethodPost:
|
||||
r.ParseForm()
|
||||
token, err := ws.vault.Login(r.Context(),
|
||||
r.FormValue("username"),
|
||||
r.FormValue("password"),
|
||||
r.FormValue("totp_code"),
|
||||
)
|
||||
if err != nil {
|
||||
ws.renderTemplate(w, "login.html", map[string]interface{}{"Error": "Invalid credentials"})
|
||||
return
|
||||
}
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "metacrypt_token",
|
||||
Value: token,
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
Secure: true,
|
||||
SameSite: http.SameSiteStrictMode,
|
||||
})
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
default:
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *WebServer) handleDashboard(w http.ResponseWriter, r *http.Request) {
|
||||
info := tokenInfoFromContext(r.Context())
|
||||
token := extractCookie(r)
|
||||
mounts, _ := ws.vault.ListMounts(r.Context(), token)
|
||||
state, _ := ws.vault.Status(r.Context())
|
||||
ws.renderTemplate(w, "dashboard.html", map[string]interface{}{
|
||||
"Username": info.Username,
|
||||
"IsAdmin": info.IsAdmin,
|
||||
"Roles": info.Roles,
|
||||
"Mounts": mounts,
|
||||
"State": state,
|
||||
})
|
||||
}
|
||||
|
||||
func (ws *WebServer) handleDashboardMountCA(w http.ResponseWriter, r *http.Request) {
|
||||
info := tokenInfoFromContext(r.Context())
|
||||
if !info.IsAdmin {
|
||||
http.Error(w, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseMultipartForm(1 << 20); err != nil {
|
||||
r.ParseForm()
|
||||
}
|
||||
|
||||
mountName := r.FormValue("name")
|
||||
if mountName == "" {
|
||||
ws.renderDashboardWithError(w, r, info, "Mount name is required")
|
||||
return
|
||||
}
|
||||
|
||||
cfg := map[string]interface{}{}
|
||||
if org := r.FormValue("organization"); org != "" {
|
||||
cfg["organization"] = org
|
||||
}
|
||||
|
||||
var certPEM, keyPEM string
|
||||
if f, _, err := r.FormFile("cert_file"); err == nil {
|
||||
defer f.Close()
|
||||
data, _ := io.ReadAll(io.LimitReader(f, 1<<20))
|
||||
certPEM = string(data)
|
||||
}
|
||||
if f, _, err := r.FormFile("key_file"); err == nil {
|
||||
defer f.Close()
|
||||
data, _ := io.ReadAll(io.LimitReader(f, 1<<20))
|
||||
keyPEM = string(data)
|
||||
}
|
||||
if certPEM != "" && keyPEM != "" {
|
||||
cfg["root_cert_pem"] = certPEM
|
||||
cfg["root_key_pem"] = keyPEM
|
||||
}
|
||||
|
||||
token := extractCookie(r)
|
||||
if err := ws.vault.Mount(r.Context(), token, mountName, "ca", cfg); err != nil {
|
||||
ws.renderDashboardWithError(w, r, info, grpcMessage(err))
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/pki", http.StatusFound)
|
||||
}
|
||||
|
||||
func (ws *WebServer) renderDashboardWithError(w http.ResponseWriter, r *http.Request, info *TokenInfo, errMsg string) {
|
||||
token := extractCookie(r)
|
||||
mounts, _ := ws.vault.ListMounts(r.Context(), token)
|
||||
state, _ := ws.vault.Status(r.Context())
|
||||
ws.renderTemplate(w, "dashboard.html", map[string]interface{}{
|
||||
"Username": info.Username,
|
||||
"IsAdmin": info.IsAdmin,
|
||||
"Roles": info.Roles,
|
||||
"Mounts": mounts,
|
||||
"State": state,
|
||||
"MountError": errMsg,
|
||||
})
|
||||
}
|
||||
|
||||
func (ws *WebServer) handlePKI(w http.ResponseWriter, r *http.Request) {
|
||||
info := tokenInfoFromContext(r.Context())
|
||||
token := extractCookie(r)
|
||||
|
||||
mountName, err := ws.findCAMount(r, token)
|
||||
if err != nil {
|
||||
http.Redirect(w, r, "/dashboard", http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]interface{}{
|
||||
"Username": info.Username,
|
||||
"IsAdmin": info.IsAdmin,
|
||||
"MountName": mountName,
|
||||
}
|
||||
|
||||
if rootPEM, err := ws.vault.GetRootCert(r.Context(), mountName); err == nil && len(rootPEM) > 0 {
|
||||
if cert, err := parsePEMCert(rootPEM); err == nil {
|
||||
data["RootCN"] = cert.Subject.CommonName
|
||||
data["RootOrg"] = strings.Join(cert.Subject.Organization, ", ")
|
||||
data["RootNotBefore"] = cert.NotBefore.Format(time.RFC3339)
|
||||
data["RootNotAfter"] = cert.NotAfter.Format(time.RFC3339)
|
||||
data["RootExpired"] = time.Now().After(cert.NotAfter)
|
||||
data["HasRoot"] = true
|
||||
}
|
||||
}
|
||||
|
||||
if resp, err := ws.vault.EngineRequest(r.Context(), token, mountName, "list-issuers", nil); err == nil {
|
||||
data["Issuers"] = resp["issuers"]
|
||||
}
|
||||
|
||||
ws.renderTemplate(w, "pki.html", data)
|
||||
}
|
||||
|
||||
func (ws *WebServer) handleImportRoot(w http.ResponseWriter, r *http.Request) {
|
||||
info := tokenInfoFromContext(r.Context())
|
||||
if !info.IsAdmin {
|
||||
http.Error(w, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
token := extractCookie(r)
|
||||
mountName, err := ws.findCAMount(r, token)
|
||||
if err != nil {
|
||||
http.Error(w, "no CA engine mounted", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseMultipartForm(1 << 20); err != nil {
|
||||
r.ParseForm()
|
||||
}
|
||||
|
||||
certPEM := r.FormValue("cert_pem")
|
||||
keyPEM := r.FormValue("key_pem")
|
||||
if certPEM == "" {
|
||||
if f, _, err := r.FormFile("cert_file"); err == nil {
|
||||
defer f.Close()
|
||||
data, _ := io.ReadAll(io.LimitReader(f, 1<<20))
|
||||
certPEM = string(data)
|
||||
}
|
||||
}
|
||||
if keyPEM == "" {
|
||||
if f, _, err := r.FormFile("key_file"); err == nil {
|
||||
defer f.Close()
|
||||
data, _ := io.ReadAll(io.LimitReader(f, 1<<20))
|
||||
keyPEM = string(data)
|
||||
}
|
||||
}
|
||||
|
||||
if certPEM == "" || keyPEM == "" {
|
||||
ws.renderPKIWithError(w, r, mountName, info, "Certificate and private key are required")
|
||||
return
|
||||
}
|
||||
|
||||
_, err = ws.vault.EngineRequest(r.Context(), token, mountName, "import-root", map[string]interface{}{
|
||||
"cert_pem": certPEM,
|
||||
"key_pem": keyPEM,
|
||||
})
|
||||
if err != nil {
|
||||
ws.renderPKIWithError(w, r, mountName, info, grpcMessage(err))
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/pki", http.StatusFound)
|
||||
}
|
||||
|
||||
func (ws *WebServer) handleCreateIssuer(w http.ResponseWriter, r *http.Request) {
|
||||
info := tokenInfoFromContext(r.Context())
|
||||
if !info.IsAdmin {
|
||||
http.Error(w, "forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
token := extractCookie(r)
|
||||
mountName, err := ws.findCAMount(r, token)
|
||||
if err != nil {
|
||||
http.Error(w, "no CA engine mounted", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
r.ParseForm()
|
||||
name := r.FormValue("name")
|
||||
if name == "" {
|
||||
ws.renderPKIWithError(w, r, mountName, info, "Issuer name is required")
|
||||
return
|
||||
}
|
||||
|
||||
reqData := map[string]interface{}{"name": name}
|
||||
if v := r.FormValue("expiry"); v != "" {
|
||||
reqData["expiry"] = v
|
||||
}
|
||||
if v := r.FormValue("max_ttl"); v != "" {
|
||||
reqData["max_ttl"] = v
|
||||
}
|
||||
if v := r.FormValue("key_algorithm"); v != "" {
|
||||
reqData["key_algorithm"] = v
|
||||
}
|
||||
if v := r.FormValue("key_size"); v != "" {
|
||||
var size float64
|
||||
if _, err := fmt.Sscanf(v, "%f", &size); err == nil {
|
||||
reqData["key_size"] = size
|
||||
}
|
||||
}
|
||||
|
||||
_, err = ws.vault.EngineRequest(r.Context(), token, mountName, "create-issuer", reqData)
|
||||
if err != nil {
|
||||
ws.renderPKIWithError(w, r, mountName, info, grpcMessage(err))
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/pki", http.StatusFound)
|
||||
}
|
||||
|
||||
func (ws *WebServer) handlePKIIssuer(w http.ResponseWriter, r *http.Request) {
|
||||
token := extractCookie(r)
|
||||
mountName, err := ws.findCAMount(r, token)
|
||||
if err != nil {
|
||||
http.Error(w, "no CA engine mounted", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
issuerName := chi.URLParam(r, "issuer")
|
||||
certPEM, err := ws.vault.GetIssuerCert(r.Context(), mountName, issuerName)
|
||||
if err != nil {
|
||||
http.Error(w, "issuer not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/x-pem-file")
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.pem", issuerName))
|
||||
w.Write(certPEM)
|
||||
}
|
||||
|
||||
func (ws *WebServer) renderPKIWithError(w http.ResponseWriter, r *http.Request, mountName string, info *TokenInfo, errMsg string) {
|
||||
data := map[string]interface{}{
|
||||
"Username": info.Username,
|
||||
"IsAdmin": info.IsAdmin,
|
||||
"MountName": mountName,
|
||||
"Error": errMsg,
|
||||
}
|
||||
|
||||
if rootPEM, err := ws.vault.GetRootCert(r.Context(), mountName); err == nil && len(rootPEM) > 0 {
|
||||
if cert, err := parsePEMCert(rootPEM); err == nil {
|
||||
data["RootCN"] = cert.Subject.CommonName
|
||||
data["RootOrg"] = strings.Join(cert.Subject.Organization, ", ")
|
||||
data["RootNotBefore"] = cert.NotBefore.Format(time.RFC3339)
|
||||
data["RootNotAfter"] = cert.NotAfter.Format(time.RFC3339)
|
||||
data["RootExpired"] = time.Now().After(cert.NotAfter)
|
||||
data["HasRoot"] = true
|
||||
}
|
||||
}
|
||||
|
||||
ws.renderTemplate(w, "pki.html", data)
|
||||
}
|
||||
|
||||
func (ws *WebServer) findCAMount(r *http.Request, token string) (string, error) {
|
||||
mounts, err := ws.vault.ListMounts(r.Context(), token)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, m := range mounts {
|
||||
if m.Type == "ca" {
|
||||
return m.Name, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("no CA engine mounted")
|
||||
}
|
||||
|
||||
// grpcMessage extracts a human-readable message from a gRPC error.
|
||||
func grpcMessage(err error) string {
|
||||
if st, ok := status.FromError(err); ok {
|
||||
return st.Message()
|
||||
}
|
||||
return err.Error()
|
||||
}
|
||||
112
internal/webserver/server.go
Normal file
112
internal/webserver/server.go
Normal file
@@ -0,0 +1,112 @@
|
||||
// Package webserver implements the standalone web UI server for Metacrypt.
|
||||
// It communicates with the vault over gRPC and renders server-side HTML.
|
||||
package webserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
webui "git.wntrmute.dev/kyle/metacrypt/web"
|
||||
"git.wntrmute.dev/kyle/metacrypt/internal/config"
|
||||
)
|
||||
|
||||
// WebServer is the standalone web UI server.
|
||||
type WebServer struct {
|
||||
cfg *config.Config
|
||||
vault *VaultClient
|
||||
logger *slog.Logger
|
||||
httpSrv *http.Server
|
||||
staticFS fs.FS
|
||||
}
|
||||
|
||||
// New creates a new WebServer. It dials the vault gRPC endpoint.
|
||||
func New(cfg *config.Config, logger *slog.Logger) (*WebServer, error) {
|
||||
vault, err := NewVaultClient(cfg.Web.VaultGRPC, cfg.Web.VaultCACert)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("webserver: connect to vault: %w", err)
|
||||
}
|
||||
|
||||
staticFS, err := fs.Sub(webui.FS, "static")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("webserver: static FS: %w", err)
|
||||
}
|
||||
|
||||
return &WebServer{
|
||||
cfg: cfg,
|
||||
vault: vault,
|
||||
logger: logger,
|
||||
staticFS: staticFS,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Start starts the web server. It blocks until the server is closed.
|
||||
func (ws *WebServer) Start() error {
|
||||
r := chi.NewRouter()
|
||||
ws.registerRoutes(r)
|
||||
|
||||
ws.httpSrv = &http.Server{
|
||||
Addr: ws.cfg.Web.ListenAddr,
|
||||
Handler: r,
|
||||
ReadTimeout: 30 * time.Second,
|
||||
WriteTimeout: 30 * time.Second,
|
||||
IdleTimeout: 120 * time.Second,
|
||||
}
|
||||
|
||||
ws.logger.Info("starting web server", "addr", ws.cfg.Web.ListenAddr)
|
||||
|
||||
if ws.cfg.Web.TLSCert != "" && ws.cfg.Web.TLSKey != "" {
|
||||
ws.httpSrv.TLSConfig = &tls.Config{MinVersion: tls.VersionTLS12}
|
||||
err := ws.httpSrv.ListenAndServeTLS(ws.cfg.Web.TLSCert, ws.cfg.Web.TLSKey)
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
return fmt.Errorf("webserver: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
err := ws.httpSrv.ListenAndServe()
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
return fmt.Errorf("webserver: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Shutdown gracefully shuts down the web server.
|
||||
func (ws *WebServer) Shutdown(ctx context.Context) error {
|
||||
_ = ws.vault.Close()
|
||||
if ws.httpSrv != nil {
|
||||
return ws.httpSrv.Shutdown(ctx)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ws *WebServer) renderTemplate(w http.ResponseWriter, name string, data interface{}) {
|
||||
tmpl, err := template.ParseFS(webui.FS,
|
||||
"templates/layout.html",
|
||||
"templates/"+name,
|
||||
)
|
||||
if err != nil {
|
||||
ws.logger.Error("parse template", "name", name, "error", err)
|
||||
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
if err := tmpl.ExecuteTemplate(w, "layout", data); err != nil {
|
||||
ws.logger.Error("execute template", "name", name, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func extractCookie(r *http.Request) string {
|
||||
c, err := r.Cookie("metacrypt_token")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return c.Value
|
||||
}
|
||||
37
internal/webserver/util.go
Normal file
37
internal/webserver/util.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package webserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
type contextKey int
|
||||
|
||||
const tokenInfoCtxKey contextKey = iota
|
||||
|
||||
func withTokenInfo(ctx context.Context, info *TokenInfo) context.Context {
|
||||
return context.WithValue(ctx, tokenInfoCtxKey, info)
|
||||
}
|
||||
|
||||
func tokenInfoFromContext(ctx context.Context) *TokenInfo {
|
||||
v, _ := ctx.Value(tokenInfoCtxKey).(*TokenInfo)
|
||||
return v
|
||||
}
|
||||
|
||||
// structFromMap converts a map[string]interface{} to a *structpb.Struct.
|
||||
func structFromMap(m map[string]interface{}) (*structpb.Struct, error) {
|
||||
return structpb.NewStruct(m)
|
||||
}
|
||||
|
||||
// parsePEMCert decodes the first PEM block and parses it as an x509 certificate.
|
||||
func parsePEMCert(pemData []byte) (*x509.Certificate, error) {
|
||||
block, _ := pem.Decode(pemData)
|
||||
if block == nil {
|
||||
return nil, errors.New("no PEM block found")
|
||||
}
|
||||
return x509.ParseCertificate(block.Bytes)
|
||||
}
|
||||
9
web/embed.go
Normal file
9
web/embed.go
Normal file
@@ -0,0 +1,9 @@
|
||||
// Package webui provides the embedded web UI assets (templates and static files).
|
||||
package webui
|
||||
|
||||
import "embed"
|
||||
|
||||
// FS contains all web UI templates and static files.
|
||||
//
|
||||
//go:embed templates static
|
||||
var FS embed.FS
|
||||
Reference in New Issue
Block a user