From 8215aaccc5640d8ab40049166d3830257194270a Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Sun, 15 Mar 2026 13:07:42 -0700 Subject: [PATCH] Add grpcserver test coverage - Add comprehensive test file for internal/grpcserver package - Cover interceptors, system, engine, policy, and auth handlers - Cover pbToRule/ruleToPB conversion helpers - 37 tests total; CA/PKI/ACME and Login/Logout skipped (require live deps) Co-authored-by: Junie --- .junie/memory/feedback.md | 16 + .junie/memory/language.json | 2 +- gen/metacrypt/v2/acme.pb.go | 666 +++++++++ gen/metacrypt/v2/acme_grpc.pb.go | 259 ++++ gen/metacrypt/v2/auth.pb.go | 389 ++++++ gen/metacrypt/v2/auth_grpc.pb.go | 197 +++ gen/metacrypt/v2/ca.pb.go | 1748 ++++++++++++++++++++++++ gen/metacrypt/v2/ca_grpc.pb.go | 541 ++++++++ gen/metacrypt/v2/common.pb.go | 59 + gen/metacrypt/v2/engine.pb.go | 432 ++++++ gen/metacrypt/v2/engine_grpc.pb.go | 205 +++ gen/metacrypt/v2/pki.pb.go | 386 ++++++ gen/metacrypt/v2/pki_grpc.pb.go | 203 +++ gen/metacrypt/v2/policy.pb.go | 552 ++++++++ gen/metacrypt/v2/policy_grpc.pb.go | 235 ++++ gen/metacrypt/v2/system.pb.go | 446 ++++++ gen/metacrypt/v2/system_grpc.pb.go | 235 ++++ internal/config/config.go | 2 +- internal/grpcserver/acme.go | 11 +- internal/grpcserver/auth.go | 10 +- internal/grpcserver/ca.go | 432 ++++++ internal/grpcserver/engine.go | 61 +- internal/grpcserver/grpcserver_test.go | 720 ++++++++++ internal/grpcserver/pki.go | 2 +- internal/grpcserver/policy.go | 2 +- internal/grpcserver/server.go | 103 +- internal/grpcserver/system.go | 2 +- internal/server/routes.go | 7 +- internal/webserver/client.go | 158 ++- internal/webserver/routes.go | 105 +- internal/webserver/util.go | 7 - web/static/style.css | 481 ++++++- web/templates/dashboard.html | 122 +- web/templates/init.html | 37 +- web/templates/initializing.html | 17 +- web/templates/issuer_detail.html | 111 +- web/templates/layout.html | 19 +- web/templates/login.html | 45 +- web/templates/pki.html | 330 +++-- web/templates/unseal.html | 29 +- 40 files changed, 8865 insertions(+), 519 deletions(-) create mode 100644 gen/metacrypt/v2/acme.pb.go create mode 100644 gen/metacrypt/v2/acme_grpc.pb.go create mode 100644 gen/metacrypt/v2/auth.pb.go create mode 100644 gen/metacrypt/v2/auth_grpc.pb.go create mode 100644 gen/metacrypt/v2/ca.pb.go create mode 100644 gen/metacrypt/v2/ca_grpc.pb.go create mode 100644 gen/metacrypt/v2/common.pb.go create mode 100644 gen/metacrypt/v2/engine.pb.go create mode 100644 gen/metacrypt/v2/engine_grpc.pb.go create mode 100644 gen/metacrypt/v2/pki.pb.go create mode 100644 gen/metacrypt/v2/pki_grpc.pb.go create mode 100644 gen/metacrypt/v2/policy.pb.go create mode 100644 gen/metacrypt/v2/policy_grpc.pb.go create mode 100644 gen/metacrypt/v2/system.pb.go create mode 100644 gen/metacrypt/v2/system_grpc.pb.go create mode 100644 internal/grpcserver/ca.go create mode 100644 internal/grpcserver/grpcserver_test.go diff --git a/.junie/memory/feedback.md b/.junie/memory/feedback.md index e69de29..b4cd1ed 100644 --- a/.junie/memory/feedback.md +++ b/.junie/memory/feedback.md @@ -0,0 +1,16 @@ +[2026-03-15 11:53] - Updated by Junie +{ + "TYPE": "correction", + "CATEGORY": "gRPC config", + "EXPECTATION": "Use only the v2 gRPC server configuration and remove v1 config paths/fields.", + "NEW INSTRUCTION": "WHEN editing gRPC server configuration THEN remove v1 config and use only v2 fields" +} + +[2026-03-15 13:02] - Updated by Junie +{ + "TYPE": "correction", + "CATEGORY": "gRPC config", + "EXPECTATION": "Use only the v2 gRPC server configuration and remove v1 config paths/fields.", + "NEW INSTRUCTION": "WHEN editing gRPC server configuration THEN remove v1 config and use only v2 fields" +} + diff --git a/.junie/memory/language.json b/.junie/memory/language.json index 0f62097..54b056a 100644 --- a/.junie/memory/language.json +++ b/.junie/memory/language.json @@ -1 +1 @@ -[{"lang":"en","usageCount":20}] \ No newline at end of file +[{"lang":"en","usageCount":32}] \ No newline at end of file diff --git a/gen/metacrypt/v2/acme.pb.go b/gen/metacrypt/v2/acme.pb.go new file mode 100644 index 0000000..dfe86a3 --- /dev/null +++ b/gen/metacrypt/v2/acme.pb.go @@ -0,0 +1,666 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v3.20.3 +// source: proto/metacrypt/v2/acme.proto + +package metacryptv2 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + 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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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 SetConfigRequest 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 *SetConfigRequest) Reset() { + *x = SetConfigRequest{} + mi := &file_proto_metacrypt_v2_acme_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SetConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetConfigRequest) ProtoMessage() {} + +func (x *SetConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_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 SetConfigRequest.ProtoReflect.Descriptor instead. +func (*SetConfigRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_acme_proto_rawDescGZIP(), []int{2} +} + +func (x *SetConfigRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +func (x *SetConfigRequest) GetDefaultIssuer() string { + if x != nil { + return x.DefaultIssuer + } + return "" +} + +type SetConfigResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SetConfigResponse) Reset() { + *x = SetConfigResponse{} + mi := &file_proto_metacrypt_v2_acme_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SetConfigResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetConfigResponse) ProtoMessage() {} + +func (x *SetConfigResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_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 SetConfigResponse.ProtoReflect.Descriptor instead. +func (*SetConfigResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_acme_proto_rawDescGZIP(), []int{3} +} + +type ListAccountsRequest 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 *ListAccountsRequest) Reset() { + *x = ListAccountsRequest{} + mi := &file_proto_metacrypt_v2_acme_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListAccountsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAccountsRequest) ProtoMessage() {} + +func (x *ListAccountsRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_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 ListAccountsRequest.ProtoReflect.Descriptor instead. +func (*ListAccountsRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_acme_proto_rawDescGZIP(), []int{4} +} + +func (x *ListAccountsRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +type ListAccountsResponse 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 *ListAccountsResponse) Reset() { + *x = ListAccountsResponse{} + mi := &file_proto_metacrypt_v2_acme_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListAccountsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAccountsResponse) ProtoMessage() {} + +func (x *ListAccountsResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_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 ListAccountsResponse.ProtoReflect.Descriptor instead. +func (*ListAccountsResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_acme_proto_rawDescGZIP(), []int{5} +} + +func (x *ListAccountsResponse) 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 *timestamppb.Timestamp `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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +type ListOrdersRequest 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 *ListOrdersRequest) Reset() { + *x = ListOrdersRequest{} + mi := &file_proto_metacrypt_v2_acme_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListOrdersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOrdersRequest) ProtoMessage() {} + +func (x *ListOrdersRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_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 ListOrdersRequest.ProtoReflect.Descriptor instead. +func (*ListOrdersRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_acme_proto_rawDescGZIP(), []int{7} +} + +func (x *ListOrdersRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +type ListOrdersResponse 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 *ListOrdersResponse) Reset() { + *x = ListOrdersResponse{} + mi := &file_proto_metacrypt_v2_acme_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListOrdersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOrdersResponse) ProtoMessage() {} + +func (x *ListOrdersResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_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 ListOrdersResponse.ProtoReflect.Descriptor instead. +func (*ListOrdersResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_acme_proto_rawDescGZIP(), []int{8} +} + +func (x *ListOrdersResponse) 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 *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + ExpiresAt *timestamppb.Timestamp `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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *ACMEOrder) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +var File_proto_metacrypt_v2_acme_proto protoreflect.FileDescriptor + +const file_proto_metacrypt_v2_acme_proto_rawDesc = "" + + "\n" + + "\x1dproto/metacrypt/v2/acme.proto\x12\fmetacrypt.v2\x1a\x1fgoogle/protobuf/timestamp.proto\"(\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\"O\n" + + "\x10SetConfigRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\x12%\n" + + "\x0edefault_issuer\x18\x02 \x01(\tR\rdefaultIssuer\"\x13\n" + + "\x11SetConfigResponse\"+\n" + + "\x13ListAccountsRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\"M\n" + + "\x14ListAccountsResponse\x125\n" + + "\baccounts\x18\x01 \x03(\v2\x19.metacrypt.v2.ACMEAccountR\baccounts\"\xb1\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\x129\n" + + "\n" + + "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\")\n" + + "\x11ListOrdersRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\"E\n" + + "\x12ListOrdersResponse\x12/\n" + + "\x06orders\x18\x01 \x03(\v2\x17.metacrypt.v2.ACMEOrderR\x06orders\"\xea\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\x129\n" + + "\n" + + "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "expires_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt2\xd1\x02\n" + + "\vACMEService\x12L\n" + + "\tCreateEAB\x12\x1e.metacrypt.v2.CreateEABRequest\x1a\x1f.metacrypt.v2.CreateEABResponse\x12L\n" + + "\tSetConfig\x12\x1e.metacrypt.v2.SetConfigRequest\x1a\x1f.metacrypt.v2.SetConfigResponse\x12U\n" + + "\fListAccounts\x12!.metacrypt.v2.ListAccountsRequest\x1a\".metacrypt.v2.ListAccountsResponse\x12O\n" + + "\n" + + "ListOrders\x12\x1f.metacrypt.v2.ListOrdersRequest\x1a .metacrypt.v2.ListOrdersResponseB>Z metacrypt.v2.ACMEAccount + 10, // 1: metacrypt.v2.ACMEAccount.created_at:type_name -> google.protobuf.Timestamp + 9, // 2: metacrypt.v2.ListOrdersResponse.orders:type_name -> metacrypt.v2.ACMEOrder + 10, // 3: metacrypt.v2.ACMEOrder.created_at:type_name -> google.protobuf.Timestamp + 10, // 4: metacrypt.v2.ACMEOrder.expires_at:type_name -> google.protobuf.Timestamp + 0, // 5: metacrypt.v2.ACMEService.CreateEAB:input_type -> metacrypt.v2.CreateEABRequest + 2, // 6: metacrypt.v2.ACMEService.SetConfig:input_type -> metacrypt.v2.SetConfigRequest + 4, // 7: metacrypt.v2.ACMEService.ListAccounts:input_type -> metacrypt.v2.ListAccountsRequest + 7, // 8: metacrypt.v2.ACMEService.ListOrders:input_type -> metacrypt.v2.ListOrdersRequest + 1, // 9: metacrypt.v2.ACMEService.CreateEAB:output_type -> metacrypt.v2.CreateEABResponse + 3, // 10: metacrypt.v2.ACMEService.SetConfig:output_type -> metacrypt.v2.SetConfigResponse + 5, // 11: metacrypt.v2.ACMEService.ListAccounts:output_type -> metacrypt.v2.ListAccountsResponse + 8, // 12: metacrypt.v2.ACMEService.ListOrders:output_type -> metacrypt.v2.ListOrdersResponse + 9, // [9:13] is the sub-list for method output_type + 5, // [5:9] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_proto_metacrypt_v2_acme_proto_init() } +func file_proto_metacrypt_v2_acme_proto_init() { + if File_proto_metacrypt_v2_acme_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_metacrypt_v2_acme_proto_rawDesc), len(file_proto_metacrypt_v2_acme_proto_rawDesc)), + NumEnums: 0, + NumMessages: 10, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_metacrypt_v2_acme_proto_goTypes, + DependencyIndexes: file_proto_metacrypt_v2_acme_proto_depIdxs, + MessageInfos: file_proto_metacrypt_v2_acme_proto_msgTypes, + }.Build() + File_proto_metacrypt_v2_acme_proto = out.File + file_proto_metacrypt_v2_acme_proto_goTypes = nil + file_proto_metacrypt_v2_acme_proto_depIdxs = nil +} diff --git a/gen/metacrypt/v2/acme_grpc.pb.go b/gen/metacrypt/v2/acme_grpc.pb.go new file mode 100644 index 0000000..b689236 --- /dev/null +++ b/gen/metacrypt/v2/acme_grpc.pb.go @@ -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: proto/metacrypt/v2/acme.proto + +package metacryptv2 + +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.v2.ACMEService/CreateEAB" + ACMEService_SetConfig_FullMethodName = "/metacrypt.v2.ACMEService/SetConfig" + ACMEService_ListAccounts_FullMethodName = "/metacrypt.v2.ACMEService/ListAccounts" + ACMEService_ListOrders_FullMethodName = "/metacrypt.v2.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 /v2/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 *SetConfigRequest, opts ...grpc.CallOption) (*SetConfigResponse, error) + // ListAccounts returns all ACME accounts for a CA mount. Admin only. + ListAccounts(ctx context.Context, in *ListAccountsRequest, opts ...grpc.CallOption) (*ListAccountsResponse, error) + // ListOrders returns all ACME orders for a CA mount. Admin only. + ListOrders(ctx context.Context, in *ListOrdersRequest, opts ...grpc.CallOption) (*ListOrdersResponse, 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 *SetConfigRequest, opts ...grpc.CallOption) (*SetConfigResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SetConfigResponse) + 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 *ListAccountsRequest, opts ...grpc.CallOption) (*ListAccountsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListAccountsResponse) + 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 *ListOrdersRequest, opts ...grpc.CallOption) (*ListOrdersResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListOrdersResponse) + 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 /v2/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, *SetConfigRequest) (*SetConfigResponse, error) + // ListAccounts returns all ACME accounts for a CA mount. Admin only. + ListAccounts(context.Context, *ListAccountsRequest) (*ListAccountsResponse, error) + // ListOrders returns all ACME orders for a CA mount. Admin only. + ListOrders(context.Context, *ListOrdersRequest) (*ListOrdersResponse, 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, *SetConfigRequest) (*SetConfigResponse, error) { + return nil, status.Error(codes.Unimplemented, "method SetConfig not implemented") +} +func (UnimplementedACMEServiceServer) ListAccounts(context.Context, *ListAccountsRequest) (*ListAccountsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListAccounts not implemented") +} +func (UnimplementedACMEServiceServer) ListOrders(context.Context, *ListOrdersRequest) (*ListOrdersResponse, 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(SetConfigRequest) + 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.(*SetConfigRequest)) + } + 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(ListAccountsRequest) + 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.(*ListAccountsRequest)) + } + 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(ListOrdersRequest) + 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.(*ListOrdersRequest)) + } + 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.v2.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: "proto/metacrypt/v2/acme.proto", +} diff --git a/gen/metacrypt/v2/auth.pb.go b/gen/metacrypt/v2/auth.pb.go new file mode 100644 index 0000000..25fc674 --- /dev/null +++ b/gen/metacrypt/v2/auth.pb.go @@ -0,0 +1,389 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v3.20.3 +// source: proto/metacrypt/v2/auth.proto + +package metacryptv2 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + 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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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 *timestamppb.Timestamp `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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_auth_proto_rawDescGZIP(), []int{1} +} + +func (x *LoginResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *LoginResponse) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +type LogoutRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LogoutRequest) Reset() { + *x = LogoutRequest{} + mi := &file_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_auth_proto protoreflect.FileDescriptor + +const file_proto_metacrypt_v2_auth_proto_rawDesc = "" + + "\n" + + "\x1dproto/metacrypt/v2/auth.proto\x12\fmetacrypt.v2\x1a\x1fgoogle/protobuf/timestamp.proto\"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\"`\n" + + "\rLoginResponse\x12\x14\n" + + "\x05token\x18\x01 \x01(\tR\x05token\x129\n" + + "\n" + + "expires_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\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.v2.LoginRequest\x1a\x1b.metacrypt.v2.LoginResponse\x12C\n" + + "\x06Logout\x12\x1b.metacrypt.v2.LogoutRequest\x1a\x1c.metacrypt.v2.LogoutResponse\x12L\n" + + "\tTokenInfo\x12\x1e.metacrypt.v2.TokenInfoRequest\x1a\x1f.metacrypt.v2.TokenInfoResponseB>Z google.protobuf.Timestamp + 0, // 1: metacrypt.v2.AuthService.Login:input_type -> metacrypt.v2.LoginRequest + 2, // 2: metacrypt.v2.AuthService.Logout:input_type -> metacrypt.v2.LogoutRequest + 4, // 3: metacrypt.v2.AuthService.TokenInfo:input_type -> metacrypt.v2.TokenInfoRequest + 1, // 4: metacrypt.v2.AuthService.Login:output_type -> metacrypt.v2.LoginResponse + 3, // 5: metacrypt.v2.AuthService.Logout:output_type -> metacrypt.v2.LogoutResponse + 5, // 6: metacrypt.v2.AuthService.TokenInfo:output_type -> metacrypt.v2.TokenInfoResponse + 4, // [4:7] is the sub-list for method output_type + 1, // [1:4] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_proto_metacrypt_v2_auth_proto_init() } +func file_proto_metacrypt_v2_auth_proto_init() { + if File_proto_metacrypt_v2_auth_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_metacrypt_v2_auth_proto_rawDesc), len(file_proto_metacrypt_v2_auth_proto_rawDesc)), + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_metacrypt_v2_auth_proto_goTypes, + DependencyIndexes: file_proto_metacrypt_v2_auth_proto_depIdxs, + MessageInfos: file_proto_metacrypt_v2_auth_proto_msgTypes, + }.Build() + File_proto_metacrypt_v2_auth_proto = out.File + file_proto_metacrypt_v2_auth_proto_goTypes = nil + file_proto_metacrypt_v2_auth_proto_depIdxs = nil +} diff --git a/gen/metacrypt/v2/auth_grpc.pb.go b/gen/metacrypt/v2/auth_grpc.pb.go new file mode 100644 index 0000000..74c9baf --- /dev/null +++ b/gen/metacrypt/v2/auth_grpc.pb.go @@ -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: proto/metacrypt/v2/auth.proto + +package metacryptv2 + +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.v2.AuthService/Login" + AuthService_Logout_FullMethodName = "/metacrypt.v2.AuthService/Logout" + AuthService_TokenInfo_FullMethodName = "/metacrypt.v2.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.v2.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: "proto/metacrypt/v2/auth.proto", +} diff --git a/gen/metacrypt/v2/ca.pb.go b/gen/metacrypt/v2/ca.pb.go new file mode 100644 index 0000000..00545ca --- /dev/null +++ b/gen/metacrypt/v2/ca.pb.go @@ -0,0 +1,1748 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v3.20.3 +// source: proto/metacrypt/v2/ca.proto + +package metacryptv2 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + 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 ImportRootRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + // cert_pem is the PEM-encoded root CA certificate. + CertPem []byte `protobuf:"bytes,2,opt,name=cert_pem,json=certPem,proto3" json:"cert_pem,omitempty"` + // key_pem is the PEM-encoded private key for the root CA. + KeyPem []byte `protobuf:"bytes,3,opt,name=key_pem,json=keyPem,proto3" json:"key_pem,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ImportRootRequest) Reset() { + *x = ImportRootRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ImportRootRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportRootRequest) ProtoMessage() {} + +func (x *ImportRootRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_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 ImportRootRequest.ProtoReflect.Descriptor instead. +func (*ImportRootRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{0} +} + +func (x *ImportRootRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +func (x *ImportRootRequest) GetCertPem() []byte { + if x != nil { + return x.CertPem + } + return nil +} + +func (x *ImportRootRequest) GetKeyPem() []byte { + if x != nil { + return x.KeyPem + } + return nil +} + +type ImportRootResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + CommonName string `protobuf:"bytes,1,opt,name=common_name,json=commonName,proto3" json:"common_name,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ImportRootResponse) Reset() { + *x = ImportRootResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ImportRootResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportRootResponse) ProtoMessage() {} + +func (x *ImportRootResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_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 ImportRootResponse.ProtoReflect.Descriptor instead. +func (*ImportRootResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{1} +} + +func (x *ImportRootResponse) GetCommonName() string { + if x != nil { + return x.CommonName + } + return "" +} + +func (x *ImportRootResponse) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +type GetRootRequest 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 *GetRootRequest) Reset() { + *x = GetRootRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetRootRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRootRequest) ProtoMessage() {} + +func (x *GetRootRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_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 GetRootRequest.ProtoReflect.Descriptor instead. +func (*GetRootRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{2} +} + +func (x *GetRootRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +type GetRootResponse 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 *GetRootResponse) Reset() { + *x = GetRootResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetRootResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRootResponse) ProtoMessage() {} + +func (x *GetRootResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_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 GetRootResponse.ProtoReflect.Descriptor instead. +func (*GetRootResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{3} +} + +func (x *GetRootResponse) GetCertPem() []byte { + if x != nil { + return x.CertPem + } + return nil +} + +type CreateIssuerRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + // name is the unique identifier for this issuer within the mount. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // key_algorithm overrides the mount-level default (e.g. "ecdsa", "rsa"). + KeyAlgorithm string `protobuf:"bytes,3,opt,name=key_algorithm,json=keyAlgorithm,proto3" json:"key_algorithm,omitempty"` + // key_size overrides the mount-level default (e.g. 256, 2048). + KeySize int32 `protobuf:"varint,4,opt,name=key_size,json=keySize,proto3" json:"key_size,omitempty"` + // expiry is the lifetime of the issuer certificate (e.g. "26280h"). + // Defaults to 3 years if empty. + Expiry string `protobuf:"bytes,5,opt,name=expiry,proto3" json:"expiry,omitempty"` + // max_ttl is the maximum TTL for leaf certificates issued by this issuer + // (e.g. "2160h"). Defaults to 90 days if empty. + MaxTtl string `protobuf:"bytes,6,opt,name=max_ttl,json=maxTtl,proto3" json:"max_ttl,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateIssuerRequest) Reset() { + *x = CreateIssuerRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateIssuerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateIssuerRequest) ProtoMessage() {} + +func (x *CreateIssuerRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_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 CreateIssuerRequest.ProtoReflect.Descriptor instead. +func (*CreateIssuerRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{4} +} + +func (x *CreateIssuerRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +func (x *CreateIssuerRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateIssuerRequest) GetKeyAlgorithm() string { + if x != nil { + return x.KeyAlgorithm + } + return "" +} + +func (x *CreateIssuerRequest) GetKeySize() int32 { + if x != nil { + return x.KeySize + } + return 0 +} + +func (x *CreateIssuerRequest) GetExpiry() string { + if x != nil { + return x.Expiry + } + return "" +} + +func (x *CreateIssuerRequest) GetMaxTtl() string { + if x != nil { + return x.MaxTtl + } + return "" +} + +type CreateIssuerResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // cert_pem is the PEM-encoded issuer certificate. + CertPem []byte `protobuf:"bytes,2,opt,name=cert_pem,json=certPem,proto3" json:"cert_pem,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateIssuerResponse) Reset() { + *x = CreateIssuerResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateIssuerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateIssuerResponse) ProtoMessage() {} + +func (x *CreateIssuerResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_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 CreateIssuerResponse.ProtoReflect.Descriptor instead. +func (*CreateIssuerResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{5} +} + +func (x *CreateIssuerResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateIssuerResponse) GetCertPem() []byte { + if x != nil { + return x.CertPem + } + return nil +} + +type DeleteIssuerRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteIssuerRequest) Reset() { + *x = DeleteIssuerRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteIssuerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteIssuerRequest) ProtoMessage() {} + +func (x *DeleteIssuerRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_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 DeleteIssuerRequest.ProtoReflect.Descriptor instead. +func (*DeleteIssuerRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{6} +} + +func (x *DeleteIssuerRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +func (x *DeleteIssuerRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type DeleteIssuerResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteIssuerResponse) Reset() { + *x = DeleteIssuerResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteIssuerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteIssuerResponse) ProtoMessage() {} + +func (x *DeleteIssuerResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_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 DeleteIssuerResponse.ProtoReflect.Descriptor instead. +func (*DeleteIssuerResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{7} +} + +type ListIssuersRequest 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 *ListIssuersRequest) Reset() { + *x = ListIssuersRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListIssuersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListIssuersRequest) ProtoMessage() {} + +func (x *ListIssuersRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_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 ListIssuersRequest.ProtoReflect.Descriptor instead. +func (*ListIssuersRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{8} +} + +func (x *ListIssuersRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +type ListIssuersResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Issuers []string `protobuf:"bytes,1,rep,name=issuers,proto3" json:"issuers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListIssuersResponse) Reset() { + *x = ListIssuersResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListIssuersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListIssuersResponse) ProtoMessage() {} + +func (x *ListIssuersResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_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 ListIssuersResponse.ProtoReflect.Descriptor instead. +func (*ListIssuersResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{9} +} + +func (x *ListIssuersResponse) GetIssuers() []string { + if x != nil { + return x.Issuers + } + return nil +} + +type GetIssuerRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetIssuerRequest) Reset() { + *x = GetIssuerRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetIssuerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetIssuerRequest) ProtoMessage() {} + +func (x *GetIssuerRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetIssuerRequest.ProtoReflect.Descriptor instead. +func (*GetIssuerRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{10} +} + +func (x *GetIssuerRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +func (x *GetIssuerRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type GetIssuerResponse 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 *GetIssuerResponse) Reset() { + *x = GetIssuerResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetIssuerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetIssuerResponse) ProtoMessage() {} + +func (x *GetIssuerResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetIssuerResponse.ProtoReflect.Descriptor instead. +func (*GetIssuerResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{11} +} + +func (x *GetIssuerResponse) GetCertPem() []byte { + if x != nil { + return x.CertPem + } + return nil +} + +type CAServiceGetChainRequest 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 *CAServiceGetChainRequest) Reset() { + *x = CAServiceGetChainRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CAServiceGetChainRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CAServiceGetChainRequest) ProtoMessage() {} + +func (x *CAServiceGetChainRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CAServiceGetChainRequest.ProtoReflect.Descriptor instead. +func (*CAServiceGetChainRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{12} +} + +func (x *CAServiceGetChainRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +func (x *CAServiceGetChainRequest) GetIssuer() string { + if x != nil { + return x.Issuer + } + return "" +} + +type CAServiceGetChainResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // chain_pem contains the issuer certificate followed by the root certificate, + // PEM-encoded and concatenated. + ChainPem []byte `protobuf:"bytes,1,opt,name=chain_pem,json=chainPem,proto3" json:"chain_pem,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CAServiceGetChainResponse) Reset() { + *x = CAServiceGetChainResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CAServiceGetChainResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CAServiceGetChainResponse) ProtoMessage() {} + +func (x *CAServiceGetChainResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CAServiceGetChainResponse.ProtoReflect.Descriptor instead. +func (*CAServiceGetChainResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{13} +} + +func (x *CAServiceGetChainResponse) GetChainPem() []byte { + if x != nil { + return x.ChainPem + } + return nil +} + +type IssueCertRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + // issuer is the name of the issuer to sign the certificate. + Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"` + // profile selects the certificate profile (e.g. "server", "client"). + // Defaults to "server" if empty. + Profile string `protobuf:"bytes,3,opt,name=profile,proto3" json:"profile,omitempty"` + CommonName string `protobuf:"bytes,4,opt,name=common_name,json=commonName,proto3" json:"common_name,omitempty"` + DnsNames []string `protobuf:"bytes,5,rep,name=dns_names,json=dnsNames,proto3" json:"dns_names,omitempty"` + IpAddresses []string `protobuf:"bytes,6,rep,name=ip_addresses,json=ipAddresses,proto3" json:"ip_addresses,omitempty"` + // ttl overrides the profile's default validity period (e.g. "8760h"). + Ttl string `protobuf:"bytes,7,opt,name=ttl,proto3" json:"ttl,omitempty"` + // key_algorithm overrides the issuer-level default. + KeyAlgorithm string `protobuf:"bytes,8,opt,name=key_algorithm,json=keyAlgorithm,proto3" json:"key_algorithm,omitempty"` + // key_size overrides the issuer-level default. + KeySize int32 `protobuf:"varint,9,opt,name=key_size,json=keySize,proto3" json:"key_size,omitempty"` + KeyUsages []string `protobuf:"bytes,10,rep,name=key_usages,json=keyUsages,proto3" json:"key_usages,omitempty"` + ExtKeyUsages []string `protobuf:"bytes,11,rep,name=ext_key_usages,json=extKeyUsages,proto3" json:"ext_key_usages,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IssueCertRequest) Reset() { + *x = IssueCertRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IssueCertRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IssueCertRequest) ProtoMessage() {} + +func (x *IssueCertRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IssueCertRequest.ProtoReflect.Descriptor instead. +func (*IssueCertRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{14} +} + +func (x *IssueCertRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +func (x *IssueCertRequest) GetIssuer() string { + if x != nil { + return x.Issuer + } + return "" +} + +func (x *IssueCertRequest) GetProfile() string { + if x != nil { + return x.Profile + } + return "" +} + +func (x *IssueCertRequest) GetCommonName() string { + if x != nil { + return x.CommonName + } + return "" +} + +func (x *IssueCertRequest) GetDnsNames() []string { + if x != nil { + return x.DnsNames + } + return nil +} + +func (x *IssueCertRequest) GetIpAddresses() []string { + if x != nil { + return x.IpAddresses + } + return nil +} + +func (x *IssueCertRequest) GetTtl() string { + if x != nil { + return x.Ttl + } + return "" +} + +func (x *IssueCertRequest) GetKeyAlgorithm() string { + if x != nil { + return x.KeyAlgorithm + } + return "" +} + +func (x *IssueCertRequest) GetKeySize() int32 { + if x != nil { + return x.KeySize + } + return 0 +} + +func (x *IssueCertRequest) GetKeyUsages() []string { + if x != nil { + return x.KeyUsages + } + return nil +} + +func (x *IssueCertRequest) GetExtKeyUsages() []string { + if x != nil { + return x.ExtKeyUsages + } + return nil +} + +type IssueCertResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Serial string `protobuf:"bytes,1,opt,name=serial,proto3" json:"serial,omitempty"` + CommonName string `protobuf:"bytes,2,opt,name=common_name,json=commonName,proto3" json:"common_name,omitempty"` + Sans []string `protobuf:"bytes,3,rep,name=sans,proto3" json:"sans,omitempty"` + IssuedBy string `protobuf:"bytes,4,opt,name=issued_by,json=issuedBy,proto3" json:"issued_by,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + // cert_pem is the PEM-encoded leaf certificate. + CertPem []byte `protobuf:"bytes,6,opt,name=cert_pem,json=certPem,proto3" json:"cert_pem,omitempty"` + // key_pem is the PEM-encoded private key for the leaf certificate. + // This is the only time the private key is returned; it is not stored. + KeyPem []byte `protobuf:"bytes,7,opt,name=key_pem,json=keyPem,proto3" json:"key_pem,omitempty"` + // chain_pem contains the full chain: leaf + issuer + root, PEM-concatenated. + ChainPem []byte `protobuf:"bytes,8,opt,name=chain_pem,json=chainPem,proto3" json:"chain_pem,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IssueCertResponse) Reset() { + *x = IssueCertResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IssueCertResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IssueCertResponse) ProtoMessage() {} + +func (x *IssueCertResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IssueCertResponse.ProtoReflect.Descriptor instead. +func (*IssueCertResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{15} +} + +func (x *IssueCertResponse) GetSerial() string { + if x != nil { + return x.Serial + } + return "" +} + +func (x *IssueCertResponse) GetCommonName() string { + if x != nil { + return x.CommonName + } + return "" +} + +func (x *IssueCertResponse) GetSans() []string { + if x != nil { + return x.Sans + } + return nil +} + +func (x *IssueCertResponse) GetIssuedBy() string { + if x != nil { + return x.IssuedBy + } + return "" +} + +func (x *IssueCertResponse) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +func (x *IssueCertResponse) GetCertPem() []byte { + if x != nil { + return x.CertPem + } + return nil +} + +func (x *IssueCertResponse) GetKeyPem() []byte { + if x != nil { + return x.KeyPem + } + return nil +} + +func (x *IssueCertResponse) GetChainPem() []byte { + if x != nil { + return x.ChainPem + } + return nil +} + +type GetCertRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + Serial string `protobuf:"bytes,2,opt,name=serial,proto3" json:"serial,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetCertRequest) Reset() { + *x = GetCertRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetCertRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCertRequest) ProtoMessage() {} + +func (x *GetCertRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetCertRequest.ProtoReflect.Descriptor instead. +func (*GetCertRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{16} +} + +func (x *GetCertRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +func (x *GetCertRequest) GetSerial() string { + if x != nil { + return x.Serial + } + return "" +} + +type GetCertResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Cert *CertRecord `protobuf:"bytes,1,opt,name=cert,proto3" json:"cert,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetCertResponse) Reset() { + *x = GetCertResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetCertResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCertResponse) ProtoMessage() {} + +func (x *GetCertResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetCertResponse.ProtoReflect.Descriptor instead. +func (*GetCertResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{17} +} + +func (x *GetCertResponse) GetCert() *CertRecord { + if x != nil { + return x.Cert + } + return nil +} + +type ListCertsRequest 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 *ListCertsRequest) Reset() { + *x = ListCertsRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListCertsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListCertsRequest) ProtoMessage() {} + +func (x *ListCertsRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListCertsRequest.ProtoReflect.Descriptor instead. +func (*ListCertsRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{18} +} + +func (x *ListCertsRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +type ListCertsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Certs []*CertSummary `protobuf:"bytes,1,rep,name=certs,proto3" json:"certs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListCertsResponse) Reset() { + *x = ListCertsResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListCertsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListCertsResponse) ProtoMessage() {} + +func (x *ListCertsResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListCertsResponse.ProtoReflect.Descriptor instead. +func (*ListCertsResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{19} +} + +func (x *ListCertsResponse) GetCerts() []*CertSummary { + if x != nil { + return x.Certs + } + return nil +} + +type RenewCertRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Mount string `protobuf:"bytes,1,opt,name=mount,proto3" json:"mount,omitempty"` + Serial string `protobuf:"bytes,2,opt,name=serial,proto3" json:"serial,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RenewCertRequest) Reset() { + *x = RenewCertRequest{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RenewCertRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RenewCertRequest) ProtoMessage() {} + +func (x *RenewCertRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RenewCertRequest.ProtoReflect.Descriptor instead. +func (*RenewCertRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{20} +} + +func (x *RenewCertRequest) GetMount() string { + if x != nil { + return x.Mount + } + return "" +} + +func (x *RenewCertRequest) GetSerial() string { + if x != nil { + return x.Serial + } + return "" +} + +type RenewCertResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Serial string `protobuf:"bytes,1,opt,name=serial,proto3" json:"serial,omitempty"` + CommonName string `protobuf:"bytes,2,opt,name=common_name,json=commonName,proto3" json:"common_name,omitempty"` + Sans []string `protobuf:"bytes,3,rep,name=sans,proto3" json:"sans,omitempty"` + IssuedBy string `protobuf:"bytes,4,opt,name=issued_by,json=issuedBy,proto3" json:"issued_by,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + CertPem []byte `protobuf:"bytes,6,opt,name=cert_pem,json=certPem,proto3" json:"cert_pem,omitempty"` + KeyPem []byte `protobuf:"bytes,7,opt,name=key_pem,json=keyPem,proto3" json:"key_pem,omitempty"` + ChainPem []byte `protobuf:"bytes,8,opt,name=chain_pem,json=chainPem,proto3" json:"chain_pem,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RenewCertResponse) Reset() { + *x = RenewCertResponse{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RenewCertResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RenewCertResponse) ProtoMessage() {} + +func (x *RenewCertResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RenewCertResponse.ProtoReflect.Descriptor instead. +func (*RenewCertResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{21} +} + +func (x *RenewCertResponse) GetSerial() string { + if x != nil { + return x.Serial + } + return "" +} + +func (x *RenewCertResponse) GetCommonName() string { + if x != nil { + return x.CommonName + } + return "" +} + +func (x *RenewCertResponse) GetSans() []string { + if x != nil { + return x.Sans + } + return nil +} + +func (x *RenewCertResponse) GetIssuedBy() string { + if x != nil { + return x.IssuedBy + } + return "" +} + +func (x *RenewCertResponse) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +func (x *RenewCertResponse) GetCertPem() []byte { + if x != nil { + return x.CertPem + } + return nil +} + +func (x *RenewCertResponse) GetKeyPem() []byte { + if x != nil { + return x.KeyPem + } + return nil +} + +func (x *RenewCertResponse) GetChainPem() []byte { + if x != nil { + return x.ChainPem + } + return nil +} + +// CertRecord is the full certificate record including the PEM-encoded cert. +type CertRecord struct { + state protoimpl.MessageState `protogen:"open.v1"` + Serial string `protobuf:"bytes,1,opt,name=serial,proto3" json:"serial,omitempty"` + Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"` + CommonName string `protobuf:"bytes,3,opt,name=common_name,json=commonName,proto3" json:"common_name,omitempty"` + Sans []string `protobuf:"bytes,4,rep,name=sans,proto3" json:"sans,omitempty"` + Profile string `protobuf:"bytes,5,opt,name=profile,proto3" json:"profile,omitempty"` + IssuedBy string `protobuf:"bytes,6,opt,name=issued_by,json=issuedBy,proto3" json:"issued_by,omitempty"` + IssuedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=issued_at,json=issuedAt,proto3" json:"issued_at,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + // cert_pem is the PEM-encoded certificate. + CertPem []byte `protobuf:"bytes,9,opt,name=cert_pem,json=certPem,proto3" json:"cert_pem,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CertRecord) Reset() { + *x = CertRecord{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CertRecord) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CertRecord) ProtoMessage() {} + +func (x *CertRecord) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CertRecord.ProtoReflect.Descriptor instead. +func (*CertRecord) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{22} +} + +func (x *CertRecord) GetSerial() string { + if x != nil { + return x.Serial + } + return "" +} + +func (x *CertRecord) GetIssuer() string { + if x != nil { + return x.Issuer + } + return "" +} + +func (x *CertRecord) GetCommonName() string { + if x != nil { + return x.CommonName + } + return "" +} + +func (x *CertRecord) GetSans() []string { + if x != nil { + return x.Sans + } + return nil +} + +func (x *CertRecord) GetProfile() string { + if x != nil { + return x.Profile + } + return "" +} + +func (x *CertRecord) GetIssuedBy() string { + if x != nil { + return x.IssuedBy + } + return "" +} + +func (x *CertRecord) GetIssuedAt() *timestamppb.Timestamp { + if x != nil { + return x.IssuedAt + } + return nil +} + +func (x *CertRecord) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +func (x *CertRecord) GetCertPem() []byte { + if x != nil { + return x.CertPem + } + return nil +} + +// CertSummary is a lightweight certificate record without the PEM data, +// suitable for list responses. +type CertSummary struct { + state protoimpl.MessageState `protogen:"open.v1"` + Serial string `protobuf:"bytes,1,opt,name=serial,proto3" json:"serial,omitempty"` + Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"` + CommonName string `protobuf:"bytes,3,opt,name=common_name,json=commonName,proto3" json:"common_name,omitempty"` + Profile string `protobuf:"bytes,4,opt,name=profile,proto3" json:"profile,omitempty"` + IssuedBy string `protobuf:"bytes,5,opt,name=issued_by,json=issuedBy,proto3" json:"issued_by,omitempty"` + IssuedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=issued_at,json=issuedAt,proto3" json:"issued_at,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CertSummary) Reset() { + *x = CertSummary{} + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CertSummary) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CertSummary) ProtoMessage() {} + +func (x *CertSummary) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_ca_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CertSummary.ProtoReflect.Descriptor instead. +func (*CertSummary) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_ca_proto_rawDescGZIP(), []int{23} +} + +func (x *CertSummary) GetSerial() string { + if x != nil { + return x.Serial + } + return "" +} + +func (x *CertSummary) GetIssuer() string { + if x != nil { + return x.Issuer + } + return "" +} + +func (x *CertSummary) GetCommonName() string { + if x != nil { + return x.CommonName + } + return "" +} + +func (x *CertSummary) GetProfile() string { + if x != nil { + return x.Profile + } + return "" +} + +func (x *CertSummary) GetIssuedBy() string { + if x != nil { + return x.IssuedBy + } + return "" +} + +func (x *CertSummary) GetIssuedAt() *timestamppb.Timestamp { + if x != nil { + return x.IssuedAt + } + return nil +} + +func (x *CertSummary) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +var File_proto_metacrypt_v2_ca_proto protoreflect.FileDescriptor + +const file_proto_metacrypt_v2_ca_proto_rawDesc = "" + + "\n" + + "\x1bproto/metacrypt/v2/ca.proto\x12\fmetacrypt.v2\x1a\x1fgoogle/protobuf/timestamp.proto\"]\n" + + "\x11ImportRootRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\x12\x19\n" + + "\bcert_pem\x18\x02 \x01(\fR\acertPem\x12\x17\n" + + "\akey_pem\x18\x03 \x01(\fR\x06keyPem\"p\n" + + "\x12ImportRootResponse\x12\x1f\n" + + "\vcommon_name\x18\x01 \x01(\tR\n" + + "commonName\x129\n" + + "\n" + + "expires_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\"&\n" + + "\x0eGetRootRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\",\n" + + "\x0fGetRootResponse\x12\x19\n" + + "\bcert_pem\x18\x01 \x01(\fR\acertPem\"\xb0\x01\n" + + "\x13CreateIssuerRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12#\n" + + "\rkey_algorithm\x18\x03 \x01(\tR\fkeyAlgorithm\x12\x19\n" + + "\bkey_size\x18\x04 \x01(\x05R\akeySize\x12\x16\n" + + "\x06expiry\x18\x05 \x01(\tR\x06expiry\x12\x17\n" + + "\amax_ttl\x18\x06 \x01(\tR\x06maxTtl\"E\n" + + "\x14CreateIssuerResponse\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x19\n" + + "\bcert_pem\x18\x02 \x01(\fR\acertPem\"?\n" + + "\x13DeleteIssuerRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\x16\n" + + "\x14DeleteIssuerResponse\"*\n" + + "\x12ListIssuersRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\"/\n" + + "\x13ListIssuersResponse\x12\x18\n" + + "\aissuers\x18\x01 \x03(\tR\aissuers\"<\n" + + "\x10GetIssuerRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\".\n" + + "\x11GetIssuerResponse\x12\x19\n" + + "\bcert_pem\x18\x01 \x01(\fR\acertPem\"H\n" + + "\x18CAServiceGetChainRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\x12\x16\n" + + "\x06issuer\x18\x02 \x01(\tR\x06issuer\"8\n" + + "\x19CAServiceGetChainResponse\x12\x1b\n" + + "\tchain_pem\x18\x01 \x01(\fR\bchainPem\"\xd2\x02\n" + + "\x10IssueCertRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\x12\x16\n" + + "\x06issuer\x18\x02 \x01(\tR\x06issuer\x12\x18\n" + + "\aprofile\x18\x03 \x01(\tR\aprofile\x12\x1f\n" + + "\vcommon_name\x18\x04 \x01(\tR\n" + + "commonName\x12\x1b\n" + + "\tdns_names\x18\x05 \x03(\tR\bdnsNames\x12!\n" + + "\fip_addresses\x18\x06 \x03(\tR\vipAddresses\x12\x10\n" + + "\x03ttl\x18\a \x01(\tR\x03ttl\x12#\n" + + "\rkey_algorithm\x18\b \x01(\tR\fkeyAlgorithm\x12\x19\n" + + "\bkey_size\x18\t \x01(\x05R\akeySize\x12\x1d\n" + + "\n" + + "key_usages\x18\n" + + " \x03(\tR\tkeyUsages\x12$\n" + + "\x0eext_key_usages\x18\v \x03(\tR\fextKeyUsages\"\x89\x02\n" + + "\x11IssueCertResponse\x12\x16\n" + + "\x06serial\x18\x01 \x01(\tR\x06serial\x12\x1f\n" + + "\vcommon_name\x18\x02 \x01(\tR\n" + + "commonName\x12\x12\n" + + "\x04sans\x18\x03 \x03(\tR\x04sans\x12\x1b\n" + + "\tissued_by\x18\x04 \x01(\tR\bissuedBy\x129\n" + + "\n" + + "expires_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x12\x19\n" + + "\bcert_pem\x18\x06 \x01(\fR\acertPem\x12\x17\n" + + "\akey_pem\x18\a \x01(\fR\x06keyPem\x12\x1b\n" + + "\tchain_pem\x18\b \x01(\fR\bchainPem\">\n" + + "\x0eGetCertRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\x12\x16\n" + + "\x06serial\x18\x02 \x01(\tR\x06serial\"?\n" + + "\x0fGetCertResponse\x12,\n" + + "\x04cert\x18\x01 \x01(\v2\x18.metacrypt.v2.CertRecordR\x04cert\"(\n" + + "\x10ListCertsRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\"D\n" + + "\x11ListCertsResponse\x12/\n" + + "\x05certs\x18\x01 \x03(\v2\x19.metacrypt.v2.CertSummaryR\x05certs\"@\n" + + "\x10RenewCertRequest\x12\x14\n" + + "\x05mount\x18\x01 \x01(\tR\x05mount\x12\x16\n" + + "\x06serial\x18\x02 \x01(\tR\x06serial\"\x89\x02\n" + + "\x11RenewCertResponse\x12\x16\n" + + "\x06serial\x18\x01 \x01(\tR\x06serial\x12\x1f\n" + + "\vcommon_name\x18\x02 \x01(\tR\n" + + "commonName\x12\x12\n" + + "\x04sans\x18\x03 \x03(\tR\x04sans\x12\x1b\n" + + "\tissued_by\x18\x04 \x01(\tR\bissuedBy\x129\n" + + "\n" + + "expires_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x12\x19\n" + + "\bcert_pem\x18\x06 \x01(\fR\acertPem\x12\x17\n" + + "\akey_pem\x18\a \x01(\fR\x06keyPem\x12\x1b\n" + + "\tchain_pem\x18\b \x01(\fR\bchainPem\"\xb7\x02\n" + + "\n" + + "CertRecord\x12\x16\n" + + "\x06serial\x18\x01 \x01(\tR\x06serial\x12\x16\n" + + "\x06issuer\x18\x02 \x01(\tR\x06issuer\x12\x1f\n" + + "\vcommon_name\x18\x03 \x01(\tR\n" + + "commonName\x12\x12\n" + + "\x04sans\x18\x04 \x03(\tR\x04sans\x12\x18\n" + + "\aprofile\x18\x05 \x01(\tR\aprofile\x12\x1b\n" + + "\tissued_by\x18\x06 \x01(\tR\bissuedBy\x127\n" + + "\tissued_at\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\bissuedAt\x129\n" + + "\n" + + "expires_at\x18\b \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x12\x19\n" + + "\bcert_pem\x18\t \x01(\fR\acertPem\"\x89\x02\n" + + "\vCertSummary\x12\x16\n" + + "\x06serial\x18\x01 \x01(\tR\x06serial\x12\x16\n" + + "\x06issuer\x18\x02 \x01(\tR\x06issuer\x12\x1f\n" + + "\vcommon_name\x18\x03 \x01(\tR\n" + + "commonName\x12\x18\n" + + "\aprofile\x18\x04 \x01(\tR\aprofile\x12\x1b\n" + + "\tissued_by\x18\x05 \x01(\tR\bissuedBy\x127\n" + + "\tissued_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\bissuedAt\x129\n" + + "\n" + + "expires_at\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt2\x83\a\n" + + "\tCAService\x12O\n" + + "\n" + + "ImportRoot\x12\x1f.metacrypt.v2.ImportRootRequest\x1a .metacrypt.v2.ImportRootResponse\x12F\n" + + "\aGetRoot\x12\x1c.metacrypt.v2.GetRootRequest\x1a\x1d.metacrypt.v2.GetRootResponse\x12U\n" + + "\fCreateIssuer\x12!.metacrypt.v2.CreateIssuerRequest\x1a\".metacrypt.v2.CreateIssuerResponse\x12U\n" + + "\fDeleteIssuer\x12!.metacrypt.v2.DeleteIssuerRequest\x1a\".metacrypt.v2.DeleteIssuerResponse\x12R\n" + + "\vListIssuers\x12 .metacrypt.v2.ListIssuersRequest\x1a!.metacrypt.v2.ListIssuersResponse\x12L\n" + + "\tGetIssuer\x12\x1e.metacrypt.v2.GetIssuerRequest\x1a\x1f.metacrypt.v2.GetIssuerResponse\x12[\n" + + "\bGetChain\x12&.metacrypt.v2.CAServiceGetChainRequest\x1a'.metacrypt.v2.CAServiceGetChainResponse\x12L\n" + + "\tIssueCert\x12\x1e.metacrypt.v2.IssueCertRequest\x1a\x1f.metacrypt.v2.IssueCertResponse\x12F\n" + + "\aGetCert\x12\x1c.metacrypt.v2.GetCertRequest\x1a\x1d.metacrypt.v2.GetCertResponse\x12L\n" + + "\tListCerts\x12\x1e.metacrypt.v2.ListCertsRequest\x1a\x1f.metacrypt.v2.ListCertsResponse\x12L\n" + + "\tRenewCert\x12\x1e.metacrypt.v2.RenewCertRequest\x1a\x1f.metacrypt.v2.RenewCertResponseB>Z google.protobuf.Timestamp + 24, // 1: metacrypt.v2.IssueCertResponse.expires_at:type_name -> google.protobuf.Timestamp + 22, // 2: metacrypt.v2.GetCertResponse.cert:type_name -> metacrypt.v2.CertRecord + 23, // 3: metacrypt.v2.ListCertsResponse.certs:type_name -> metacrypt.v2.CertSummary + 24, // 4: metacrypt.v2.RenewCertResponse.expires_at:type_name -> google.protobuf.Timestamp + 24, // 5: metacrypt.v2.CertRecord.issued_at:type_name -> google.protobuf.Timestamp + 24, // 6: metacrypt.v2.CertRecord.expires_at:type_name -> google.protobuf.Timestamp + 24, // 7: metacrypt.v2.CertSummary.issued_at:type_name -> google.protobuf.Timestamp + 24, // 8: metacrypt.v2.CertSummary.expires_at:type_name -> google.protobuf.Timestamp + 0, // 9: metacrypt.v2.CAService.ImportRoot:input_type -> metacrypt.v2.ImportRootRequest + 2, // 10: metacrypt.v2.CAService.GetRoot:input_type -> metacrypt.v2.GetRootRequest + 4, // 11: metacrypt.v2.CAService.CreateIssuer:input_type -> metacrypt.v2.CreateIssuerRequest + 6, // 12: metacrypt.v2.CAService.DeleteIssuer:input_type -> metacrypt.v2.DeleteIssuerRequest + 8, // 13: metacrypt.v2.CAService.ListIssuers:input_type -> metacrypt.v2.ListIssuersRequest + 10, // 14: metacrypt.v2.CAService.GetIssuer:input_type -> metacrypt.v2.GetIssuerRequest + 12, // 15: metacrypt.v2.CAService.GetChain:input_type -> metacrypt.v2.CAServiceGetChainRequest + 14, // 16: metacrypt.v2.CAService.IssueCert:input_type -> metacrypt.v2.IssueCertRequest + 16, // 17: metacrypt.v2.CAService.GetCert:input_type -> metacrypt.v2.GetCertRequest + 18, // 18: metacrypt.v2.CAService.ListCerts:input_type -> metacrypt.v2.ListCertsRequest + 20, // 19: metacrypt.v2.CAService.RenewCert:input_type -> metacrypt.v2.RenewCertRequest + 1, // 20: metacrypt.v2.CAService.ImportRoot:output_type -> metacrypt.v2.ImportRootResponse + 3, // 21: metacrypt.v2.CAService.GetRoot:output_type -> metacrypt.v2.GetRootResponse + 5, // 22: metacrypt.v2.CAService.CreateIssuer:output_type -> metacrypt.v2.CreateIssuerResponse + 7, // 23: metacrypt.v2.CAService.DeleteIssuer:output_type -> metacrypt.v2.DeleteIssuerResponse + 9, // 24: metacrypt.v2.CAService.ListIssuers:output_type -> metacrypt.v2.ListIssuersResponse + 11, // 25: metacrypt.v2.CAService.GetIssuer:output_type -> metacrypt.v2.GetIssuerResponse + 13, // 26: metacrypt.v2.CAService.GetChain:output_type -> metacrypt.v2.CAServiceGetChainResponse + 15, // 27: metacrypt.v2.CAService.IssueCert:output_type -> metacrypt.v2.IssueCertResponse + 17, // 28: metacrypt.v2.CAService.GetCert:output_type -> metacrypt.v2.GetCertResponse + 19, // 29: metacrypt.v2.CAService.ListCerts:output_type -> metacrypt.v2.ListCertsResponse + 21, // 30: metacrypt.v2.CAService.RenewCert:output_type -> metacrypt.v2.RenewCertResponse + 20, // [20:31] is the sub-list for method output_type + 9, // [9:20] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_proto_metacrypt_v2_ca_proto_init() } +func file_proto_metacrypt_v2_ca_proto_init() { + if File_proto_metacrypt_v2_ca_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_metacrypt_v2_ca_proto_rawDesc), len(file_proto_metacrypt_v2_ca_proto_rawDesc)), + NumEnums: 0, + NumMessages: 24, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_metacrypt_v2_ca_proto_goTypes, + DependencyIndexes: file_proto_metacrypt_v2_ca_proto_depIdxs, + MessageInfos: file_proto_metacrypt_v2_ca_proto_msgTypes, + }.Build() + File_proto_metacrypt_v2_ca_proto = out.File + file_proto_metacrypt_v2_ca_proto_goTypes = nil + file_proto_metacrypt_v2_ca_proto_depIdxs = nil +} diff --git a/gen/metacrypt/v2/ca_grpc.pb.go b/gen/metacrypt/v2/ca_grpc.pb.go new file mode 100644 index 0000000..8b57f52 --- /dev/null +++ b/gen/metacrypt/v2/ca_grpc.pb.go @@ -0,0 +1,541 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.1 +// - protoc v3.20.3 +// source: proto/metacrypt/v2/ca.proto + +package metacryptv2 + +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 ( + CAService_ImportRoot_FullMethodName = "/metacrypt.v2.CAService/ImportRoot" + CAService_GetRoot_FullMethodName = "/metacrypt.v2.CAService/GetRoot" + CAService_CreateIssuer_FullMethodName = "/metacrypt.v2.CAService/CreateIssuer" + CAService_DeleteIssuer_FullMethodName = "/metacrypt.v2.CAService/DeleteIssuer" + CAService_ListIssuers_FullMethodName = "/metacrypt.v2.CAService/ListIssuers" + CAService_GetIssuer_FullMethodName = "/metacrypt.v2.CAService/GetIssuer" + CAService_GetChain_FullMethodName = "/metacrypt.v2.CAService/GetChain" + CAService_IssueCert_FullMethodName = "/metacrypt.v2.CAService/IssueCert" + CAService_GetCert_FullMethodName = "/metacrypt.v2.CAService/GetCert" + CAService_ListCerts_FullMethodName = "/metacrypt.v2.CAService/ListCerts" + CAService_RenewCert_FullMethodName = "/metacrypt.v2.CAService/RenewCert" +) + +// CAServiceClient is the client API for CAService 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. +// +// CAService provides typed, authenticated access to CA engine operations. +// All RPCs require the service to be unsealed. Write operations (CreateIssuer, +// DeleteIssuer, ImportRoot, IssueCert, RenewCert) require authentication. +// Admin-only operations (CreateIssuer, DeleteIssuer, ImportRoot) additionally +// require the caller to have admin privileges. +type CAServiceClient interface { + // ImportRoot imports an existing root CA certificate and private key. + // Admin only. Only allowed when no valid root exists. + ImportRoot(ctx context.Context, in *ImportRootRequest, opts ...grpc.CallOption) (*ImportRootResponse, error) + // GetRoot returns the root CA certificate for a mount. + GetRoot(ctx context.Context, in *GetRootRequest, opts ...grpc.CallOption) (*GetRootResponse, error) + // CreateIssuer creates a new intermediate CA issuer signed by the root. + // Admin only. + CreateIssuer(ctx context.Context, in *CreateIssuerRequest, opts ...grpc.CallOption) (*CreateIssuerResponse, error) + // DeleteIssuer removes an issuer and its key material. Admin only. + DeleteIssuer(ctx context.Context, in *DeleteIssuerRequest, opts ...grpc.CallOption) (*DeleteIssuerResponse, error) + // ListIssuers returns the names of all configured issuers. Auth required. + ListIssuers(ctx context.Context, in *ListIssuersRequest, opts ...grpc.CallOption) (*ListIssuersResponse, error) + // GetIssuer returns the PEM-encoded certificate for a named issuer. + GetIssuer(ctx context.Context, in *GetIssuerRequest, opts ...grpc.CallOption) (*GetIssuerResponse, error) + // GetChain returns the full PEM certificate chain for a named issuer. + GetChain(ctx context.Context, in *CAServiceGetChainRequest, opts ...grpc.CallOption) (*CAServiceGetChainResponse, error) + // IssueCert issues a new leaf certificate from a named issuer. Auth required. + IssueCert(ctx context.Context, in *IssueCertRequest, opts ...grpc.CallOption) (*IssueCertResponse, error) + // GetCert retrieves a certificate record by serial number. Auth required. + GetCert(ctx context.Context, in *GetCertRequest, opts ...grpc.CallOption) (*GetCertResponse, error) + // ListCerts lists all certificate records for a mount. Auth required. + ListCerts(ctx context.Context, in *ListCertsRequest, opts ...grpc.CallOption) (*ListCertsResponse, error) + // RenewCert renews an existing certificate, generating a new key and serial. + // Auth required. + RenewCert(ctx context.Context, in *RenewCertRequest, opts ...grpc.CallOption) (*RenewCertResponse, error) +} + +type cAServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewCAServiceClient(cc grpc.ClientConnInterface) CAServiceClient { + return &cAServiceClient{cc} +} + +func (c *cAServiceClient) ImportRoot(ctx context.Context, in *ImportRootRequest, opts ...grpc.CallOption) (*ImportRootResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ImportRootResponse) + err := c.cc.Invoke(ctx, CAService_ImportRoot_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cAServiceClient) GetRoot(ctx context.Context, in *GetRootRequest, opts ...grpc.CallOption) (*GetRootResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetRootResponse) + err := c.cc.Invoke(ctx, CAService_GetRoot_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cAServiceClient) CreateIssuer(ctx context.Context, in *CreateIssuerRequest, opts ...grpc.CallOption) (*CreateIssuerResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateIssuerResponse) + err := c.cc.Invoke(ctx, CAService_CreateIssuer_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cAServiceClient) DeleteIssuer(ctx context.Context, in *DeleteIssuerRequest, opts ...grpc.CallOption) (*DeleteIssuerResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DeleteIssuerResponse) + err := c.cc.Invoke(ctx, CAService_DeleteIssuer_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cAServiceClient) ListIssuers(ctx context.Context, in *ListIssuersRequest, opts ...grpc.CallOption) (*ListIssuersResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListIssuersResponse) + err := c.cc.Invoke(ctx, CAService_ListIssuers_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cAServiceClient) GetIssuer(ctx context.Context, in *GetIssuerRequest, opts ...grpc.CallOption) (*GetIssuerResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetIssuerResponse) + err := c.cc.Invoke(ctx, CAService_GetIssuer_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cAServiceClient) GetChain(ctx context.Context, in *CAServiceGetChainRequest, opts ...grpc.CallOption) (*CAServiceGetChainResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CAServiceGetChainResponse) + err := c.cc.Invoke(ctx, CAService_GetChain_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cAServiceClient) IssueCert(ctx context.Context, in *IssueCertRequest, opts ...grpc.CallOption) (*IssueCertResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(IssueCertResponse) + err := c.cc.Invoke(ctx, CAService_IssueCert_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cAServiceClient) GetCert(ctx context.Context, in *GetCertRequest, opts ...grpc.CallOption) (*GetCertResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetCertResponse) + err := c.cc.Invoke(ctx, CAService_GetCert_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cAServiceClient) ListCerts(ctx context.Context, in *ListCertsRequest, opts ...grpc.CallOption) (*ListCertsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListCertsResponse) + err := c.cc.Invoke(ctx, CAService_ListCerts_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cAServiceClient) RenewCert(ctx context.Context, in *RenewCertRequest, opts ...grpc.CallOption) (*RenewCertResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RenewCertResponse) + err := c.cc.Invoke(ctx, CAService_RenewCert_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CAServiceServer is the server API for CAService service. +// All implementations must embed UnimplementedCAServiceServer +// for forward compatibility. +// +// CAService provides typed, authenticated access to CA engine operations. +// All RPCs require the service to be unsealed. Write operations (CreateIssuer, +// DeleteIssuer, ImportRoot, IssueCert, RenewCert) require authentication. +// Admin-only operations (CreateIssuer, DeleteIssuer, ImportRoot) additionally +// require the caller to have admin privileges. +type CAServiceServer interface { + // ImportRoot imports an existing root CA certificate and private key. + // Admin only. Only allowed when no valid root exists. + ImportRoot(context.Context, *ImportRootRequest) (*ImportRootResponse, error) + // GetRoot returns the root CA certificate for a mount. + GetRoot(context.Context, *GetRootRequest) (*GetRootResponse, error) + // CreateIssuer creates a new intermediate CA issuer signed by the root. + // Admin only. + CreateIssuer(context.Context, *CreateIssuerRequest) (*CreateIssuerResponse, error) + // DeleteIssuer removes an issuer and its key material. Admin only. + DeleteIssuer(context.Context, *DeleteIssuerRequest) (*DeleteIssuerResponse, error) + // ListIssuers returns the names of all configured issuers. Auth required. + ListIssuers(context.Context, *ListIssuersRequest) (*ListIssuersResponse, error) + // GetIssuer returns the PEM-encoded certificate for a named issuer. + GetIssuer(context.Context, *GetIssuerRequest) (*GetIssuerResponse, error) + // GetChain returns the full PEM certificate chain for a named issuer. + GetChain(context.Context, *CAServiceGetChainRequest) (*CAServiceGetChainResponse, error) + // IssueCert issues a new leaf certificate from a named issuer. Auth required. + IssueCert(context.Context, *IssueCertRequest) (*IssueCertResponse, error) + // GetCert retrieves a certificate record by serial number. Auth required. + GetCert(context.Context, *GetCertRequest) (*GetCertResponse, error) + // ListCerts lists all certificate records for a mount. Auth required. + ListCerts(context.Context, *ListCertsRequest) (*ListCertsResponse, error) + // RenewCert renews an existing certificate, generating a new key and serial. + // Auth required. + RenewCert(context.Context, *RenewCertRequest) (*RenewCertResponse, error) + mustEmbedUnimplementedCAServiceServer() +} + +// UnimplementedCAServiceServer 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 UnimplementedCAServiceServer struct{} + +func (UnimplementedCAServiceServer) ImportRoot(context.Context, *ImportRootRequest) (*ImportRootResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ImportRoot not implemented") +} +func (UnimplementedCAServiceServer) GetRoot(context.Context, *GetRootRequest) (*GetRootResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetRoot not implemented") +} +func (UnimplementedCAServiceServer) CreateIssuer(context.Context, *CreateIssuerRequest) (*CreateIssuerResponse, error) { + return nil, status.Error(codes.Unimplemented, "method CreateIssuer not implemented") +} +func (UnimplementedCAServiceServer) DeleteIssuer(context.Context, *DeleteIssuerRequest) (*DeleteIssuerResponse, error) { + return nil, status.Error(codes.Unimplemented, "method DeleteIssuer not implemented") +} +func (UnimplementedCAServiceServer) ListIssuers(context.Context, *ListIssuersRequest) (*ListIssuersResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListIssuers not implemented") +} +func (UnimplementedCAServiceServer) GetIssuer(context.Context, *GetIssuerRequest) (*GetIssuerResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetIssuer not implemented") +} +func (UnimplementedCAServiceServer) GetChain(context.Context, *CAServiceGetChainRequest) (*CAServiceGetChainResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetChain not implemented") +} +func (UnimplementedCAServiceServer) IssueCert(context.Context, *IssueCertRequest) (*IssueCertResponse, error) { + return nil, status.Error(codes.Unimplemented, "method IssueCert not implemented") +} +func (UnimplementedCAServiceServer) GetCert(context.Context, *GetCertRequest) (*GetCertResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetCert not implemented") +} +func (UnimplementedCAServiceServer) ListCerts(context.Context, *ListCertsRequest) (*ListCertsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListCerts not implemented") +} +func (UnimplementedCAServiceServer) RenewCert(context.Context, *RenewCertRequest) (*RenewCertResponse, error) { + return nil, status.Error(codes.Unimplemented, "method RenewCert not implemented") +} +func (UnimplementedCAServiceServer) mustEmbedUnimplementedCAServiceServer() {} +func (UnimplementedCAServiceServer) testEmbeddedByValue() {} + +// UnsafeCAServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to CAServiceServer will +// result in compilation errors. +type UnsafeCAServiceServer interface { + mustEmbedUnimplementedCAServiceServer() +} + +func RegisterCAServiceServer(s grpc.ServiceRegistrar, srv CAServiceServer) { + // If the following call panics, it indicates UnimplementedCAServiceServer 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(&CAService_ServiceDesc, srv) +} + +func _CAService_ImportRoot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImportRootRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).ImportRoot(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_ImportRoot_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).ImportRoot(ctx, req.(*ImportRootRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CAService_GetRoot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetRootRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).GetRoot(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_GetRoot_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).GetRoot(ctx, req.(*GetRootRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CAService_CreateIssuer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateIssuerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).CreateIssuer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_CreateIssuer_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).CreateIssuer(ctx, req.(*CreateIssuerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CAService_DeleteIssuer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteIssuerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).DeleteIssuer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_DeleteIssuer_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).DeleteIssuer(ctx, req.(*DeleteIssuerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CAService_ListIssuers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListIssuersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).ListIssuers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_ListIssuers_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).ListIssuers(ctx, req.(*ListIssuersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CAService_GetIssuer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetIssuerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).GetIssuer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_GetIssuer_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).GetIssuer(ctx, req.(*GetIssuerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CAService_GetChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CAServiceGetChainRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).GetChain(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_GetChain_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).GetChain(ctx, req.(*CAServiceGetChainRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CAService_IssueCert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(IssueCertRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).IssueCert(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_IssueCert_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).IssueCert(ctx, req.(*IssueCertRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CAService_GetCert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetCertRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).GetCert(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_GetCert_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).GetCert(ctx, req.(*GetCertRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CAService_ListCerts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListCertsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).ListCerts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_ListCerts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).ListCerts(ctx, req.(*ListCertsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _CAService_RenewCert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RenewCertRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CAServiceServer).RenewCert(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CAService_RenewCert_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CAServiceServer).RenewCert(ctx, req.(*RenewCertRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// CAService_ServiceDesc is the grpc.ServiceDesc for CAService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var CAService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "metacrypt.v2.CAService", + HandlerType: (*CAServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ImportRoot", + Handler: _CAService_ImportRoot_Handler, + }, + { + MethodName: "GetRoot", + Handler: _CAService_GetRoot_Handler, + }, + { + MethodName: "CreateIssuer", + Handler: _CAService_CreateIssuer_Handler, + }, + { + MethodName: "DeleteIssuer", + Handler: _CAService_DeleteIssuer_Handler, + }, + { + MethodName: "ListIssuers", + Handler: _CAService_ListIssuers_Handler, + }, + { + MethodName: "GetIssuer", + Handler: _CAService_GetIssuer_Handler, + }, + { + MethodName: "GetChain", + Handler: _CAService_GetChain_Handler, + }, + { + MethodName: "IssueCert", + Handler: _CAService_IssueCert_Handler, + }, + { + MethodName: "GetCert", + Handler: _CAService_GetCert_Handler, + }, + { + MethodName: "ListCerts", + Handler: _CAService_ListCerts_Handler, + }, + { + MethodName: "RenewCert", + Handler: _CAService_RenewCert_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "proto/metacrypt/v2/ca.proto", +} diff --git a/gen/metacrypt/v2/common.pb.go b/gen/metacrypt/v2/common.pb.go new file mode 100644 index 0000000..6a7af5a --- /dev/null +++ b/gen/metacrypt/v2/common.pb.go @@ -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: proto/metacrypt/v2/common.proto + +package metacryptv2 + +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_proto_metacrypt_v2_common_proto protoreflect.FileDescriptor + +const file_proto_metacrypt_v2_common_proto_rawDesc = "" + + "\n" + + "\x1fproto/metacrypt/v2/common.proto\x12\fmetacrypt.v2B>Z\n" + + "\x06config\x18\x03 \x03(\v2&.metacrypt.v2.MountRequest.ConfigEntryR\x06config\x1a9\n" + + "\vConfigEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\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.v2.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\tmountPath2\xea\x01\n" + + "\rEngineService\x12@\n" + + "\x05Mount\x12\x1a.metacrypt.v2.MountRequest\x1a\x1b.metacrypt.v2.MountResponse\x12F\n" + + "\aUnmount\x12\x1c.metacrypt.v2.UnmountRequest\x1a\x1d.metacrypt.v2.UnmountResponse\x12O\n" + + "\n" + + "ListMounts\x12\x1f.metacrypt.v2.ListMountsRequest\x1a .metacrypt.v2.ListMountsResponseB>Z metacrypt.v2.MountRequest.ConfigEntry + 6, // 1: metacrypt.v2.ListMountsResponse.mounts:type_name -> metacrypt.v2.MountInfo + 0, // 2: metacrypt.v2.EngineService.Mount:input_type -> metacrypt.v2.MountRequest + 2, // 3: metacrypt.v2.EngineService.Unmount:input_type -> metacrypt.v2.UnmountRequest + 4, // 4: metacrypt.v2.EngineService.ListMounts:input_type -> metacrypt.v2.ListMountsRequest + 1, // 5: metacrypt.v2.EngineService.Mount:output_type -> metacrypt.v2.MountResponse + 3, // 6: metacrypt.v2.EngineService.Unmount:output_type -> metacrypt.v2.UnmountResponse + 5, // 7: metacrypt.v2.EngineService.ListMounts:output_type -> metacrypt.v2.ListMountsResponse + 5, // [5:8] is the sub-list for method output_type + 2, // [2:5] 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_proto_metacrypt_v2_engine_proto_init() } +func file_proto_metacrypt_v2_engine_proto_init() { + if File_proto_metacrypt_v2_engine_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_metacrypt_v2_engine_proto_rawDesc), len(file_proto_metacrypt_v2_engine_proto_rawDesc)), + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_metacrypt_v2_engine_proto_goTypes, + DependencyIndexes: file_proto_metacrypt_v2_engine_proto_depIdxs, + MessageInfos: file_proto_metacrypt_v2_engine_proto_msgTypes, + }.Build() + File_proto_metacrypt_v2_engine_proto = out.File + file_proto_metacrypt_v2_engine_proto_goTypes = nil + file_proto_metacrypt_v2_engine_proto_depIdxs = nil +} diff --git a/gen/metacrypt/v2/engine_grpc.pb.go b/gen/metacrypt/v2/engine_grpc.pb.go new file mode 100644 index 0000000..5058a23 --- /dev/null +++ b/gen/metacrypt/v2/engine_grpc.pb.go @@ -0,0 +1,205 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.1 +// - protoc v3.20.3 +// source: proto/metacrypt/v2/engine.proto + +package metacryptv2 + +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.v2.EngineService/Mount" + EngineService_Unmount_FullMethodName = "/metacrypt.v2.EngineService/Unmount" + EngineService_ListMounts_FullMethodName = "/metacrypt.v2.EngineService/ListMounts" +) + +// 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. +// +// EngineService manages the lifecycle of engine mounts. +// In v2, typed service RPCs (e.g. CAService) replace the generic Execute RPC +// for all engine operations. +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) +} + +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 +} + +// EngineServiceServer is the server API for EngineService service. +// All implementations must embed UnimplementedEngineServiceServer +// for forward compatibility. +// +// EngineService manages the lifecycle of engine mounts. +// In v2, typed service RPCs (e.g. CAService) replace the generic Execute RPC +// for all engine operations. +type EngineServiceServer interface { + Mount(context.Context, *MountRequest) (*MountResponse, error) + Unmount(context.Context, *UnmountRequest) (*UnmountResponse, error) + ListMounts(context.Context, *ListMountsRequest) (*ListMountsResponse, 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) 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) +} + +// 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.v2.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, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "proto/metacrypt/v2/engine.proto", +} diff --git a/gen/metacrypt/v2/pki.pb.go b/gen/metacrypt/v2/pki.pb.go new file mode 100644 index 0000000..610d65a --- /dev/null +++ b/gen/metacrypt/v2/pki.pb.go @@ -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: proto/metacrypt/v2/pki.proto + +package metacryptv2 + +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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_pki_proto_rawDescGZIP(), []int{5} +} + +func (x *GetIssuerCertResponse) GetCertPem() []byte { + if x != nil { + return x.CertPem + } + return nil +} + +var File_proto_metacrypt_v2_pki_proto protoreflect.FileDescriptor + +const file_proto_metacrypt_v2_pki_proto_rawDesc = "" + + "\n" + + "\x1cproto/metacrypt/v2/pki.proto\x12\fmetacrypt.v2\"*\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.v2.GetRootCertRequest\x1a!.metacrypt.v2.GetRootCertResponse\x12I\n" + + "\bGetChain\x12\x1d.metacrypt.v2.GetChainRequest\x1a\x1e.metacrypt.v2.GetChainResponse\x12X\n" + + "\rGetIssuerCert\x12\".metacrypt.v2.GetIssuerCertRequest\x1a#.metacrypt.v2.GetIssuerCertResponseB>Z metacrypt.v2.GetRootCertRequest + 2, // 1: metacrypt.v2.PKIService.GetChain:input_type -> metacrypt.v2.GetChainRequest + 4, // 2: metacrypt.v2.PKIService.GetIssuerCert:input_type -> metacrypt.v2.GetIssuerCertRequest + 1, // 3: metacrypt.v2.PKIService.GetRootCert:output_type -> metacrypt.v2.GetRootCertResponse + 3, // 4: metacrypt.v2.PKIService.GetChain:output_type -> metacrypt.v2.GetChainResponse + 5, // 5: metacrypt.v2.PKIService.GetIssuerCert:output_type -> metacrypt.v2.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_proto_metacrypt_v2_pki_proto_init() } +func file_proto_metacrypt_v2_pki_proto_init() { + if File_proto_metacrypt_v2_pki_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_metacrypt_v2_pki_proto_rawDesc), len(file_proto_metacrypt_v2_pki_proto_rawDesc)), + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_metacrypt_v2_pki_proto_goTypes, + DependencyIndexes: file_proto_metacrypt_v2_pki_proto_depIdxs, + MessageInfos: file_proto_metacrypt_v2_pki_proto_msgTypes, + }.Build() + File_proto_metacrypt_v2_pki_proto = out.File + file_proto_metacrypt_v2_pki_proto_goTypes = nil + file_proto_metacrypt_v2_pki_proto_depIdxs = nil +} diff --git a/gen/metacrypt/v2/pki_grpc.pb.go b/gen/metacrypt/v2/pki_grpc.pb.go new file mode 100644 index 0000000..5197dd1 --- /dev/null +++ b/gen/metacrypt/v2/pki_grpc.pb.go @@ -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: proto/metacrypt/v2/pki.proto + +package metacryptv2 + +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.v2.PKIService/GetRootCert" + PKIService_GetChain_FullMethodName = "/metacrypt.v2.PKIService/GetChain" + PKIService_GetIssuerCert_FullMethodName = "/metacrypt.v2.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.v2.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: "proto/metacrypt/v2/pki.proto", +} diff --git a/gen/metacrypt/v2/policy.pb.go b/gen/metacrypt/v2/policy.pb.go new file mode 100644 index 0000000..878fefb --- /dev/null +++ b/gen/metacrypt/v2/policy.pb.go @@ -0,0 +1,552 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v3.20.3 +// source: proto/metacrypt/v2/policy.proto + +package metacryptv2 + +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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_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_proto_metacrypt_v2_policy_proto_rawDescGZIP(), []int{1} +} + +func (x *CreatePolicyRequest) GetRule() *PolicyRule { + if x != nil { + return x.Rule + } + return nil +} + +type CreatePolicyResponse 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 *CreatePolicyResponse) Reset() { + *x = CreatePolicyResponse{} + mi := &file_proto_metacrypt_v2_policy_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreatePolicyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreatePolicyResponse) ProtoMessage() {} + +func (x *CreatePolicyResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_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 CreatePolicyResponse.ProtoReflect.Descriptor instead. +func (*CreatePolicyResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_policy_proto_rawDescGZIP(), []int{2} +} + +func (x *CreatePolicyResponse) 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_proto_metacrypt_v2_policy_proto_msgTypes[3] + 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_proto_metacrypt_v2_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 ListPoliciesRequest.ProtoReflect.Descriptor instead. +func (*ListPoliciesRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_policy_proto_rawDescGZIP(), []int{3} +} + +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_proto_metacrypt_v2_policy_proto_msgTypes[4] + 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_proto_metacrypt_v2_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 ListPoliciesResponse.ProtoReflect.Descriptor instead. +func (*ListPoliciesResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_policy_proto_rawDescGZIP(), []int{4} +} + +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_proto_metacrypt_v2_policy_proto_msgTypes[5] + 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_proto_metacrypt_v2_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 GetPolicyRequest.ProtoReflect.Descriptor instead. +func (*GetPolicyRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_policy_proto_rawDescGZIP(), []int{5} +} + +func (x *GetPolicyRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type GetPolicyResponse 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 *GetPolicyResponse) Reset() { + *x = GetPolicyResponse{} + mi := &file_proto_metacrypt_v2_policy_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetPolicyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetPolicyResponse) ProtoMessage() {} + +func (x *GetPolicyResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_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 GetPolicyResponse.ProtoReflect.Descriptor instead. +func (*GetPolicyResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_policy_proto_rawDescGZIP(), []int{6} +} + +func (x *GetPolicyResponse) GetRule() *PolicyRule { + if x != nil { + return x.Rule + } + return nil +} + +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_proto_metacrypt_v2_policy_proto_msgTypes[7] + 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_proto_metacrypt_v2_policy_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 DeletePolicyRequest.ProtoReflect.Descriptor instead. +func (*DeletePolicyRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_policy_proto_rawDescGZIP(), []int{7} +} + +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_proto_metacrypt_v2_policy_proto_msgTypes[8] + 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_proto_metacrypt_v2_policy_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 DeletePolicyResponse.ProtoReflect.Descriptor instead. +func (*DeletePolicyResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_policy_proto_rawDescGZIP(), []int{8} +} + +var File_proto_metacrypt_v2_policy_proto protoreflect.FileDescriptor + +const file_proto_metacrypt_v2_policy_proto_rawDesc = "" + + "\n" + + "\x1fproto/metacrypt/v2/policy.proto\x12\fmetacrypt.v2\"\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.v2.PolicyRuleR\x04rule\"D\n" + + "\x14CreatePolicyResponse\x12,\n" + + "\x04rule\x18\x01 \x01(\v2\x18.metacrypt.v2.PolicyRuleR\x04rule\"\x15\n" + + "\x13ListPoliciesRequest\"F\n" + + "\x14ListPoliciesResponse\x12.\n" + + "\x05rules\x18\x01 \x03(\v2\x18.metacrypt.v2.PolicyRuleR\x05rules\"\"\n" + + "\x10GetPolicyRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"A\n" + + "\x11GetPolicyResponse\x12,\n" + + "\x04rule\x18\x01 \x01(\v2\x18.metacrypt.v2.PolicyRuleR\x04rule\"%\n" + + "\x13DeletePolicyRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"\x16\n" + + "\x14DeletePolicyResponse2\xe2\x02\n" + + "\rPolicyService\x12U\n" + + "\fCreatePolicy\x12!.metacrypt.v2.CreatePolicyRequest\x1a\".metacrypt.v2.CreatePolicyResponse\x12U\n" + + "\fListPolicies\x12!.metacrypt.v2.ListPoliciesRequest\x1a\".metacrypt.v2.ListPoliciesResponse\x12L\n" + + "\tGetPolicy\x12\x1e.metacrypt.v2.GetPolicyRequest\x1a\x1f.metacrypt.v2.GetPolicyResponse\x12U\n" + + "\fDeletePolicy\x12!.metacrypt.v2.DeletePolicyRequest\x1a\".metacrypt.v2.DeletePolicyResponseB>Z metacrypt.v2.PolicyRule + 0, // 1: metacrypt.v2.CreatePolicyResponse.rule:type_name -> metacrypt.v2.PolicyRule + 0, // 2: metacrypt.v2.ListPoliciesResponse.rules:type_name -> metacrypt.v2.PolicyRule + 0, // 3: metacrypt.v2.GetPolicyResponse.rule:type_name -> metacrypt.v2.PolicyRule + 1, // 4: metacrypt.v2.PolicyService.CreatePolicy:input_type -> metacrypt.v2.CreatePolicyRequest + 3, // 5: metacrypt.v2.PolicyService.ListPolicies:input_type -> metacrypt.v2.ListPoliciesRequest + 5, // 6: metacrypt.v2.PolicyService.GetPolicy:input_type -> metacrypt.v2.GetPolicyRequest + 7, // 7: metacrypt.v2.PolicyService.DeletePolicy:input_type -> metacrypt.v2.DeletePolicyRequest + 2, // 8: metacrypt.v2.PolicyService.CreatePolicy:output_type -> metacrypt.v2.CreatePolicyResponse + 4, // 9: metacrypt.v2.PolicyService.ListPolicies:output_type -> metacrypt.v2.ListPoliciesResponse + 6, // 10: metacrypt.v2.PolicyService.GetPolicy:output_type -> metacrypt.v2.GetPolicyResponse + 8, // 11: metacrypt.v2.PolicyService.DeletePolicy:output_type -> metacrypt.v2.DeletePolicyResponse + 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_proto_metacrypt_v2_policy_proto_init() } +func file_proto_metacrypt_v2_policy_proto_init() { + if File_proto_metacrypt_v2_policy_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_metacrypt_v2_policy_proto_rawDesc), len(file_proto_metacrypt_v2_policy_proto_rawDesc)), + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_metacrypt_v2_policy_proto_goTypes, + DependencyIndexes: file_proto_metacrypt_v2_policy_proto_depIdxs, + MessageInfos: file_proto_metacrypt_v2_policy_proto_msgTypes, + }.Build() + File_proto_metacrypt_v2_policy_proto = out.File + file_proto_metacrypt_v2_policy_proto_goTypes = nil + file_proto_metacrypt_v2_policy_proto_depIdxs = nil +} diff --git a/gen/metacrypt/v2/policy_grpc.pb.go b/gen/metacrypt/v2/policy_grpc.pb.go new file mode 100644 index 0000000..a3662fb --- /dev/null +++ b/gen/metacrypt/v2/policy_grpc.pb.go @@ -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: proto/metacrypt/v2/policy.proto + +package metacryptv2 + +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.v2.PolicyService/CreatePolicy" + PolicyService_ListPolicies_FullMethodName = "/metacrypt.v2.PolicyService/ListPolicies" + PolicyService_GetPolicy_FullMethodName = "/metacrypt.v2.PolicyService/GetPolicy" + PolicyService_DeletePolicy_FullMethodName = "/metacrypt.v2.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) (*CreatePolicyResponse, error) + ListPolicies(ctx context.Context, in *ListPoliciesRequest, opts ...grpc.CallOption) (*ListPoliciesResponse, error) + GetPolicy(ctx context.Context, in *GetPolicyRequest, opts ...grpc.CallOption) (*GetPolicyResponse, 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) (*CreatePolicyResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreatePolicyResponse) + 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) (*GetPolicyResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetPolicyResponse) + 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) (*CreatePolicyResponse, error) + ListPolicies(context.Context, *ListPoliciesRequest) (*ListPoliciesResponse, error) + GetPolicy(context.Context, *GetPolicyRequest) (*GetPolicyResponse, 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) (*CreatePolicyResponse, 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) (*GetPolicyResponse, 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.v2.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: "proto/metacrypt/v2/policy.proto", +} diff --git a/gen/metacrypt/v2/system.pb.go b/gen/metacrypt/v2/system.pb.go new file mode 100644 index 0000000..fe44429 --- /dev/null +++ b/gen/metacrypt/v2/system.pb.go @@ -0,0 +1,446 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v3.20.3 +// source: proto/metacrypt/v2/system.proto + +package metacryptv2 + +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 StatusRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StatusRequest) Reset() { + *x = StatusRequest{} + mi := &file_proto_metacrypt_v2_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) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_system_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 StatusRequest.ProtoReflect.Descriptor instead. +func (*StatusRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_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"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StatusResponse) Reset() { + *x = StatusResponse{} + mi := &file_proto_metacrypt_v2_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) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_system_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 StatusResponse.ProtoReflect.Descriptor instead. +func (*StatusResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_system_proto_rawDescGZIP(), []int{1} +} + +func (x *StatusResponse) GetState() string { + if x != nil { + return x.State + } + return "" +} + +type InitRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Password string `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InitRequest) Reset() { + *x = InitRequest{} + mi := &file_proto_metacrypt_v2_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) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_system_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 InitRequest.ProtoReflect.Descriptor instead. +func (*InitRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_system_proto_rawDescGZIP(), []int{2} +} + +func (x *InitRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type InitResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + State string `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InitResponse) Reset() { + *x = InitResponse{} + mi := &file_proto_metacrypt_v2_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) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_system_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 InitResponse.ProtoReflect.Descriptor instead. +func (*InitResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_system_proto_rawDescGZIP(), []int{3} +} + +func (x *InitResponse) GetState() string { + if x != nil { + return x.State + } + return "" +} + +type UnsealRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Password string `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UnsealRequest) Reset() { + *x = UnsealRequest{} + mi := &file_proto_metacrypt_v2_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) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_system_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 UnsealRequest.ProtoReflect.Descriptor instead. +func (*UnsealRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_system_proto_rawDescGZIP(), []int{4} +} + +func (x *UnsealRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type UnsealResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + State string `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UnsealResponse) Reset() { + *x = UnsealResponse{} + mi := &file_proto_metacrypt_v2_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) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_system_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 UnsealResponse.ProtoReflect.Descriptor instead. +func (*UnsealResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_system_proto_rawDescGZIP(), []int{5} +} + +func (x *UnsealResponse) GetState() string { + if x != nil { + return x.State + } + return "" +} + +type SealRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SealRequest) Reset() { + *x = SealRequest{} + mi := &file_proto_metacrypt_v2_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) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_system_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 SealRequest.ProtoReflect.Descriptor instead. +func (*SealRequest) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_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"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SealResponse) Reset() { + *x = SealResponse{} + mi := &file_proto_metacrypt_v2_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) ProtoReflect() protoreflect.Message { + mi := &file_proto_metacrypt_v2_system_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 SealResponse.ProtoReflect.Descriptor instead. +func (*SealResponse) Descriptor() ([]byte, []int) { + return file_proto_metacrypt_v2_system_proto_rawDescGZIP(), []int{7} +} + +func (x *SealResponse) GetState() string { + if x != nil { + return x.State + } + return "" +} + +var File_proto_metacrypt_v2_system_proto protoreflect.FileDescriptor + +const file_proto_metacrypt_v2_system_proto_rawDesc = "" + + "\n" + + "\x1fproto/metacrypt/v2/system.proto\x12\fmetacrypt.v2\"\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.v2.StatusRequest\x1a\x1c.metacrypt.v2.StatusResponse\x12=\n" + + "\x04Init\x12\x19.metacrypt.v2.InitRequest\x1a\x1a.metacrypt.v2.InitResponse\x12C\n" + + "\x06Unseal\x12\x1b.metacrypt.v2.UnsealRequest\x1a\x1c.metacrypt.v2.UnsealResponse\x12=\n" + + "\x04Seal\x12\x19.metacrypt.v2.SealRequest\x1a\x1a.metacrypt.v2.SealResponseB>Z metacrypt.v2.StatusRequest + 2, // 1: metacrypt.v2.SystemService.Init:input_type -> metacrypt.v2.InitRequest + 4, // 2: metacrypt.v2.SystemService.Unseal:input_type -> metacrypt.v2.UnsealRequest + 6, // 3: metacrypt.v2.SystemService.Seal:input_type -> metacrypt.v2.SealRequest + 1, // 4: metacrypt.v2.SystemService.Status:output_type -> metacrypt.v2.StatusResponse + 3, // 5: metacrypt.v2.SystemService.Init:output_type -> metacrypt.v2.InitResponse + 5, // 6: metacrypt.v2.SystemService.Unseal:output_type -> metacrypt.v2.UnsealResponse + 7, // 7: metacrypt.v2.SystemService.Seal:output_type -> metacrypt.v2.SealResponse + 4, // [4:8] is the sub-list for method output_type + 0, // [0:4] 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_proto_metacrypt_v2_system_proto_init() } +func file_proto_metacrypt_v2_system_proto_init() { + if File_proto_metacrypt_v2_system_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_metacrypt_v2_system_proto_rawDesc), len(file_proto_metacrypt_v2_system_proto_rawDesc)), + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_metacrypt_v2_system_proto_goTypes, + DependencyIndexes: file_proto_metacrypt_v2_system_proto_depIdxs, + MessageInfos: file_proto_metacrypt_v2_system_proto_msgTypes, + }.Build() + File_proto_metacrypt_v2_system_proto = out.File + file_proto_metacrypt_v2_system_proto_goTypes = nil + file_proto_metacrypt_v2_system_proto_depIdxs = nil +} diff --git a/gen/metacrypt/v2/system_grpc.pb.go b/gen/metacrypt/v2/system_grpc.pb.go new file mode 100644 index 0000000..46bde69 --- /dev/null +++ b/gen/metacrypt/v2/system_grpc.pb.go @@ -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: proto/metacrypt/v2/system.proto + +package metacryptv2 + +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 ( + SystemService_Status_FullMethodName = "/metacrypt.v2.SystemService/Status" + SystemService_Init_FullMethodName = "/metacrypt.v2.SystemService/Init" + SystemService_Unseal_FullMethodName = "/metacrypt.v2.SystemService/Unseal" + SystemService_Seal_FullMethodName = "/metacrypt.v2.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) + Unseal(ctx context.Context, in *UnsealRequest, opts ...grpc.CallOption) (*UnsealResponse, error) + Seal(ctx context.Context, in *SealRequest, opts ...grpc.CallOption) (*SealResponse, error) +} + +type systemServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewSystemServiceClient(cc grpc.ClientConnInterface) SystemServiceClient { + return &systemServiceClient{cc} +} + +func (c *systemServiceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(StatusResponse) + err := c.cc.Invoke(ctx, SystemService_Status_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *systemServiceClient) Init(ctx context.Context, in *InitRequest, opts ...grpc.CallOption) (*InitResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(InitResponse) + err := c.cc.Invoke(ctx, SystemService_Init_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *systemServiceClient) Unseal(ctx context.Context, in *UnsealRequest, opts ...grpc.CallOption) (*UnsealResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UnsealResponse) + err := c.cc.Invoke(ctx, SystemService_Unseal_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *systemServiceClient) Seal(ctx context.Context, in *SealRequest, opts ...grpc.CallOption) (*SealResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SealResponse) + err := c.cc.Invoke(ctx, SystemService_Seal_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// 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) + Unseal(context.Context, *UnsealRequest) (*UnsealResponse, error) + Seal(context.Context, *SealRequest) (*SealResponse, error) + mustEmbedUnimplementedSystemServiceServer() +} + +// 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.Error(codes.Unimplemented, "method Status not implemented") +} +func (UnimplementedSystemServiceServer) Init(context.Context, *InitRequest) (*InitResponse, error) { + return nil, status.Error(codes.Unimplemented, "method Init not implemented") +} +func (UnimplementedSystemServiceServer) Unseal(context.Context, *UnsealRequest) (*UnsealResponse, error) { + return nil, status.Error(codes.Unimplemented, "method Unseal not implemented") +} +func (UnimplementedSystemServiceServer) Seal(context.Context, *SealRequest) (*SealResponse, error) { + 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 for this service. +// Use of this interface is not recommended, as added methods to SystemServiceServer will +// result in compilation errors. +type UnsafeSystemServiceServer interface { + mustEmbedUnimplementedSystemServiceServer() +} + +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) +} + +func _SystemService_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemServiceServer).Status(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SystemService_Status_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemServiceServer).Status(ctx, req.(*StatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SystemService_Init_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InitRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemServiceServer).Init(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SystemService_Init_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemServiceServer).Init(ctx, req.(*InitRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SystemService_Unseal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UnsealRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemServiceServer).Unseal(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SystemService_Unseal_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemServiceServer).Unseal(ctx, req.(*UnsealRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SystemService_Seal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SealRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemServiceServer).Seal(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SystemService_Seal_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemServiceServer).Seal(ctx, req.(*SealRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// 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.v2.SystemService", + HandlerType: (*SystemServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Status", + Handler: _SystemService_Status_Handler, + }, + { + MethodName: "Init", + Handler: _SystemService_Init_Handler, + }, + { + MethodName: "Unseal", + Handler: _SystemService_Unseal_Handler, + }, + { + MethodName: "Seal", + Handler: _SystemService_Seal_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "proto/metacrypt/v2/system.proto", +} diff --git a/internal/config/config.go b/internal/config/config.go index 10713d2..c523cfc 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -21,7 +21,7 @@ type Config struct { // ServerConfig holds HTTP/gRPC server settings. type ServerConfig struct { ListenAddr string `toml:"listen_addr"` - GRPCAddr string `toml:"grpc_addr"` + GRPCAddr string `toml:"grpc_addr"` TLSCert string `toml:"tls_cert"` TLSKey string `toml:"tls_key"` ExternalURL string `toml:"external_url"` // public base URL for ACME directory, e.g. "https://metacrypt.example.com" diff --git a/internal/grpcserver/acme.go b/internal/grpcserver/acme.go index 4d88da2..1afcc5a 100644 --- a/internal/grpcserver/acme.go +++ b/internal/grpcserver/acme.go @@ -6,8 +6,9 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" - pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1" + pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v2" internacme "git.wntrmute.dev/kyle/metacrypt/internal/acme" "git.wntrmute.dev/kyle/metacrypt/internal/engine" ) @@ -46,7 +47,7 @@ func (as *acmeServer) SetConfig(ctx context.Context, req *pb.SetConfigRequest) ( as.s.logger.Error("grpc: acme set config", "error", err) return nil, status.Error(codes.Internal, "failed to save config") } - return &pb.SetConfigResponse{Ok: true}, nil + return &pb.SetConfigResponse{}, nil } func (as *acmeServer) ListAccounts(ctx context.Context, req *pb.ListAccountsRequest) (*pb.ListAccountsResponse, error) { @@ -68,7 +69,7 @@ func (as *acmeServer) ListAccounts(ctx context.Context, req *pb.ListAccountsRequ Status: a.Status, Contact: contacts, MciasUsername: a.MCIASUsername, - CreatedAt: a.CreatedAt.String(), + CreatedAt: timestamppb.New(a.CreatedAt), }) } return &pb.ListAccountsResponse{Accounts: pbAccounts}, nil @@ -95,8 +96,8 @@ func (as *acmeServer) ListOrders(ctx context.Context, req *pb.ListOrdersRequest) AccountId: o.AccountID, Status: o.Status, Identifiers: identifiers, - CreatedAt: o.CreatedAt.String(), - ExpiresAt: o.ExpiresAt.String(), + CreatedAt: timestamppb.New(o.CreatedAt), + ExpiresAt: timestamppb.New(o.ExpiresAt), }) } return &pb.ListOrdersResponse{Orders: pbOrders}, nil diff --git a/internal/grpcserver/auth.go b/internal/grpcserver/auth.go index 9b34ca6..01ff57d 100644 --- a/internal/grpcserver/auth.go +++ b/internal/grpcserver/auth.go @@ -2,13 +2,15 @@ package grpcserver import ( "context" + "time" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" mcias "git.wntrmute.dev/kyle/mcias/clients/go" - pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1" + pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v2" ) type authServer struct { @@ -17,10 +19,14 @@ type authServer struct { } 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) + token, expiresAtStr, err := as.s.auth.Login(req.Username, req.Password, req.TotpCode) if err != nil { return nil, status.Error(codes.Unauthenticated, "invalid credentials") } + var expiresAt *timestamppb.Timestamp + if t, err := time.Parse(time.RFC3339, expiresAtStr); err == nil { + expiresAt = timestamppb.New(t) + } return &pb.LoginResponse{Token: token, ExpiresAt: expiresAt}, nil } diff --git a/internal/grpcserver/ca.go b/internal/grpcserver/ca.go new file mode 100644 index 0000000..f6fa1ba --- /dev/null +++ b/internal/grpcserver/ca.go @@ -0,0 +1,432 @@ +package grpcserver + +import ( + "context" + "errors" + "strings" + "time" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" + + pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v2" + "git.wntrmute.dev/kyle/metacrypt/internal/engine" + "git.wntrmute.dev/kyle/metacrypt/internal/engine/ca" +) + +type caServer struct { + pb.UnimplementedCAServiceServer + s *GRPCServer +} + +// caHandleRequest is a helper that dispatches a CA engine request and maps +// common errors to gRPC status codes. +func (cs *caServer) caHandleRequest(ctx context.Context, mount, operation string, req *engine.Request) (*engine.Response, error) { + resp, err := cs.s.engines.HandleRequest(ctx, mount, req) + if err != nil { + st := codes.Internal + switch { + case errors.Is(err, engine.ErrMountNotFound): + st = codes.NotFound + case errors.Is(err, ca.ErrIssuerNotFound): + st = codes.NotFound + case errors.Is(err, ca.ErrCertNotFound): + st = codes.NotFound + case errors.Is(err, ca.ErrIssuerExists): + st = codes.AlreadyExists + case errors.Is(err, ca.ErrUnauthorized): + st = codes.Unauthenticated + case errors.Is(err, ca.ErrForbidden): + st = codes.PermissionDenied + case strings.Contains(err.Error(), "not found"): + st = codes.NotFound + } + cs.s.logger.Error("grpc: ca "+operation, "mount", mount, "error", err) + return nil, status.Error(st, err.Error()) + } + return resp, nil +} + +func (cs *caServer) callerInfo(ctx context.Context) *engine.CallerInfo { + ti := tokenInfoFromContext(ctx) + if ti == nil { + return nil + } + return &engine.CallerInfo{ + Username: ti.Username, + Roles: ti.Roles, + IsAdmin: ti.IsAdmin, + } +} + +func (cs *caServer) ImportRoot(ctx context.Context, req *pb.ImportRootRequest) (*pb.ImportRootResponse, error) { + if req.Mount == "" { + return nil, status.Error(codes.InvalidArgument, "mount is required") + } + resp, err := cs.caHandleRequest(ctx, req.Mount, "import-root", &engine.Request{ + Operation: "import-root", + CallerInfo: cs.callerInfo(ctx), + Data: map[string]interface{}{ + "cert_pem": string(req.CertPem), + "key_pem": string(req.KeyPem), + }, + }) + if err != nil { + return nil, err + } + cn, _ := resp.Data["cn"].(string) + var expiresAt *timestamppb.Timestamp + if s, ok := resp.Data["expires_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, s); err == nil { + expiresAt = timestamppb.New(t) + } + } + return &pb.ImportRootResponse{CommonName: cn, ExpiresAt: expiresAt}, nil +} + +func (cs *caServer) GetRoot(ctx context.Context, req *pb.GetRootRequest) (*pb.GetRootResponse, error) { + if req.Mount == "" { + return nil, status.Error(codes.InvalidArgument, "mount is required") + } + resp, err := cs.caHandleRequest(ctx, req.Mount, "get-root", &engine.Request{ + Operation: "get-root", + }) + if err != nil { + return nil, err + } + certPEM, _ := resp.Data["cert_pem"].(string) + return &pb.GetRootResponse{CertPem: []byte(certPEM)}, nil +} + +func (cs *caServer) CreateIssuer(ctx context.Context, req *pb.CreateIssuerRequest) (*pb.CreateIssuerResponse, error) { + if req.Mount == "" || req.Name == "" { + return nil, status.Error(codes.InvalidArgument, "mount and name are required") + } + data := map[string]interface{}{ + "name": req.Name, + } + if req.KeyAlgorithm != "" { + data["key_algorithm"] = req.KeyAlgorithm + } + if req.KeySize != 0 { + data["key_size"] = float64(req.KeySize) + } + if req.Expiry != "" { + data["expiry"] = req.Expiry + } + if req.MaxTtl != "" { + data["max_ttl"] = req.MaxTtl + } + resp, err := cs.caHandleRequest(ctx, req.Mount, "create-issuer", &engine.Request{ + Operation: "create-issuer", + CallerInfo: cs.callerInfo(ctx), + Data: data, + }) + if err != nil { + return nil, err + } + name, _ := resp.Data["name"].(string) + certPEM, _ := resp.Data["cert_pem"].(string) + return &pb.CreateIssuerResponse{Name: name, CertPem: []byte(certPEM)}, nil +} + +func (cs *caServer) DeleteIssuer(ctx context.Context, req *pb.DeleteIssuerRequest) (*pb.DeleteIssuerResponse, error) { + if req.Mount == "" || req.Name == "" { + return nil, status.Error(codes.InvalidArgument, "mount and name are required") + } + _, err := cs.caHandleRequest(ctx, req.Mount, "delete-issuer", &engine.Request{ + Operation: "delete-issuer", + CallerInfo: cs.callerInfo(ctx), + Data: map[string]interface{}{"name": req.Name}, + }) + if err != nil { + return nil, err + } + return &pb.DeleteIssuerResponse{}, nil +} + +func (cs *caServer) ListIssuers(ctx context.Context, req *pb.ListIssuersRequest) (*pb.ListIssuersResponse, error) { + if req.Mount == "" { + return nil, status.Error(codes.InvalidArgument, "mount is required") + } + resp, err := cs.caHandleRequest(ctx, req.Mount, "list-issuers", &engine.Request{ + Operation: "list-issuers", + CallerInfo: cs.callerInfo(ctx), + }) + if err != nil { + return nil, err + } + raw, _ := resp.Data["issuers"].([]interface{}) + issuers := make([]string, 0, len(raw)) + for _, v := range raw { + if s, ok := v.(string); ok { + issuers = append(issuers, s) + } + } + return &pb.ListIssuersResponse{Issuers: issuers}, nil +} + +func (cs *caServer) GetIssuer(ctx context.Context, req *pb.GetIssuerRequest) (*pb.GetIssuerResponse, error) { + if req.Mount == "" || req.Name == "" { + return nil, status.Error(codes.InvalidArgument, "mount and name are required") + } + resp, err := cs.caHandleRequest(ctx, req.Mount, "get-issuer", &engine.Request{ + Operation: "get-issuer", + Path: req.Name, + }) + if err != nil { + return nil, err + } + certPEM, _ := resp.Data["cert_pem"].(string) + return &pb.GetIssuerResponse{CertPem: []byte(certPEM)}, nil +} + +func (cs *caServer) GetChain(ctx context.Context, req *pb.CAServiceGetChainRequest) (*pb.CAServiceGetChainResponse, error) { + if req.Mount == "" || req.Issuer == "" { + return nil, status.Error(codes.InvalidArgument, "mount and issuer are required") + } + resp, err := cs.caHandleRequest(ctx, req.Mount, "get-chain", &engine.Request{ + Operation: "get-chain", + Data: map[string]interface{}{"issuer": req.Issuer}, + }) + if err != nil { + return nil, err + } + chainPEM, _ := resp.Data["chain_pem"].(string) + return &pb.CAServiceGetChainResponse{ChainPem: []byte(chainPEM)}, nil +} + +func (cs *caServer) IssueCert(ctx context.Context, req *pb.IssueCertRequest) (*pb.IssueCertResponse, error) { + if req.Mount == "" || req.Issuer == "" { + return nil, status.Error(codes.InvalidArgument, "mount and issuer are required") + } + data := map[string]interface{}{ + "issuer": req.Issuer, + } + if req.Profile != "" { + data["profile"] = req.Profile + } + if req.CommonName != "" { + data["common_name"] = req.CommonName + } + if len(req.DnsNames) > 0 { + dns := make([]interface{}, len(req.DnsNames)) + for i, v := range req.DnsNames { + dns[i] = v + } + data["dns_names"] = dns + } + if len(req.IpAddresses) > 0 { + ips := make([]interface{}, len(req.IpAddresses)) + for i, v := range req.IpAddresses { + ips[i] = v + } + data["ip_addresses"] = ips + } + if req.Ttl != "" { + data["ttl"] = req.Ttl + } + if req.KeyAlgorithm != "" { + data["key_algorithm"] = req.KeyAlgorithm + } + if req.KeySize != 0 { + data["key_size"] = float64(req.KeySize) + } + if len(req.KeyUsages) > 0 { + ku := make([]interface{}, len(req.KeyUsages)) + for i, v := range req.KeyUsages { + ku[i] = v + } + data["key_usages"] = ku + } + if len(req.ExtKeyUsages) > 0 { + eku := make([]interface{}, len(req.ExtKeyUsages)) + for i, v := range req.ExtKeyUsages { + eku[i] = v + } + data["ext_key_usages"] = eku + } + + resp, err := cs.caHandleRequest(ctx, req.Mount, "issue", &engine.Request{ + Operation: "issue", + CallerInfo: cs.callerInfo(ctx), + Data: data, + }) + if err != nil { + return nil, err + } + + serial, _ := resp.Data["serial"].(string) + cn, _ := resp.Data["cn"].(string) + issuedBy, _ := resp.Data["issued_by"].(string) + certPEM, _ := resp.Data["cert_pem"].(string) + keyPEM, _ := resp.Data["key_pem"].(string) + chainPEM, _ := resp.Data["chain_pem"].(string) + sans := toStringSliceFromInterface(resp.Data["sans"]) + var expiresAt *timestamppb.Timestamp + if s, ok := resp.Data["expires_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, s); err == nil { + expiresAt = timestamppb.New(t) + } + } + return &pb.IssueCertResponse{ + Serial: serial, + CommonName: cn, + Sans: sans, + IssuedBy: issuedBy, + ExpiresAt: expiresAt, + CertPem: []byte(certPEM), + KeyPem: []byte(keyPEM), + ChainPem: []byte(chainPEM), + }, nil +} + +func (cs *caServer) GetCert(ctx context.Context, req *pb.GetCertRequest) (*pb.GetCertResponse, error) { + if req.Mount == "" || req.Serial == "" { + return nil, status.Error(codes.InvalidArgument, "mount and serial are required") + } + resp, err := cs.caHandleRequest(ctx, req.Mount, "get-cert", &engine.Request{ + Operation: "get-cert", + CallerInfo: cs.callerInfo(ctx), + Data: map[string]interface{}{"serial": req.Serial}, + }) + if err != nil { + return nil, err + } + rec := certRecordFromData(resp.Data) + return &pb.GetCertResponse{Cert: rec}, nil +} + +func (cs *caServer) ListCerts(ctx context.Context, req *pb.ListCertsRequest) (*pb.ListCertsResponse, error) { + if req.Mount == "" { + return nil, status.Error(codes.InvalidArgument, "mount is required") + } + resp, err := cs.caHandleRequest(ctx, req.Mount, "list-certs", &engine.Request{ + Operation: "list-certs", + CallerInfo: cs.callerInfo(ctx), + }) + if err != nil { + return nil, err + } + raw, _ := resp.Data["certs"].([]interface{}) + summaries := make([]*pb.CertSummary, 0, len(raw)) + for _, item := range raw { + m, ok := item.(map[string]interface{}) + if !ok { + continue + } + summaries = append(summaries, certSummaryFromData(m)) + } + return &pb.ListCertsResponse{Certs: summaries}, nil +} + +func (cs *caServer) RenewCert(ctx context.Context, req *pb.RenewCertRequest) (*pb.RenewCertResponse, error) { + if req.Mount == "" || req.Serial == "" { + return nil, status.Error(codes.InvalidArgument, "mount and serial are required") + } + resp, err := cs.caHandleRequest(ctx, req.Mount, "renew", &engine.Request{ + Operation: "renew", + CallerInfo: cs.callerInfo(ctx), + Data: map[string]interface{}{"serial": req.Serial}, + }) + if err != nil { + return nil, err + } + serial, _ := resp.Data["serial"].(string) + cn, _ := resp.Data["cn"].(string) + issuedBy, _ := resp.Data["issued_by"].(string) + certPEM, _ := resp.Data["cert_pem"].(string) + keyPEM, _ := resp.Data["key_pem"].(string) + chainPEM, _ := resp.Data["chain_pem"].(string) + sans := toStringSliceFromInterface(resp.Data["sans"]) + var expiresAt *timestamppb.Timestamp + if s, ok := resp.Data["expires_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, s); err == nil { + expiresAt = timestamppb.New(t) + } + } + return &pb.RenewCertResponse{ + Serial: serial, + CommonName: cn, + Sans: sans, + IssuedBy: issuedBy, + ExpiresAt: expiresAt, + CertPem: []byte(certPEM), + KeyPem: []byte(keyPEM), + ChainPem: []byte(chainPEM), + }, nil +} + +// --- helpers --- + +func certRecordFromData(d map[string]interface{}) *pb.CertRecord { + serial, _ := d["serial"].(string) + issuer, _ := d["issuer"].(string) + cn, _ := d["cn"].(string) + profile, _ := d["profile"].(string) + issuedBy, _ := d["issued_by"].(string) + certPEM, _ := d["cert_pem"].(string) + sans := toStringSliceFromInterface(d["sans"]) + var issuedAt, expiresAt *timestamppb.Timestamp + if s, ok := d["issued_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, s); err == nil { + issuedAt = timestamppb.New(t) + } + } + if s, ok := d["expires_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, s); err == nil { + expiresAt = timestamppb.New(t) + } + } + return &pb.CertRecord{ + Serial: serial, + Issuer: issuer, + CommonName: cn, + Sans: sans, + Profile: profile, + IssuedBy: issuedBy, + IssuedAt: issuedAt, + ExpiresAt: expiresAt, + CertPem: []byte(certPEM), + } +} + +func certSummaryFromData(d map[string]interface{}) *pb.CertSummary { + serial, _ := d["serial"].(string) + issuer, _ := d["issuer"].(string) + cn, _ := d["cn"].(string) + profile, _ := d["profile"].(string) + issuedBy, _ := d["issued_by"].(string) + var issuedAt, expiresAt *timestamppb.Timestamp + if s, ok := d["issued_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, s); err == nil { + issuedAt = timestamppb.New(t) + } + } + if s, ok := d["expires_at"].(string); ok { + if t, err := time.Parse(time.RFC3339, s); err == nil { + expiresAt = timestamppb.New(t) + } + } + return &pb.CertSummary{ + Serial: serial, + Issuer: issuer, + CommonName: cn, + Profile: profile, + IssuedBy: issuedBy, + IssuedAt: issuedAt, + ExpiresAt: expiresAt, + } +} + +func toStringSliceFromInterface(v interface{}) []string { + raw, _ := v.([]interface{}) + out := make([]string, 0, len(raw)) + for _, item := range raw { + if s, ok := item.(string); ok { + out = append(out, s) + } + } + return out +} diff --git a/internal/grpcserver/engine.go b/internal/grpcserver/engine.go index de78d78..7b2534b 100644 --- a/internal/grpcserver/engine.go +++ b/internal/grpcserver/engine.go @@ -3,13 +3,11 @@ 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" + pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v2" "git.wntrmute.dev/kyle/metacrypt/internal/engine" ) @@ -24,8 +22,11 @@ func (es *engineServer) Mount(ctx context.Context, req *pb.MountRequest) (*pb.Mo } var config map[string]interface{} - if req.Config != nil { - config = req.Config.AsMap() + if len(req.Config) > 0 { + config = make(map[string]interface{}, len(req.Config)) + for k, v := range req.Config { + config[k] = v + } } if err := es.s.engines.Mount(ctx, req.Name, engine.EngineType(req.Type), config); err != nil { @@ -68,53 +69,3 @@ func (es *engineServer) ListMounts(_ context.Context, _ *pb.ListMountsRequest) ( return &pb.ListMountsResponse{Mounts: pbMounts}, nil } -func (es *engineServer) Execute(ctx context.Context, req *pb.ExecuteRequest) (*pb.ExecuteResponse, 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, - } - } - - username := "" - if ti != nil { - username = ti.Username - } - es.s.logger.Info("grpc: engine execute", "mount", req.Mount, "operation", req.Operation, "username", username) - - 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 - } - es.s.logger.Error("grpc: engine execute failed", "mount", req.Mount, "operation", req.Operation, "username", username, "error", err) - return nil, status.Error(st, err.Error()) - } - es.s.logger.Info("grpc: engine execute ok", "mount", req.Mount, "operation", req.Operation, "username", username) - - pbData, err := structpb.NewStruct(resp.Data) - if err != nil { - return nil, status.Error(codes.Internal, "failed to encode response") - } - return &pb.ExecuteResponse{Data: pbData}, nil -} diff --git a/internal/grpcserver/grpcserver_test.go b/internal/grpcserver/grpcserver_test.go new file mode 100644 index 0000000..4807358 --- /dev/null +++ b/internal/grpcserver/grpcserver_test.go @@ -0,0 +1,720 @@ +package grpcserver + +import ( + "context" + "log/slog" + "path/filepath" + "testing" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + + pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v2" + "git.wntrmute.dev/kyle/metacrypt/internal/auth" + "git.wntrmute.dev/kyle/metacrypt/internal/barrier" + "git.wntrmute.dev/kyle/metacrypt/internal/config" + "git.wntrmute.dev/kyle/metacrypt/internal/crypto" + "git.wntrmute.dev/kyle/metacrypt/internal/db" + "git.wntrmute.dev/kyle/metacrypt/internal/engine" + "git.wntrmute.dev/kyle/metacrypt/internal/policy" + "git.wntrmute.dev/kyle/metacrypt/internal/seal" +) + +// ---- test helpers ---- + +func fastArgon2Params() crypto.Argon2Params { + return crypto.Argon2Params{Time: 1, Memory: 64 * 1024, Threads: 1} +} + +// mockBarrier is a no-op barrier for engine registry tests. +type mockBarrier struct{} + +func (m *mockBarrier) Unseal(_ []byte) error { return nil } +func (m *mockBarrier) Seal() error { return nil } +func (m *mockBarrier) IsSealed() bool { return false } +func (m *mockBarrier) Get(_ context.Context, _ string) ([]byte, error) { return nil, barrier.ErrNotFound } +func (m *mockBarrier) Put(_ context.Context, _ string, _ []byte) error { return nil } +func (m *mockBarrier) Delete(_ context.Context, _ string) error { return nil } +func (m *mockBarrier) List(_ context.Context, _ string) ([]string, error) { return nil, nil } + +// mockEngine is a minimal engine.Engine for registry tests. +type mockEngine struct{ t engine.EngineType } + +func (m *mockEngine) Type() engine.EngineType { return m.t } +func (m *mockEngine) Initialize(_ context.Context, _ barrier.Barrier, _ string, _ map[string]interface{}) error { + return nil +} +func (m *mockEngine) Unseal(_ context.Context, _ barrier.Barrier, _ string) error { return nil } +func (m *mockEngine) Seal() error { return nil } +func (m *mockEngine) HandleRequest(_ context.Context, _ *engine.Request) (*engine.Response, error) { + return &engine.Response{Data: map[string]interface{}{"ok": true}}, nil +} + +func newTestRegistry() *engine.Registry { + reg := engine.NewRegistry(&mockBarrier{}, slog.Default()) + reg.RegisterFactory(engine.EngineTypeTransit, func() engine.Engine { + return &mockEngine{t: engine.EngineTypeTransit} + }) + return reg +} + +func newTestGRPCServer(t *testing.T) (*GRPCServer, func()) { + t.Helper() + dir := t.TempDir() + database, err := db.Open(filepath.Join(dir, "test.db")) + if err != nil { + t.Fatalf("open db: %v", err) + } + if err := db.Migrate(database); err != nil { + t.Fatalf("migrate: %v", err) + } + b := barrier.NewAESGCMBarrier(database) + sealMgr := seal.NewManager(database, b, slog.Default()) + policyEngine := policy.NewEngine(b) + reg := newTestRegistry() + authenticator := auth.NewAuthenticator(nil, slog.Default()) + cfg := &config.Config{ + Seal: config.SealConfig{ + Argon2Time: 1, + Argon2Memory: 64 * 1024, + Argon2Threads: 1, + }, + } + srv := New(cfg, sealMgr, authenticator, policyEngine, reg, slog.Default()) + return srv, func() { _ = database.Close() } +} + +// okHandler is a grpc.UnaryHandler that always succeeds. +func okHandler(_ context.Context, _ interface{}) (interface{}, error) { + return "ok", nil +} + +func methodInfo(name string) *grpc.UnaryServerInfo { + return &grpc.UnaryServerInfo{FullMethod: name} +} + +// ---- interceptor tests ---- + +func TestSealInterceptor_Unsealed(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + // Initialize and unseal so state == StateUnsealed. + if err := srv.sealMgr.Initialize(context.Background(), []byte("pw"), fastArgon2Params()); err != nil { + t.Fatalf("initialize: %v", err) + } + + methods := map[string]bool{"/test.Service/Method": true} + interceptor := sealInterceptor(srv.sealMgr, slog.Default(), methods) + + resp, err := interceptor(context.Background(), nil, methodInfo("/test.Service/Method"), okHandler) + if err != nil { + t.Fatalf("expected success when unsealed, got: %v", err) + } + if resp != "ok" { + t.Errorf("expected 'ok', got %v", resp) + } +} + +func TestSealInterceptor_Sealed(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + // Initialize then seal. + if err := srv.sealMgr.Initialize(context.Background(), []byte("pw"), fastArgon2Params()); err != nil { + t.Fatalf("initialize: %v", err) + } + if err := srv.sealMgr.Seal(); err != nil { + t.Fatalf("seal: %v", err) + } + + methods := map[string]bool{"/test.Service/Method": true} + interceptor := sealInterceptor(srv.sealMgr, slog.Default(), methods) + + _, err := interceptor(context.Background(), nil, methodInfo("/test.Service/Method"), okHandler) + if err == nil { + t.Fatal("expected error when sealed") + } + if code := status.Code(err); code != codes.FailedPrecondition { + t.Errorf("expected FailedPrecondition, got %v", code) + } +} + +func TestSealInterceptor_SkipsUnlistedMethod(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + // State is uninitialized (sealed), but method is not in the list. + methods := map[string]bool{"/test.Service/Other": true} + interceptor := sealInterceptor(srv.sealMgr, slog.Default(), methods) + + resp, err := interceptor(context.Background(), nil, methodInfo("/test.Service/Method"), okHandler) + if err != nil { + t.Fatalf("expected pass-through, got: %v", err) + } + if resp != "ok" { + t.Errorf("expected 'ok', got %v", resp) + } +} + +func TestAuthInterceptor_MissingToken(t *testing.T) { + authenticator := auth.NewAuthenticator(nil, slog.Default()) + methods := map[string]bool{"/test.Service/Method": true} + interceptor := authInterceptor(authenticator, slog.Default(), methods) + + _, err := interceptor(context.Background(), nil, methodInfo("/test.Service/Method"), okHandler) + if err == nil { + t.Fatal("expected error for missing token") + } + if code := status.Code(err); code != codes.Unauthenticated { + t.Errorf("expected Unauthenticated, got %v", code) + } +} + +func TestAuthInterceptor_SkipsUnlistedMethod(t *testing.T) { + authenticator := auth.NewAuthenticator(nil, slog.Default()) + methods := map[string]bool{"/test.Service/Other": true} + interceptor := authInterceptor(authenticator, slog.Default(), methods) + + resp, err := interceptor(context.Background(), nil, methodInfo("/test.Service/Method"), okHandler) + if err != nil { + t.Fatalf("expected pass-through, got: %v", err) + } + if resp != "ok" { + t.Errorf("expected 'ok', got %v", resp) + } +} + +func TestAdminInterceptor_NoTokenInfo(t *testing.T) { + methods := map[string]bool{"/test.Service/Admin": true} + interceptor := adminInterceptor(slog.Default(), methods) + + _, err := interceptor(context.Background(), nil, methodInfo("/test.Service/Admin"), okHandler) + if err == nil { + t.Fatal("expected error when no token info in context") + } + if code := status.Code(err); code != codes.PermissionDenied { + t.Errorf("expected PermissionDenied, got %v", code) + } +} + +func TestAdminInterceptor_NonAdmin(t *testing.T) { + methods := map[string]bool{"/test.Service/Admin": true} + interceptor := adminInterceptor(slog.Default(), methods) + + ctx := context.WithValue(context.Background(), tokenInfoKey, &auth.TokenInfo{ + Username: "user", + IsAdmin: false, + }) + _, err := interceptor(ctx, nil, methodInfo("/test.Service/Admin"), okHandler) + if err == nil { + t.Fatal("expected error for non-admin") + } + if code := status.Code(err); code != codes.PermissionDenied { + t.Errorf("expected PermissionDenied, got %v", code) + } +} + +func TestAdminInterceptor_Admin(t *testing.T) { + methods := map[string]bool{"/test.Service/Admin": true} + interceptor := adminInterceptor(slog.Default(), methods) + + ctx := context.WithValue(context.Background(), tokenInfoKey, &auth.TokenInfo{ + Username: "admin", + IsAdmin: true, + }) + resp, err := interceptor(ctx, nil, methodInfo("/test.Service/Admin"), okHandler) + if err != nil { + t.Fatalf("expected success for admin, got: %v", err) + } + if resp != "ok" { + t.Errorf("expected 'ok', got %v", resp) + } +} + +func TestAdminInterceptor_SkipsUnlistedMethod(t *testing.T) { + methods := map[string]bool{"/test.Service/Other": true} + interceptor := adminInterceptor(slog.Default(), methods) + + // No token info in context — but method not listed, so should pass through. + resp, err := interceptor(context.Background(), nil, methodInfo("/test.Service/Method"), okHandler) + if err != nil { + t.Fatalf("expected pass-through, got: %v", err) + } + if resp != "ok" { + t.Errorf("expected 'ok', got %v", resp) + } +} + +func TestChainInterceptors(t *testing.T) { + var order []int + makeInterceptor := func(n int) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + order = append(order, n) + return handler(ctx, req) + } + } + + chained := chainInterceptors(makeInterceptor(1), makeInterceptor(2), makeInterceptor(3)) + _, err := chained(context.Background(), nil, methodInfo("/test/Method"), okHandler) + if err != nil { + t.Fatalf("chain: %v", err) + } + if len(order) != 3 || order[0] != 1 || order[1] != 2 || order[2] != 3 { + t.Errorf("expected execution order [1 2 3], got %v", order) + } +} + +func TestExtractToken(t *testing.T) { + tests := []struct { + name string + md metadata.MD + expected string + }{ + {"no metadata", nil, ""}, + {"no authorization", metadata.Pairs("other", "val"), ""}, + {"bearer token", metadata.Pairs("authorization", "Bearer mytoken"), "mytoken"}, + {"raw token", metadata.Pairs("authorization", "mytoken"), "mytoken"}, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var ctx context.Context + if tc.md != nil { + ctx = metadata.NewIncomingContext(context.Background(), tc.md) + } else { + ctx = context.Background() + } + got := extractToken(ctx) + if got != tc.expected { + t.Errorf("extractToken: got %q, want %q", got, tc.expected) + } + }) + } +} + +// ---- systemServer tests ---- + +func TestSystemStatus(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ss := &systemServer{s: srv} + resp, err := ss.Status(context.Background(), &pb.StatusRequest{}) + if err != nil { + t.Fatalf("Status: %v", err) + } + if resp.State != "uninitialized" { + t.Errorf("expected 'uninitialized', got %q", resp.State) + } +} + +func TestSystemInit_EmptyPassword(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ss := &systemServer{s: srv} + _, err := ss.Init(context.Background(), &pb.InitRequest{Password: ""}) + if err == nil { + t.Fatal("expected error for empty password") + } + if code := status.Code(err); code != codes.InvalidArgument { + t.Errorf("expected InvalidArgument, got %v", code) + } +} + +func TestSystemInit_Success(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ss := &systemServer{s: srv} + resp, err := ss.Init(context.Background(), &pb.InitRequest{Password: "testpassword"}) + if err != nil { + t.Fatalf("Init: %v", err) + } + if resp.State != "unsealed" { + t.Errorf("expected 'unsealed' after init, got %q", resp.State) + } +} + +func TestSystemInit_AlreadyInitialized(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ss := &systemServer{s: srv} + if _, err := ss.Init(context.Background(), &pb.InitRequest{Password: "pw"}); err != nil { + t.Fatalf("first Init: %v", err) + } + _, err := ss.Init(context.Background(), &pb.InitRequest{Password: "pw"}) + if err == nil { + t.Fatal("expected error on second Init") + } + if code := status.Code(err); code != codes.AlreadyExists { + t.Errorf("expected AlreadyExists, got %v", code) + } +} + +func TestSystemUnseal_NotInitialized(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ss := &systemServer{s: srv} + _, err := ss.Unseal(context.Background(), &pb.UnsealRequest{Password: "pw"}) + if err == nil { + t.Fatal("expected error when not initialized") + } + if code := status.Code(err); code != codes.FailedPrecondition { + t.Errorf("expected FailedPrecondition, got %v", code) + } +} + +func TestSystemUnseal_InvalidPassword(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ss := &systemServer{s: srv} + if _, err := ss.Init(context.Background(), &pb.InitRequest{Password: "correct"}); err != nil { + t.Fatalf("Init: %v", err) + } + if err := srv.sealMgr.Seal(); err != nil { + t.Fatalf("Seal: %v", err) + } + + _, err := ss.Unseal(context.Background(), &pb.UnsealRequest{Password: "wrong"}) + if err == nil { + t.Fatal("expected error for wrong password") + } + if code := status.Code(err); code != codes.Unauthenticated { + t.Errorf("expected Unauthenticated, got %v", code) + } +} + +func TestSystemUnseal_Success(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ss := &systemServer{s: srv} + if _, err := ss.Init(context.Background(), &pb.InitRequest{Password: "pw"}); err != nil { + t.Fatalf("Init: %v", err) + } + if err := srv.sealMgr.Seal(); err != nil { + t.Fatalf("Seal: %v", err) + } + + resp, err := ss.Unseal(context.Background(), &pb.UnsealRequest{Password: "pw"}) + if err != nil { + t.Fatalf("Unseal: %v", err) + } + if resp.State != "unsealed" { + t.Errorf("expected 'unsealed', got %q", resp.State) + } +} + +func TestSystemSeal_Success(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ss := &systemServer{s: srv} + if _, err := ss.Init(context.Background(), &pb.InitRequest{Password: "pw"}); err != nil { + t.Fatalf("Init: %v", err) + } + + resp, err := ss.Seal(context.Background(), &pb.SealRequest{}) + if err != nil { + t.Fatalf("Seal: %v", err) + } + if resp.State != "sealed" { + t.Errorf("expected 'sealed', got %q", resp.State) + } +} + +// ---- engineServer tests ---- + +func TestEngineMount_MissingFields(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + es := &engineServer{s: srv} + + _, err := es.Mount(context.Background(), &pb.MountRequest{Name: "", Type: "transit"}) + if code := status.Code(err); code != codes.InvalidArgument { + t.Errorf("empty name: expected InvalidArgument, got %v", code) + } + + _, err = es.Mount(context.Background(), &pb.MountRequest{Name: "default", Type: ""}) + if code := status.Code(err); code != codes.InvalidArgument { + t.Errorf("empty type: expected InvalidArgument, got %v", code) + } +} + +func TestEngineMount_UnknownType(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + es := &engineServer{s: srv} + _, err := es.Mount(context.Background(), &pb.MountRequest{Name: "test", Type: "unknown"}) + if err == nil { + t.Fatal("expected error for unknown engine type") + } + if code := status.Code(err); code != codes.InvalidArgument { + t.Errorf("expected InvalidArgument, got %v", code) + } +} + +func TestEngineMount_Success(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + es := &engineServer{s: srv} + _, err := es.Mount(context.Background(), &pb.MountRequest{Name: "default", Type: "transit"}) + if err != nil { + t.Fatalf("Mount: %v", err) + } +} + +func TestEngineMount_Duplicate(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + es := &engineServer{s: srv} + if _, err := es.Mount(context.Background(), &pb.MountRequest{Name: "default", Type: "transit"}); err != nil { + t.Fatalf("first Mount: %v", err) + } + _, err := es.Mount(context.Background(), &pb.MountRequest{Name: "default", Type: "transit"}) + if err == nil { + t.Fatal("expected error for duplicate mount") + } + if code := status.Code(err); code != codes.AlreadyExists { + t.Errorf("expected AlreadyExists, got %v", code) + } +} + +func TestEngineUnmount_MissingName(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + es := &engineServer{s: srv} + _, err := es.Unmount(context.Background(), &pb.UnmountRequest{Name: ""}) + if code := status.Code(err); code != codes.InvalidArgument { + t.Errorf("expected InvalidArgument, got %v", code) + } +} + +func TestEngineUnmount_NotFound(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + es := &engineServer{s: srv} + _, err := es.Unmount(context.Background(), &pb.UnmountRequest{Name: "nonexistent"}) + if code := status.Code(err); code != codes.NotFound { + t.Errorf("expected NotFound, got %v", code) + } +} + +func TestEngineUnmount_Success(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + es := &engineServer{s: srv} + if _, err := es.Mount(context.Background(), &pb.MountRequest{Name: "default", Type: "transit"}); err != nil { + t.Fatalf("Mount: %v", err) + } + if _, err := es.Unmount(context.Background(), &pb.UnmountRequest{Name: "default"}); err != nil { + t.Fatalf("Unmount: %v", err) + } +} + +func TestEngineListMounts(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + es := &engineServer{s: srv} + + resp, err := es.ListMounts(context.Background(), &pb.ListMountsRequest{}) + if err != nil { + t.Fatalf("ListMounts: %v", err) + } + if len(resp.Mounts) != 0 { + t.Errorf("expected 0 mounts, got %d", len(resp.Mounts)) + } + + if _, err := es.Mount(context.Background(), &pb.MountRequest{Name: "eng1", Type: "transit"}); err != nil { + t.Fatalf("Mount: %v", err) + } + + resp, err = es.ListMounts(context.Background(), &pb.ListMountsRequest{}) + if err != nil { + t.Fatalf("ListMounts after mount: %v", err) + } + if len(resp.Mounts) != 1 { + t.Errorf("expected 1 mount, got %d", len(resp.Mounts)) + } + if resp.Mounts[0].Name != "eng1" { + t.Errorf("mount name: got %q, want %q", resp.Mounts[0].Name, "eng1") + } +} + +// ---- policyServer tests ---- + +func TestPolicyCreate_MissingID(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ps := &policyServer{s: srv} + _, err := ps.CreatePolicy(context.Background(), &pb.CreatePolicyRequest{ + Rule: &pb.PolicyRule{Id: ""}, + }) + if code := status.Code(err); code != codes.InvalidArgument { + t.Errorf("expected InvalidArgument, got %v", code) + } +} + +func TestPolicyCreate_NilRule(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ps := &policyServer{s: srv} + _, err := ps.CreatePolicy(context.Background(), &pb.CreatePolicyRequest{Rule: nil}) + if code := status.Code(err); code != codes.InvalidArgument { + t.Errorf("expected InvalidArgument, got %v", code) + } +} + +func TestPolicyRoundtrip(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + // Policy engine needs an unsealed barrier; unseal it via the seal manager. + if err := srv.sealMgr.Initialize(context.Background(), []byte("pw"), fastArgon2Params()); err != nil { + t.Fatalf("initialize: %v", err) + } + + ps := &policyServer{s: srv} + rule := &pb.PolicyRule{ + Id: "rule-1", + Priority: 10, + Effect: "allow", + Usernames: []string{"alice"}, + Resources: []string{"/ca/*"}, + Actions: []string{"read"}, + } + + // Create. + createResp, err := ps.CreatePolicy(context.Background(), &pb.CreatePolicyRequest{Rule: rule}) + if err != nil { + t.Fatalf("CreatePolicy: %v", err) + } + if createResp.Rule.Id != "rule-1" { + t.Errorf("created rule id: got %q, want %q", createResp.Rule.Id, "rule-1") + } + + // Get. + getResp, err := ps.GetPolicy(context.Background(), &pb.GetPolicyRequest{Id: "rule-1"}) + if err != nil { + t.Fatalf("GetPolicy: %v", err) + } + if getResp.Rule.Id != "rule-1" { + t.Errorf("get rule id: got %q, want %q", getResp.Rule.Id, "rule-1") + } + + // List. + listResp, err := ps.ListPolicies(context.Background(), &pb.ListPoliciesRequest{}) + if err != nil { + t.Fatalf("ListPolicies: %v", err) + } + if len(listResp.Rules) != 1 { + t.Errorf("expected 1 rule, got %d", len(listResp.Rules)) + } + + // Delete. + if _, err := ps.DeletePolicy(context.Background(), &pb.DeletePolicyRequest{Id: "rule-1"}); err != nil { + t.Fatalf("DeletePolicy: %v", err) + } + + // Get after delete should fail. + _, err = ps.GetPolicy(context.Background(), &pb.GetPolicyRequest{Id: "rule-1"}) + if code := status.Code(err); code != codes.NotFound { + t.Errorf("expected NotFound after delete, got %v", code) + } +} + +func TestPolicyGet_MissingID(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ps := &policyServer{s: srv} + _, err := ps.GetPolicy(context.Background(), &pb.GetPolicyRequest{Id: ""}) + if code := status.Code(err); code != codes.InvalidArgument { + t.Errorf("expected InvalidArgument, got %v", code) + } +} + +func TestPolicyDelete_MissingID(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + ps := &policyServer{s: srv} + _, err := ps.DeletePolicy(context.Background(), &pb.DeletePolicyRequest{Id: ""}) + if code := status.Code(err); code != codes.InvalidArgument { + t.Errorf("expected InvalidArgument, got %v", code) + } +} + +// ---- authServer tests ---- + +func TestAuthTokenInfo_FromContext(t *testing.T) { + srv, cleanup := newTestGRPCServer(t) + defer cleanup() + + as := &authServer{s: srv} + ti := &auth.TokenInfo{Username: "alice", Roles: []string{"user"}, IsAdmin: false} + ctx := context.WithValue(context.Background(), tokenInfoKey, ti) + + resp, err := as.TokenInfo(ctx, &pb.TokenInfoRequest{}) + if err != nil { + t.Fatalf("TokenInfo: %v", err) + } + if resp.Username != "alice" { + t.Errorf("username: got %q, want %q", resp.Username, "alice") + } + if resp.IsAdmin { + t.Error("expected IsAdmin=false") + } +} + + +// ---- pbToRule / ruleToPB conversion tests ---- + +func TestPbToRuleRoundtrip(t *testing.T) { + original := &pb.PolicyRule{ + Id: "test-rule", + Priority: 5, + Effect: "deny", + Usernames: []string{"bob"}, + Roles: []string{"operator"}, + Resources: []string{"/pki/*"}, + Actions: []string{"write", "delete"}, + } + + rule := pbToRule(original) + if rule.ID != original.Id { + t.Errorf("ID: got %q, want %q", rule.ID, original.Id) + } + if rule.Priority != int(original.Priority) { + t.Errorf("Priority: got %d, want %d", rule.Priority, original.Priority) + } + if string(rule.Effect) != original.Effect { + t.Errorf("Effect: got %q, want %q", rule.Effect, original.Effect) + } + + back := ruleToPB(rule) + if back.Id != original.Id { + t.Errorf("roundtrip Id: got %q, want %q", back.Id, original.Id) + } + if back.Priority != original.Priority { + t.Errorf("roundtrip Priority: got %d, want %d", back.Priority, original.Priority) + } + if back.Effect != original.Effect { + t.Errorf("roundtrip Effect: got %q, want %q", back.Effect, original.Effect) + } +} diff --git a/internal/grpcserver/pki.go b/internal/grpcserver/pki.go index 5e5c77b..ce55be8 100644 --- a/internal/grpcserver/pki.go +++ b/internal/grpcserver/pki.go @@ -7,7 +7,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1" + pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v2" "git.wntrmute.dev/kyle/metacrypt/internal/engine" "git.wntrmute.dev/kyle/metacrypt/internal/engine/ca" ) diff --git a/internal/grpcserver/policy.go b/internal/grpcserver/policy.go index 94437cf..83e740d 100644 --- a/internal/grpcserver/policy.go +++ b/internal/grpcserver/policy.go @@ -6,7 +6,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1" + pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v2" "git.wntrmute.dev/kyle/metacrypt/internal/policy" ) diff --git a/internal/grpcserver/server.go b/internal/grpcserver/server.go index ae05b30..85666db 100644 --- a/internal/grpcserver/server.go +++ b/internal/grpcserver/server.go @@ -11,7 +11,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials" - pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1" + pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v2" internacme "git.wntrmute.dev/kyle/metacrypt/internal/acme" "git.wntrmute.dev/kyle/metacrypt/internal/auth" "git.wntrmute.dev/kyle/metacrypt/internal/config" @@ -79,6 +79,7 @@ func (s *GRPCServer) Start() error { pb.RegisterAuthServiceServer(s.srv, &authServer{s: s}) pb.RegisterEngineServiceServer(s.srv, &engineServer{s: s}) pb.RegisterPKIServiceServer(s.srv, &pkiServer{s: s}) + pb.RegisterCAServiceServer(s.srv, &caServer{s: s}) pb.RegisterPolicyServiceServer(s.srv, &policyServer{s: s}) pb.RegisterACMEServiceServer(s.srv, &acmeServer{s: s}) @@ -105,57 +106,77 @@ func (s *GRPCServer) Shutdown() { // 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/Execute": 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, + "/metacrypt.v2.AuthService/Login": true, + "/metacrypt.v2.AuthService/Logout": true, + "/metacrypt.v2.AuthService/TokenInfo": true, + "/metacrypt.v2.EngineService/Mount": true, + "/metacrypt.v2.EngineService/Unmount": true, + "/metacrypt.v2.EngineService/ListMounts": true, + "/metacrypt.v2.PKIService/GetRootCert": true, + "/metacrypt.v2.PKIService/GetChain": true, + "/metacrypt.v2.PKIService/GetIssuerCert": true, + "/metacrypt.v2.CAService/ImportRoot": true, + "/metacrypt.v2.CAService/GetRoot": true, + "/metacrypt.v2.CAService/CreateIssuer": true, + "/metacrypt.v2.CAService/DeleteIssuer": true, + "/metacrypt.v2.CAService/ListIssuers": true, + "/metacrypt.v2.CAService/GetIssuer": true, + "/metacrypt.v2.CAService/GetChain": true, + "/metacrypt.v2.CAService/IssueCert": true, + "/metacrypt.v2.CAService/GetCert": true, + "/metacrypt.v2.CAService/ListCerts": true, + "/metacrypt.v2.CAService/RenewCert": true, + "/metacrypt.v2.PolicyService/CreatePolicy": true, + "/metacrypt.v2.PolicyService/ListPolicies": true, + "/metacrypt.v2.PolicyService/GetPolicy": true, + "/metacrypt.v2.PolicyService/DeletePolicy": true, + "/metacrypt.v2.ACMEService/CreateEAB": true, + "/metacrypt.v2.ACMEService/SetConfig": true, + "/metacrypt.v2.ACMEService/ListAccounts": true, + "/metacrypt.v2.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/Execute": 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, + "/metacrypt.v2.AuthService/Logout": true, + "/metacrypt.v2.AuthService/TokenInfo": true, + "/metacrypt.v2.EngineService/Mount": true, + "/metacrypt.v2.EngineService/Unmount": true, + "/metacrypt.v2.EngineService/ListMounts": true, + "/metacrypt.v2.CAService/ImportRoot": true, + "/metacrypt.v2.CAService/CreateIssuer": true, + "/metacrypt.v2.CAService/DeleteIssuer": true, + "/metacrypt.v2.CAService/ListIssuers": true, + "/metacrypt.v2.CAService/IssueCert": true, + "/metacrypt.v2.CAService/GetCert": true, + "/metacrypt.v2.CAService/ListCerts": true, + "/metacrypt.v2.CAService/RenewCert": true, + "/metacrypt.v2.PolicyService/CreatePolicy": true, + "/metacrypt.v2.PolicyService/ListPolicies": true, + "/metacrypt.v2.PolicyService/GetPolicy": true, + "/metacrypt.v2.PolicyService/DeletePolicy": true, + "/metacrypt.v2.ACMEService/CreateEAB": true, + "/metacrypt.v2.ACMEService/SetConfig": true, + "/metacrypt.v2.ACMEService/ListAccounts": true, + "/metacrypt.v2.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, + "/metacrypt.v2.SystemService/Seal": true, + "/metacrypt.v2.EngineService/Mount": true, + "/metacrypt.v2.EngineService/Unmount": true, + "/metacrypt.v2.CAService/ImportRoot": true, + "/metacrypt.v2.CAService/CreateIssuer": true, + "/metacrypt.v2.CAService/DeleteIssuer": true, + "/metacrypt.v2.PolicyService/CreatePolicy": true, + "/metacrypt.v2.PolicyService/DeletePolicy": true, + "/metacrypt.v2.ACMEService/SetConfig": true, + "/metacrypt.v2.ACMEService/ListAccounts": true, + "/metacrypt.v2.ACMEService/ListOrders": true, } } diff --git a/internal/grpcserver/system.go b/internal/grpcserver/system.go index 282d0c7..a4c4afa 100644 --- a/internal/grpcserver/system.go +++ b/internal/grpcserver/system.go @@ -7,7 +7,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1" + pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v2" "git.wntrmute.dev/kyle/metacrypt/internal/crypto" "git.wntrmute.dev/kyle/metacrypt/internal/seal" ) diff --git a/internal/server/routes.go b/internal/server/routes.go index 50a17cb..c3582ce 100644 --- a/internal/server/routes.go +++ b/internal/server/routes.go @@ -96,15 +96,19 @@ func (s *Server) handleUnseal(w http.ResponseWriter, r *http.Request) { if err := s.seal.Unseal([]byte(req.Password)); err != nil { if errors.Is(err, seal.ErrNotInitialized) { + s.logger.Warn("unseal attempt on uninitialized service", "remote_addr", r.RemoteAddr) http.Error(w, `{"error":"not initialized"}`, http.StatusPreconditionFailed) } else if errors.Is(err, seal.ErrInvalidPassword) { + s.logger.Warn("unseal attempt with invalid password", "remote_addr", r.RemoteAddr) http.Error(w, `{"error":"invalid password"}`, http.StatusUnauthorized) } else if errors.Is(err, seal.ErrRateLimited) { + s.logger.Warn("unseal attempt rate limited", "remote_addr", r.RemoteAddr) http.Error(w, `{"error":"too many attempts, try again later"}`, http.StatusTooManyRequests) } else if errors.Is(err, seal.ErrNotSealed) { + s.logger.Warn("unseal attempt on already-unsealed service", "remote_addr", r.RemoteAddr) http.Error(w, `{"error":"already unsealed"}`, http.StatusConflict) } else { - s.logger.Error("unseal failed", "error", err) + s.logger.Error("unseal failed", "remote_addr", r.RemoteAddr, "error", err) http.Error(w, `{"error":"unseal failed"}`, http.StatusInternalServerError) } return @@ -116,6 +120,7 @@ func (s *Server) handleUnseal(w http.ResponseWriter, r *http.Request) { return } + s.logger.Info("service unsealed", "remote_addr", r.RemoteAddr) writeJSON(w, http.StatusOK, map[string]interface{}{ "state": s.seal.State().String(), }) diff --git a/internal/webserver/client.go b/internal/webserver/client.go index cc3e78e..7e9969a 100644 --- a/internal/webserver/client.go +++ b/internal/webserver/client.go @@ -12,7 +12,7 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" - pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1" + pb "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v2" ) // VaultClient wraps the gRPC stubs for communicating with the vault. @@ -22,6 +22,7 @@ type VaultClient struct { auth pb.AuthServiceClient engine pb.EngineServiceClient pki pb.PKIServiceClient + ca pb.CAServiceClient } // NewVaultClient dials the vault gRPC server and returns a client. @@ -58,6 +59,7 @@ func NewVaultClient(addr, caCertPath string, logger *slog.Logger) (*VaultClient, auth: pb.NewAuthServiceClient(conn), engine: pb.NewEngineServiceClient(conn), pki: pb.NewPKIServiceClient(conn), + ca: pb.NewCAServiceClient(conn), }, nil } @@ -156,39 +158,16 @@ func (c *VaultClient) Mount(ctx context.Context, token, name, engineType string, Type: engineType, } if len(config) > 0 { - s, err := structFromMap(config) - if err != nil { - return fmt.Errorf("webserver: encode mount config: %w", err) + cfg := make(map[string]string, len(config)) + for k, v := range config { + cfg[k] = fmt.Sprintf("%v", v) } - req.Config = s + req.Config = cfg } _, 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.ExecuteRequest{ - 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.Execute(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}) @@ -206,3 +185,126 @@ func (c *VaultClient) GetIssuerCert(ctx context.Context, mount, issuer string) ( } return resp.CertPem, nil } + +// ImportRoot imports an existing root CA certificate and key into the given mount. +func (c *VaultClient) ImportRoot(ctx context.Context, token, mount, certPEM, keyPEM string) error { + _, err := c.ca.ImportRoot(withToken(ctx, token), &pb.ImportRootRequest{ + Mount: mount, + CertPem: []byte(certPEM), + KeyPem: []byte(keyPEM), + }) + return err +} + +// CreateIssuerRequest holds parameters for creating an intermediate CA issuer. +type CreateIssuerRequest struct { + Mount string + Name string + KeyAlgorithm string + KeySize int32 + Expiry string + MaxTTL string +} + +// CreateIssuer creates a new intermediate CA issuer on the given mount. +func (c *VaultClient) CreateIssuer(ctx context.Context, token string, req CreateIssuerRequest) error { + _, err := c.ca.CreateIssuer(withToken(ctx, token), &pb.CreateIssuerRequest{ + Mount: req.Mount, + Name: req.Name, + KeyAlgorithm: req.KeyAlgorithm, + KeySize: req.KeySize, + Expiry: req.Expiry, + MaxTtl: req.MaxTTL, + }) + return err +} + +// ListIssuers returns the names of all issuers for the given mount. +func (c *VaultClient) ListIssuers(ctx context.Context, token, mount string) ([]string, error) { + resp, err := c.ca.ListIssuers(withToken(ctx, token), &pb.ListIssuersRequest{Mount: mount}) + if err != nil { + return nil, err + } + return resp.Issuers, nil +} + +// IssueCertRequest holds parameters for issuing a leaf certificate. +type IssueCertRequest struct { + Mount string + Issuer string + Profile string + CommonName string + DNSNames []string + IPAddresses []string + TTL string + KeyUsages []string + ExtKeyUsages []string +} + +// IssuedCert holds the result of a certificate issuance. +type IssuedCert struct { + Serial string + CertPEM string + KeyPEM string + ChainPEM string + ExpiresAt string +} + +// IssueCert issues a new leaf certificate from the named issuer. +func (c *VaultClient) IssueCert(ctx context.Context, token string, req IssueCertRequest) (*IssuedCert, error) { + resp, err := c.ca.IssueCert(withToken(ctx, token), &pb.IssueCertRequest{ + Mount: req.Mount, + Issuer: req.Issuer, + Profile: req.Profile, + CommonName: req.CommonName, + DnsNames: req.DNSNames, + IpAddresses: req.IPAddresses, + Ttl: req.TTL, + KeyUsages: req.KeyUsages, + ExtKeyUsages: req.ExtKeyUsages, + }) + if err != nil { + return nil, err + } + issued := &IssuedCert{ + Serial: resp.Serial, + CertPEM: string(resp.CertPem), + KeyPEM: string(resp.KeyPem), + ChainPEM: string(resp.ChainPem), + } + if resp.ExpiresAt != nil { + issued.ExpiresAt = resp.ExpiresAt.AsTime().Format("2006-01-02T15:04:05Z") + } + return issued, nil +} + +// CertSummary holds lightweight certificate metadata for list views. +type CertSummary struct { + Serial string + Issuer string + CommonName string + Profile string + ExpiresAt string +} + +// ListCerts returns all certificate summaries for the given mount. +func (c *VaultClient) ListCerts(ctx context.Context, token, mount string) ([]CertSummary, error) { + resp, err := c.ca.ListCerts(withToken(ctx, token), &pb.ListCertsRequest{Mount: mount}) + if err != nil { + return nil, err + } + certs := make([]CertSummary, 0, len(resp.Certs)) + for _, s := range resp.Certs { + cs := CertSummary{ + Serial: s.Serial, + Issuer: s.Issuer, + CommonName: s.CommonName, + Profile: s.Profile, + } + if s.ExpiresAt != nil { + cs.ExpiresAt = s.ExpiresAt.AsTime().Format("2006-01-02T15:04:05Z") + } + certs = append(certs, cs) + } + return certs, nil +} diff --git a/internal/webserver/routes.go b/internal/webserver/routes.go index fe5af22..e74fc8c 100644 --- a/internal/webserver/routes.go +++ b/internal/webserver/routes.go @@ -280,8 +280,8 @@ func (ws *WebServer) handlePKI(w http.ResponseWriter, r *http.Request) { } } - if resp, err := ws.vault.EngineRequest(r.Context(), token, mountName, "list-issuers", nil); err == nil { - data["Issuers"] = resp["issuers"] + if issuers, err := ws.vault.ListIssuers(r.Context(), token, mountName); err == nil { + data["Issuers"] = issuers } ws.renderTemplate(w, "pki.html", data) @@ -329,11 +329,7 @@ func (ws *WebServer) handleImportRoot(w http.ResponseWriter, r *http.Request) { return } - _, err = ws.vault.EngineRequest(r.Context(), token, mountName, "import-root", map[string]interface{}{ - "cert_pem": certPEM, - "key_pem": keyPEM, - }) - if err != nil { + if err = ws.vault.ImportRoot(r.Context(), token, mountName, certPEM, keyPEM); err != nil { ws.renderPKIWithError(w, r, mountName, info, grpcMessage(err)) return } @@ -362,25 +358,27 @@ func (ws *WebServer) handleCreateIssuer(w http.ResponseWriter, r *http.Request) return } - reqData := map[string]interface{}{"name": name} + issuerReq := CreateIssuerRequest{ + Mount: mountName, + Name: name, + } if v := r.FormValue("expiry"); v != "" { - reqData["expiry"] = v + issuerReq.Expiry = v } if v := r.FormValue("max_ttl"); v != "" { - reqData["max_ttl"] = v + issuerReq.MaxTTL = v } if v := r.FormValue("key_algorithm"); v != "" { - reqData["key_algorithm"] = v + issuerReq.KeyAlgorithm = v } if v := r.FormValue("key_size"); v != "" { - var size float64 - if _, err := fmt.Sscanf(v, "%f", &size); err == nil { - reqData["key_size"] = size + var size int32 + if _, err := fmt.Sscanf(v, "%d", &size); err == nil { + issuerReq.KeySize = size } } - _, err = ws.vault.EngineRequest(r.Context(), token, mountName, "create-issuer", reqData) - if err != nil { + if err = ws.vault.CreateIssuer(r.Context(), token, issuerReq); err != nil { ws.renderPKIWithError(w, r, mountName, info, grpcMessage(err)) return } @@ -419,7 +417,7 @@ func (ws *WebServer) handleIssuerDetail(w http.ResponseWriter, r *http.Request) issuerName := chi.URLParam(r, "issuer") - resp, err := ws.vault.EngineRequest(r.Context(), token, mountName, "list-certs", nil) + allCerts, err := ws.vault.ListCerts(r.Context(), token, mountName) if err != nil { http.Error(w, "failed to list certificates", http.StatusInternalServerError) return @@ -431,34 +429,22 @@ func (ws *WebServer) handleIssuerDetail(w http.ResponseWriter, r *http.Request) sortBy = "cn" } - var certs []map[string]interface{} - if raw, ok := resp["certs"]; ok { - if list, ok := raw.([]interface{}); ok { - for _, item := range list { - if m, ok := item.(map[string]interface{}); ok { - issuer, _ := m["issuer"].(string) - if issuer != issuerName { - continue - } - if nameFilter != "" { - cn, _ := m["cn"].(string) - if !strings.Contains(strings.ToLower(cn), nameFilter) { - continue - } - } - certs = append(certs, m) - } - } + var certs []CertSummary + for _, cs := range allCerts { + if cs.Issuer != issuerName { + continue } + if nameFilter != "" && !strings.Contains(strings.ToLower(cs.CommonName), strings.ToLower(nameFilter)) { + continue + } + certs = append(certs, cs) } // Sort: by expiry date or by common name (default). if sortBy == "expiry" { for i := 1; i < len(certs); i++ { for j := i; j > 0; j-- { - a, _ := certs[j-1]["expires_at"].(string) - b, _ := certs[j]["expires_at"].(string) - if a > b { + if certs[j-1].ExpiresAt > certs[j].ExpiresAt { certs[j-1], certs[j] = certs[j], certs[j-1] } } @@ -466,9 +452,7 @@ func (ws *WebServer) handleIssuerDetail(w http.ResponseWriter, r *http.Request) } else { for i := 1; i < len(certs); i++ { for j := i; j > 0; j-- { - a, _ := certs[j-1]["cn"].(string) - b, _ := certs[j]["cn"].(string) - if strings.ToLower(a) > strings.ToLower(b) { + if strings.ToLower(certs[j-1].CommonName) > strings.ToLower(certs[j].CommonName) { certs[j-1], certs[j] = certs[j], certs[j-1] } } @@ -512,24 +496,31 @@ func (ws *WebServer) handleIssueCert(w http.ResponseWriter, r *http.Request) { return } - reqData := map[string]interface{}{ - "common_name": commonName, - "issuer": issuer, + certReq := IssueCertRequest{ + Mount: mountName, + Issuer: issuer, + CommonName: commonName, } if v := r.FormValue("profile"); v != "" { - reqData["profile"] = v + certReq.Profile = v } if v := r.FormValue("ttl"); v != "" { - reqData["ttl"] = v + certReq.TTL = v } if lines := splitLines(r.FormValue("dns_names")); len(lines) > 0 { - reqData["dns_names"] = lines + for _, l := range lines { + certReq.DNSNames = append(certReq.DNSNames, l.(string)) + } } if lines := splitLines(r.FormValue("ip_addresses")); len(lines) > 0 { - reqData["ip_addresses"] = lines + for _, l := range lines { + certReq.IPAddresses = append(certReq.IPAddresses, l.(string)) + } } + certReq.KeyUsages = r.Form["key_usages"] + certReq.ExtKeyUsages = r.Form["ext_key_usages"] - resp, err := ws.vault.EngineRequest(r.Context(), token, mountName, "issue", reqData) + issuedCert, err := ws.vault.IssueCert(r.Context(), token, certReq) if err != nil { ws.renderPKIWithError(w, r, mountName, info, grpcMessage(err)) return @@ -537,10 +528,10 @@ func (ws *WebServer) handleIssueCert(w http.ResponseWriter, r *http.Request) { // Re-render the PKI page with the issued certificate displayed. data := map[string]interface{}{ - "Username": info.Username, - "IsAdmin": info.IsAdmin, - "MountName": mountName, - "IssuedCert": resp, + "Username": info.Username, + "IsAdmin": info.IsAdmin, + "MountName": mountName, + "IssuedCert": issuedCert, } if rootPEM, err := ws.vault.GetRootCert(r.Context(), mountName); err == nil && len(rootPEM) > 0 { if cert, err := parsePEMCert(rootPEM); err == nil { @@ -552,8 +543,8 @@ func (ws *WebServer) handleIssueCert(w http.ResponseWriter, r *http.Request) { data["HasRoot"] = true } } - if issuerResp, err := ws.vault.EngineRequest(r.Context(), token, mountName, "list-issuers", nil); err == nil { - data["Issuers"] = issuerResp["issuers"] + if issuers, err := ws.vault.ListIssuers(r.Context(), token, mountName); err == nil { + data["Issuers"] = issuers } ws.renderTemplate(w, "pki.html", data) } @@ -577,8 +568,8 @@ func (ws *WebServer) renderPKIWithError(w http.ResponseWriter, r *http.Request, data["HasRoot"] = true } } - if resp, err := ws.vault.EngineRequest(r.Context(), token, mountName, "list-issuers", nil); err == nil { - data["Issuers"] = resp["issuers"] + if issuers, err := ws.vault.ListIssuers(r.Context(), token, mountName); err == nil { + data["Issuers"] = issuers } ws.renderTemplate(w, "pki.html", data) diff --git a/internal/webserver/util.go b/internal/webserver/util.go index 7270326..1068f39 100644 --- a/internal/webserver/util.go +++ b/internal/webserver/util.go @@ -5,8 +5,6 @@ import ( "crypto/x509" "encoding/pem" "errors" - - "google.golang.org/protobuf/types/known/structpb" ) type contextKey int @@ -22,11 +20,6 @@ func tokenInfoFromContext(ctx context.Context) *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) diff --git a/web/static/style.css b/web/static/style.css index 00a7809..e657690 100644 --- a/web/static/style.css +++ b/web/static/style.css @@ -1,31 +1,456 @@ -* { margin: 0; padding: 0; box-sizing: border-box; } -body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f5f5f5; color: #333; line-height: 1.6; } -.container { max-width: 800px; margin: 0 auto; padding: 2rem; } -header h1 { margin-bottom: 2rem; } -header h1 a { color: #333; text-decoration: none; } -main { background: #fff; border-radius: 8px; padding: 2rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1); } -h2 { margin-bottom: 1rem; color: #222; } -h3 { margin: 1.5rem 0 0.5rem; color: #444; } -p { margin-bottom: 1rem; } +/* Metacrypt — Nord dark theme */ + +/* =========================== + Colour tokens (Nord palette) + =========================== */ +:root { + /* Polar Night */ + --n0: #2E3440; + --n1: #3B4252; + --n2: #434C5E; + --n3: #4C566A; + /* Snow Storm */ + --s0: #D8DEE9; + --s1: #E5E9F0; + --s2: #ECEFF4; + /* Frost */ + --f0: #8FBCBB; + --f1: #88C0D0; + --f2: #81A1C1; + --f3: #5E81AC; + /* Aurora */ + --red: #BF616A; + --orange: #D08770; + --yellow: #EBCB8B; + --green: #A3BE8C; + --green-dark: #4C7A4A; + --purple: #B48EAD; +} + +/* =========================== + Reset + =========================== */ +*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } +html { font-size: 16px; } + +/* =========================== + Base + =========================== */ +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif; + background: var(--n0); + color: var(--s0); + line-height: 1.6; + min-height: 100vh; +} +a { color: var(--f1); text-decoration: none; } +a:hover { color: var(--f0); text-decoration: underline; } +p { margin-bottom: 0.875rem; } +h2 { font-size: 1.375rem; font-weight: 600; color: var(--s2); margin-bottom: 0.25rem; } +h3 { font-size: 1.0625rem; font-weight: 600; color: var(--s1); margin: 0; } +code { + font-family: "SF Mono", "Cascadia Code", "Fira Code", Consolas, monospace; + font-size: 0.8125rem; + color: var(--f0); + background: var(--n2); + padding: 0.125rem 0.375rem; + border-radius: 3px; +} +small { font-size: 0.8125rem; color: var(--s0); } + +/* =========================== + Top navigation + =========================== */ +.topnav { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 2rem; + height: 52px; + background: var(--n1); + border-bottom: 1px solid var(--n3); + position: sticky; + top: 0; + z-index: 100; +} +.topnav-brand { + font-size: 1rem; + font-weight: 700; + color: var(--s2); + text-decoration: none; + letter-spacing: 0.04em; +} +.topnav-brand:hover { color: var(--f1); text-decoration: none; } +.topnav-right { + display: flex; + align-items: center; + gap: 0.75rem; +} +.topnav-user { + font-size: 0.875rem; + color: var(--s1); +} + +/* =========================== + Page containers + =========================== */ +.page-container { + max-width: 1100px; + margin: 0 auto; + padding: 2rem; +} +.auth-container { + max-width: 420px; + margin: 5rem auto 2rem; + padding: 0 1rem; +} + +/* =========================== + Page header + =========================== */ +.page-header { + margin-bottom: 1.5rem; + padding-bottom: 1rem; + border-bottom: 1px solid var(--n2); +} +.page-header h2 { margin-bottom: 0; } +.page-meta { + margin-top: 0.375rem; + display: flex; + align-items: center; + gap: 0.75rem; + font-size: 0.8125rem; + color: var(--n3); +} +.page-meta a { color: var(--f2); font-size: 0.8125rem; } +.page-meta a:hover { color: var(--f1); } + +/* =========================== + Auth pages + =========================== */ +.auth-header { + text-align: center; + margin-bottom: 1.75rem; +} +.auth-header .brand { + font-size: 1.5rem; + font-weight: 700; + color: var(--s2); + letter-spacing: 0.04em; +} +.auth-header .tagline { + font-size: 0.6875rem; + color: var(--f2); + text-transform: uppercase; + letter-spacing: 0.12em; + margin-top: 0.25rem; +} + +/* =========================== + Cards + =========================== */ +.card { + background: var(--n1); + border: 1px solid var(--n3); + border-radius: 6px; + padding: 1.5rem; + margin-bottom: 1.25rem; +} +.card:last-child { margin-bottom: 0; } +.card-title { + font-size: 0.6875rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.09em; + color: var(--f2); + margin-bottom: 1rem; + padding-bottom: 0.625rem; + border-bottom: 1px solid var(--n2); +} +.card p:last-child { margin-bottom: 0; } + +/* =========================== + State chip + =========================== */ +.state-chip { + display: inline-flex; + align-items: center; + gap: 0.4rem; + font-size: 0.8125rem; + color: var(--s0); +} +.state-chip::before { + content: ''; + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--n3); + flex-shrink: 0; +} +.state-chip.state-unsealed::before { + background: var(--green); + box-shadow: 0 0 5px rgba(163, 190, 140, 0.55); +} +.state-chip.state-sealed::before { background: var(--red); } + +/* =========================== + Badges + =========================== */ +.badge { + display: inline-block; + padding: 0.125rem 0.5rem; + border-radius: 3px; + font-size: 0.6875rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.06em; + background: rgba(94, 129, 172, 0.2); + color: var(--f1); + border: 1px solid rgba(94, 129, 172, 0.35); +} +.badge-danger { + background: rgba(191, 97, 106, 0.15); + color: #e07c82; + border-color: rgba(191, 97, 106, 0.35); +} + +/* =========================== + Alerts + =========================== */ +.error { + background: rgba(191, 97, 106, 0.12); + color: #e07c82; + border: 1px solid rgba(191, 97, 106, 0.3); + padding: 0.75rem 1rem; + border-radius: 4px; + margin-bottom: 1rem; + font-size: 0.875rem; +} +.success { + background: rgba(163, 190, 140, 0.1); + border: 1px solid rgba(163, 190, 140, 0.3); + border-radius: 4px; + padding: 1rem; + margin-bottom: 1rem; +} +.success p { color: var(--green); } + +/* =========================== + Buttons + =========================== */ +button, .btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.375rem; + padding: 0.5rem 1.25rem; + font-size: 0.875rem; + font-weight: 600; + font-family: inherit; + border: 1px solid var(--f3); + border-radius: 4px; + cursor: pointer; + text-decoration: none; + white-space: nowrap; + transition: background 0.12s, border-color 0.12s, color 0.12s; + line-height: 1.4; + background: var(--f3); + color: var(--s2); +} +button:hover, .btn:hover { + background: var(--f2); + border-color: var(--f2); + text-decoration: none; + color: var(--s2); +} +.btn-danger { + background: var(--red); + color: var(--s2); + border-color: var(--red); +} +.btn-danger:hover { + background: #a8535b; + border-color: #a8535b; + color: var(--s2); +} +.btn-ghost { + background: transparent; + color: var(--s0); + border-color: var(--n3); +} +.btn-ghost:hover { + background: var(--n2); + color: var(--s1); + border-color: var(--n3); + text-decoration: none; +} +.btn-sm { + padding: 0.3125rem 0.875rem; + font-size: 0.8125rem; +} + +/* =========================== + Forms + =========================== */ .form-group { margin-bottom: 1rem; } -.form-group label { display: block; margin-bottom: 0.25rem; font-weight: 600; } -.form-group input { width: 100%; padding: 0.5rem; border: 1px solid #ccc; border-radius: 4px; font-size: 1rem; } -button { padding: 0.5rem 1.5rem; background: #2563eb; color: #fff; border: none; border-radius: 4px; font-size: 1rem; cursor: pointer; } -button:hover { background: #1d4ed8; } -.error { background: #fee2e2; color: #991b1b; padding: 0.75rem; border-radius: 4px; margin-bottom: 1rem; } -.badge { background: #dbeafe; color: #1e40af; padding: 0.125rem 0.5rem; border-radius: 4px; font-size: 0.875rem; } -.status-bar { display: flex; gap: 1rem; align-items: center; padding: 0.75rem; background: #f9fafb; border-radius: 4px; margin-bottom: 1.5rem; flex-wrap: wrap; } -.status-bar a { margin-left: auto; color: #2563eb; } -table { width: 100%; border-collapse: collapse; margin: 0.5rem 0; } -th, td { text-align: left; padding: 0.5rem; border-bottom: 1px solid #e5e7eb; } -th { font-weight: 600; background: #f9fafb; } -.admin-actions { margin-top: 0.5rem; } -.admin-actions button { background: #dc2626; } -.admin-actions button:hover { background: #b91c1c; } -.badge-danger { background: #fee2e2; color: #991b1b; } -.form-group textarea, .pem-input { width: 100%; padding: 0.5rem; border: 1px solid #ccc; border-radius: 4px; font-family: monospace; font-size: 0.875rem; resize: vertical; } -.form-group input[type="file"] { padding: 0.25rem 0; border: none; } +.form-group label { + display: block; + font-size: 0.6875rem; + font-weight: 700; + color: var(--s0); + margin-bottom: 0.375rem; + text-transform: uppercase; + letter-spacing: 0.06em; +} +.form-group input, +.form-group select, +.form-group textarea { + width: 100%; + padding: 0.5rem 0.75rem; + background: var(--n0); + border: 1px solid var(--n3); + border-radius: 4px; + color: var(--s1); + font-size: 0.9375rem; + font-family: inherit; + transition: border-color 0.12s, box-shadow 0.12s; + -webkit-appearance: none; + appearance: none; +} +.form-group input:focus, +.form-group select:focus, +.form-group textarea:focus { + outline: none; + border-color: var(--f3); + box-shadow: 0 0 0 3px rgba(94, 129, 172, 0.2); +} +.form-group input::placeholder, +.form-group textarea::placeholder { color: var(--n3); } +.form-group input[type="file"] { + padding: 0.375rem 0.5rem; + font-size: 0.875rem; + color: var(--s0); + cursor: pointer; + border-style: dashed; +} +.form-group select { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2381A1C1' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 0.75rem center; + padding-right: 2.25rem; + cursor: pointer; +} .form-row { display: flex; gap: 1rem; } -.form-row .form-group { flex: 1; } +.form-row .form-group { flex: 1; min-width: 0; } +.form-actions { margin-top: 0.25rem; } +.pem-input, +.form-group textarea.pem-input { + font-family: "SF Mono", "Cascadia Code", "Fira Code", Consolas, monospace; + font-size: 0.8125rem; + resize: vertical; +} + +/* =========================== + Details / Summary + =========================== */ details { margin: 0.75rem 0; } -details summary { cursor: pointer; color: #2563eb; font-weight: 600; margin-bottom: 0.5rem; } +details summary { + cursor: pointer; + color: var(--f2); + font-size: 0.875rem; + font-weight: 600; + padding: 0.375rem 0; + user-select: none; + list-style: none; +} +details summary::-webkit-details-marker { display: none; } +details summary::before { + content: '▸ '; + color: var(--n3); + font-size: 0.75rem; +} +details[open] summary::before { content: '▾ '; } +details summary:hover { color: var(--f1); } +details[open] > summary { margin-bottom: 0.75rem; } +details > :not(summary):first-of-type { margin-top: 0.25rem; } + +/* =========================== + Tables + =========================== */ +.table-wrapper { overflow-x: auto; } +table { width: 100%; border-collapse: collapse; } +th { + text-align: left; + padding: 0.5rem 0.875rem; + font-size: 0.6875rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.07em; + color: var(--f2); + border-bottom: 1px solid var(--n3); + white-space: nowrap; +} +td { + text-align: left; + padding: 0.625rem 0.875rem; + font-size: 0.875rem; + color: var(--s0); + border-bottom: 1px solid var(--n2); +} +tbody tr:last-child td { border-bottom: none; } +tbody tr:hover td { background: rgba(76, 86, 106, 0.25); } + +/* Key–value table (cert info) */ +.kv-table { border-collapse: collapse; width: 100%; } +.kv-table th { + width: 140px; + font-size: 0.75rem; + font-weight: 700; + color: var(--f2); + text-transform: uppercase; + letter-spacing: 0.05em; + padding: 0.375rem 1rem 0.375rem 0; + border-bottom: none; + vertical-align: top; + white-space: nowrap; +} +.kv-table td { + font-size: 0.9375rem; + color: var(--s1); + padding: 0.375rem 0; + border-bottom: none; +} +.kv-table tbody tr:hover td { background: transparent; } + +.checkbox-group { + display: flex; + flex-direction: column; + gap: 0.375rem; + margin-top: 0.25rem; +} +.form-group .checkbox-label { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.9375rem; + font-weight: normal; + text-transform: none; + letter-spacing: 0; + color: var(--s1); + cursor: pointer; +} +.form-group .checkbox-label input[type="checkbox"] { + width: 1rem; + height: 1rem; + padding: 0; + cursor: pointer; + flex-shrink: 0; + accent-color: var(--green-dark); +} +.form-group .checkbox-label input[type="checkbox"]:checked { + outline: 2px solid var(--green-dark); + outline-offset: 1px; +} +.form-group .checkbox-label:has(input[type="checkbox"]:checked) { + color: var(--green); +} diff --git a/web/templates/dashboard.html b/web/templates/dashboard.html index a870d7f..1b45e22 100644 --- a/web/templates/dashboard.html +++ b/web/templates/dashboard.html @@ -1,63 +1,85 @@ {{define "title"}} - Dashboard{{end}} {{define "content"}} -

Dashboard

-
- Logged in as {{.Username}} - {{if .IsAdmin}}Admin{{end}} - State: {{.State}} - v{{.Version}} - Logout + -

Engine Mounts

-{{if .Mounts}} - - - - {{range .Mounts}} - - - - - +
+
Engine Mounts
+ {{if .Mounts}} +
+
NameTypePath
{{if eq (printf "%s" .Type) "ca"}}{{.Name}}{{else}}{{.Name}}{{end}}{{.Type}}{{.MountPath}}
+ + + + + + + + + {{range .Mounts}} + + + + + + {{end}} + +
NameTypePath
+ {{if eq (printf "%s" .Type) "ca"}} + {{.Name}} + {{else}} + {{.Name}} + {{end}} + {{.Type}}{{.MountPath}}
+
+ {{else}} +

No engines mounted.

{{end}} - - -{{else}} -

No engines mounted.

-{{end}} + {{if .IsAdmin}} -

Mount CA Engine

-{{if .MountError}}
{{.MountError}}
{{end}} -
-
-
- - -
-
- - -
-
+
+
Mount Engine
+ {{if .MountError}}
{{.MountError}}
{{end}}
- Import existing root CA (optional) -
- - -
-
- - -
+ Mount a CA engine + +
+
+ + +
+
+ + +
+
+
+ Import existing root CA (optional) +
+ + +
+
+ + +
+
+
+ +
+
- - +
-

Admin Actions

-
- +
+
Administration
+

Sealing the service will require the seal password to restore access.

+
{{end}} {{end}} diff --git a/web/templates/init.html b/web/templates/init.html index cad9281..461fa78 100644 --- a/web/templates/init.html +++ b/web/templates/init.html @@ -1,17 +1,26 @@ {{define "title"}} - Initialize{{end}} +{{define "container-class"}}auth-container{{end}} {{define "content"}} -

Initialize Metacrypt

-

Set the seal password for this Metacrypt instance. This password will be required to unseal the service after each restart.

-{{if .Error}}
{{.Error}}
{{end}} -
-
- - -
-
- - -
- -
+
+
Metacrypt
+
Cryptographic Services
+
+
+
Initialize
+

Set the seal password for this instance. This password will be required to unseal the service after each restart.

+ {{if .Error}}
{{.Error}}
{{end}} +
+
+ + +
+
+ + +
+
+ +
+
+
{{end}} diff --git a/web/templates/initializing.html b/web/templates/initializing.html index 94825ab..5837a25 100644 --- a/web/templates/initializing.html +++ b/web/templates/initializing.html @@ -1,9 +1,16 @@ {{define "title"}} - Initializing{{end}} +{{define "container-class"}}auth-container{{end}} {{define "content"}} -

Initializing...

-

Metacrypt is being initialized. Please wait.

-
-

Checking status...

+
+
Metacrypt
+
Cryptographic Services
+
+
+
Initializing
+

Metacrypt is being initialized. This will only take a moment.

+
+

Waiting for service to come online…

+
{{end}} diff --git a/web/templates/issuer_detail.html b/web/templates/issuer_detail.html index 4872118..8dfbb95 100644 --- a/web/templates/issuer_detail.html +++ b/web/templates/issuer_detail.html @@ -1,60 +1,63 @@ {{define "title"}} - Issuer: {{.IssuerName}}{{end}} {{define "content"}} -

Issuer: {{.IssuerName}}

- -

- ← PKI: {{.MountName}} -  —  - Download Issuer Cert (PEM) -

- -

Certificates

- -
-
-
- - -
-
- - -
-
- -
+ -{{if .Certs}} - - - - - - - - - - - - - {{range .Certs}} - - - - - - - - +
+
Certificates
+
+
+
+ + +
+
+ + +
+
+ +
+
+ + {{if .Certs}} +
+
Common NameProfileSerialIssued ByIssued AtExpires At
{{index . "cn"}}{{index . "profile"}}{{index . "serial"}}{{index . "issued_by"}}{{index . "issued_at"}}{{index . "expires_at"}}
+ + + + + + + + + + + + {{range .Certs}} + + + + + + + + + {{end}} + +
Common NameProfileSerialIssued ByIssued AtExpires At
{{index . "cn"}}{{index . "profile"}}{{index . "serial"}}{{index . "issued_by"}}{{index . "issued_at"}}{{index . "expires_at"}}
+
+ {{else}} +

No certificates found{{if .NameFilter}} matching “{{.NameFilter}}”{{end}}.

{{end}} - - -{{else}} -

No certificates found{{if .NameFilter}} matching “{{.NameFilter}}”{{end}}.

-{{end}} +
{{end}} diff --git a/web/templates/layout.html b/web/templates/layout.html index 9274807..9d17b6a 100644 --- a/web/templates/layout.html +++ b/web/templates/layout.html @@ -8,13 +8,18 @@ -
-
-

Metacrypt

-
-
- {{template "content" .}} -
+ +
+ {{template "content" .}}
{{end}} diff --git a/web/templates/login.html b/web/templates/login.html index c3bb77b..e3291cb 100644 --- a/web/templates/login.html +++ b/web/templates/login.html @@ -1,21 +1,30 @@ {{define "title"}} - Login{{end}} +{{define "container-class"}}auth-container{{end}} {{define "content"}} -

Login

-

Authenticate with your MCIAS credentials.

-{{if .Error}}
{{.Error}}
{{end}} -
-
- - -
-
- - -
-
- - -
- -
+
+
Metacrypt
+
Cryptographic Services
+
+
+
Sign In
+

Authenticate with your MCIAS credentials.

+ {{if .Error}}
{{.Error}}
{{end}} +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
{{end}} diff --git a/web/templates/pki.html b/web/templates/pki.html index 4e8f187..b06ee46 100644 --- a/web/templates/pki.html +++ b/web/templates/pki.html @@ -1,82 +1,115 @@ {{define "title"}} - PKI: {{.MountName}}{{end}} {{define "content"}} -

PKI Engine: {{.MountName}}

+ -

← Dashboard

+{{if .Error}}
{{.Error}}
{{end}} -{{if .Error}} -
{{.Error}}
-{{end}} - -

Root CA

-{{if .HasRoot}} - - - - - - - - -
Common Name{{.RootCN}}
Organization{{.RootOrg}}
Valid From{{.RootNotBefore}}
Valid Until - {{.RootNotAfter}} - {{if .RootExpired}} Expired{{end}} -
-

- Download Root CA (PEM) -

-{{else}} -

No root CA configured.

-{{end}} +
+
Root CA
+ {{if .HasRoot}} + + + + + + + + + + +
Common Name{{.RootCN}}
Organization{{.RootOrg}}
Valid From{{.RootNotBefore}}
Valid Until + {{.RootNotAfter}} + {{if .RootExpired}} Expired{{end}} +
+

+ Download Root CA (PEM) +

+ {{else}} +

No root CA configured.

+ {{end}} +
{{if .IsAdmin}} {{if or (not .HasRoot) .RootExpired}} -

Import Root CA

-

{{if .RootExpired}}The current root CA has expired. Import a new one.{{else}}No root CA is present. Import one to get started.{{end}}

-
-
- - -
-
- - -
-
- - -
-
- - -
- -
+
+
Import Root CA
+

{{if .RootExpired}}The current root CA has expired. Import a new one to continue issuing certificates.{{else}}No root CA is present. Import one to get started.{{end}}

+
+
+
+ + +
+
+ + +
+
+
+ Or paste PEM directly +
+ + +
+
+ + +
+
+
+ +
+
+
{{end}} {{end}} -

Issuers

-{{if .Issuers}} - - - - {{range .Issuers}} - - - - +
+
Issuers
+ {{if .Issuers}} +
+
NameActions
{{.}}Download Cert (PEM)
+ + + + + + + + {{range .Issuers}} + + + + + {{end}} + +
NameActions
{{.}}Download Cert (PEM)
+
+ {{else}} +

No issuers configured.

{{end}} - - -{{else}} -

No issuers configured.

-{{end}} +
{{if and .HasRoot .Issuers}} -

Issue Certificate

-{{if .IssuedCert}} -
-

Certificate issued successfully.

+
+
Issue Certificate
+ {{if .IssuedCert}} +
+

Certificate issued successfully.

+
+
+ + +
+
+ + +
@@ -89,89 +122,122 @@
-

Serial: {{index .IssuedCert "serial"}} — Expires: {{index .IssuedCert "expires_at"}}

-
-{{else}} -
-
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
-
- SANs + {{else}} +
- - + +
- - + +
-
- -
-{{end}} +
+
+ + +
+
+ + +
+
+
+ Subject Alternative Names +
+
+ + +
+
+ + +
+
+
+
+ Key Usages +
+
+ +
+ + + + + + + +
+
+
+ +
+ + + + + + +
+
+
+
+
+ +
+ + {{end}} +
{{end}} {{if .IsAdmin}} {{if .HasRoot}} -

Create Issuer

-{{if .IssuerError}}
{{.IssuerError}}
{{end}} -
-
-
- - -
-
- - -
-
-
- Advanced options +
+
Create Issuer
+ {{if .IssuerError}}
{{.IssuerError}}
{{end}} +
- - + +
- - + +
-
- - +
+ Advanced options +
+
+ + +
+
+ + +
+
+
+ + +
+
+
+
-
- -
+ + {{end}} {{end}} {{end}} diff --git a/web/templates/unseal.html b/web/templates/unseal.html index f365c98..08f02ea 100644 --- a/web/templates/unseal.html +++ b/web/templates/unseal.html @@ -1,13 +1,22 @@ {{define "title"}} - Unseal{{end}} +{{define "container-class"}}auth-container{{end}} {{define "content"}} -

Unseal Metacrypt

-

The service is sealed. Enter the seal password to unseal.

-{{if .Error}}
{{.Error}}
{{end}} -
-
- - -
- -
+
+
Metacrypt
+
Cryptographic Services
+
+
+
Unseal
+

The service is sealed. Enter the seal password to restore access.

+ {{if .Error}}
{{.Error}}
{{end}} +
+
+ + +
+
+ +
+
+
{{end}}