mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:47:32 +00:00
feat: exchange gRPC server implementation to connectRPC (#10145)
# Which Problems Are Solved The current maintained gRPC server in combination with a REST (grpc) gateway is getting harder and harder to maintain. Additionally, there have been and still are issues with supporting / displaying `oneOf`s correctly. We therefore decided to exchange the server implementation to connectRPC, which apart from supporting connect as protocol, also also "standard" gRCP clients as well as HTTP/1.1 / rest like clients, e.g. curl directly call the server without any additional gateway. # How the Problems Are Solved - All v2 services are moved to connectRPC implementation. (v1 services are still served as pure grpc servers) - All gRPC server interceptors were migrated / copied to a corresponding connectRPC interceptor. - API.ListGrpcServices and API. ListGrpcMethods were changed to include the connect services and endpoints. - gRPC server reflection was changed to a `StaticReflector` using the `ListGrpcServices` list. - The `grpc.Server` interfaces was split into different combinations to be able to handle the different cases (grpc server and prefixed gateway, connect server with grpc gateway, connect server only, ...) - Docs of services serving connectRPC only with no additional gateway (instance, webkey, project, app, org v2 beta) are changed to expose that - since the plugin is not yet available on buf, we download it using `postinstall` hook of the docs # Additional Changes - WebKey service is added as v2 service (in addition to the current v2beta) # Additional Context closes #9483 --------- Co-authored-by: Elio Bischof <elio@zitadel.com>
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
//go:build integration
|
||||
|
||||
package webkey_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/webkey/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
CTX context.Context
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(func() int {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
|
||||
defer cancel()
|
||||
CTX = ctx
|
||||
return m.Run()
|
||||
}())
|
||||
}
|
||||
|
||||
func TestServer_ListWebKeys(t *testing.T) {
|
||||
instance, iamCtx, creationDate := createInstance(t)
|
||||
// After the feature is first enabled, we can expect 2 generated keys with the default config.
|
||||
checkWebKeyListState(iamCtx, t, instance, 2, "", &webkey.WebKey_Rsa{
|
||||
Rsa: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_2048,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA256,
|
||||
},
|
||||
}, creationDate)
|
||||
}
|
||||
|
||||
func TestServer_CreateWebKey(t *testing.T) {
|
||||
instance, iamCtx, creationDate := createInstance(t)
|
||||
client := instance.Client.WebKeyV2
|
||||
|
||||
_, err := client.CreateWebKey(iamCtx, &webkey.CreateWebKeyRequest{
|
||||
Key: &webkey.CreateWebKeyRequest_Rsa{
|
||||
Rsa: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_2048,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA256,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
checkWebKeyListState(iamCtx, t, instance, 3, "", &webkey.WebKey_Rsa{
|
||||
Rsa: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_2048,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA256,
|
||||
},
|
||||
}, creationDate)
|
||||
}
|
||||
|
||||
func TestServer_ActivateWebKey(t *testing.T) {
|
||||
instance, iamCtx, creationDate := createInstance(t)
|
||||
client := instance.Client.WebKeyV2
|
||||
|
||||
resp, err := client.CreateWebKey(iamCtx, &webkey.CreateWebKeyRequest{
|
||||
Key: &webkey.CreateWebKeyRequest_Rsa{
|
||||
Rsa: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_2048,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA256,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = client.ActivateWebKey(iamCtx, &webkey.ActivateWebKeyRequest{
|
||||
Id: resp.GetId(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
checkWebKeyListState(iamCtx, t, instance, 3, resp.GetId(), &webkey.WebKey_Rsa{
|
||||
Rsa: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_2048,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA256,
|
||||
},
|
||||
}, creationDate)
|
||||
}
|
||||
|
||||
func TestServer_DeleteWebKey(t *testing.T) {
|
||||
instance, iamCtx, creationDate := createInstance(t)
|
||||
client := instance.Client.WebKeyV2
|
||||
|
||||
keyIDs := make([]string, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
resp, err := client.CreateWebKey(iamCtx, &webkey.CreateWebKeyRequest{
|
||||
Key: &webkey.CreateWebKeyRequest_Rsa{
|
||||
Rsa: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_2048,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA256,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
keyIDs[i] = resp.GetId()
|
||||
}
|
||||
_, err := client.ActivateWebKey(iamCtx, &webkey.ActivateWebKeyRequest{
|
||||
Id: keyIDs[0],
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
ok := t.Run("cannot delete active key", func(t *testing.T) {
|
||||
_, err := client.DeleteWebKey(iamCtx, &webkey.DeleteWebKeyRequest{
|
||||
Id: keyIDs[0],
|
||||
})
|
||||
require.Error(t, err)
|
||||
s := status.Convert(err)
|
||||
assert.Equal(t, codes.FailedPrecondition, s.Code())
|
||||
assert.Contains(t, s.Message(), "COMMAND-Chai1")
|
||||
})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
ok = t.Run("delete inactive key", func(t *testing.T) {
|
||||
resp, err := client.DeleteWebKey(iamCtx, &webkey.DeleteWebKeyRequest{
|
||||
Id: keyIDs[1],
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.WithinRange(t, resp.GetDeletionDate().AsTime(), start, time.Now())
|
||||
})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
ok = t.Run("delete inactive key again", func(t *testing.T) {
|
||||
resp, err := client.DeleteWebKey(iamCtx, &webkey.DeleteWebKeyRequest{
|
||||
Id: keyIDs[1],
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.WithinRange(t, resp.GetDeletionDate().AsTime(), start, time.Now())
|
||||
})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
ok = t.Run("delete not existing key", func(t *testing.T) {
|
||||
resp, err := client.DeleteWebKey(iamCtx, &webkey.DeleteWebKeyRequest{
|
||||
Id: "not-existing",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, resp.DeletionDate)
|
||||
})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// There are 2 keys from feature setup, +2 created, -1 deleted = 3
|
||||
checkWebKeyListState(iamCtx, t, instance, 3, keyIDs[0], &webkey.WebKey_Rsa{
|
||||
Rsa: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_2048,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA256,
|
||||
},
|
||||
}, creationDate)
|
||||
}
|
||||
|
||||
func createInstance(t *testing.T) (*integration.Instance, context.Context, *timestamppb.Timestamp) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
creationDate := timestamppb.Now()
|
||||
iamCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(iamCTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(collect *assert.CollectT) {
|
||||
resp, err := instance.Client.WebKeyV2.ListWebKeys(iamCTX, &webkey.ListWebKeysRequest{})
|
||||
assert.NoError(collect, err)
|
||||
assert.Len(collect, resp.GetWebKeys(), 2)
|
||||
|
||||
}, retryDuration, tick)
|
||||
|
||||
return instance, iamCTX, creationDate
|
||||
}
|
||||
|
||||
func checkWebKeyListState(ctx context.Context, t *testing.T, instance *integration.Instance, nKeys int, expectActiveKeyID string, config any, creationDate *timestamppb.Timestamp) {
|
||||
t.Helper()
|
||||
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(ctx, time.Minute)
|
||||
assert.EventuallyWithT(t, func(collect *assert.CollectT) {
|
||||
resp, err := instance.Client.WebKeyV2.ListWebKeys(ctx, &webkey.ListWebKeysRequest{})
|
||||
require.NoError(collect, err)
|
||||
list := resp.GetWebKeys()
|
||||
assert.Len(collect, list, nKeys)
|
||||
|
||||
now := time.Now()
|
||||
var gotActiveKeyID string
|
||||
for _, key := range list {
|
||||
assert.WithinRange(collect, key.GetCreationDate().AsTime(), now.Add(-time.Minute), now.Add(time.Minute))
|
||||
assert.WithinRange(collect, key.GetChangeDate().AsTime(), now.Add(-time.Minute), now.Add(time.Minute))
|
||||
assert.NotEqual(collect, webkey.State_STATE_UNSPECIFIED, key.GetState())
|
||||
assert.NotEqual(collect, webkey.State_STATE_REMOVED, key.GetState())
|
||||
assert.Equal(collect, config, key.GetKey())
|
||||
|
||||
if key.GetState() == webkey.State_STATE_ACTIVE {
|
||||
gotActiveKeyID = key.GetId()
|
||||
}
|
||||
}
|
||||
assert.NotEmpty(collect, gotActiveKeyID)
|
||||
if expectActiveKeyID != "" {
|
||||
assert.Equal(collect, expectActiveKeyID, gotActiveKeyID)
|
||||
}
|
||||
}, retryDuration, tick)
|
||||
}
|
51
internal/api/grpc/webkey/v2/server.go
Normal file
51
internal/api/grpc/webkey/v2/server.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package webkey
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/webkey/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/webkey/v2/webkeyconnect"
|
||||
)
|
||||
|
||||
var _ webkeyconnect.WebKeyServiceHandler = (*Server)(nil)
|
||||
|
||||
type Server struct {
|
||||
command *command.Commands
|
||||
query *query.Queries
|
||||
}
|
||||
|
||||
func CreateServer(
|
||||
command *command.Commands,
|
||||
query *query.Queries,
|
||||
) *Server {
|
||||
return &Server{
|
||||
command: command,
|
||||
query: query,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) AppName() string {
|
||||
return webkey.WebKeyService_ServiceDesc.ServiceName
|
||||
}
|
||||
|
||||
func (s *Server) MethodPrefix() string {
|
||||
return webkey.WebKeyService_ServiceDesc.ServiceName
|
||||
}
|
||||
|
||||
func (s *Server) AuthMethods() authz.MethodMapping {
|
||||
return webkey.WebKeyService_AuthMethods
|
||||
}
|
||||
|
||||
func (s *Server) RegisterConnectServer(interceptors ...connect.Interceptor) (string, http.Handler) {
|
||||
return webkeyconnect.NewWebKeyServiceHandler(s, connect.WithInterceptors(interceptors...))
|
||||
}
|
||||
|
||||
func (s *Server) FileDescriptor() protoreflect.FileDescriptor {
|
||||
return webkey.File_zitadel_webkey_v2_webkey_service_proto
|
||||
}
|
72
internal/api/grpc/webkey/v2/webkey.go
Normal file
72
internal/api/grpc/webkey/v2/webkey.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package webkey
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/webkey/v2"
|
||||
)
|
||||
|
||||
func (s *Server) CreateWebKey(ctx context.Context, req *connect.Request[webkey.CreateWebKeyRequest]) (_ *connect.Response[webkey.CreateWebKeyResponse], err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
webKey, err := s.command.CreateWebKey(ctx, createWebKeyRequestToConfig(req.Msg))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return connect.NewResponse(&webkey.CreateWebKeyResponse{
|
||||
Id: webKey.KeyID,
|
||||
CreationDate: timestamppb.New(webKey.ObjectDetails.EventDate),
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *Server) ActivateWebKey(ctx context.Context, req *connect.Request[webkey.ActivateWebKeyRequest]) (_ *connect.Response[webkey.ActivateWebKeyResponse], err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
details, err := s.command.ActivateWebKey(ctx, req.Msg.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return connect.NewResponse(&webkey.ActivateWebKeyResponse{
|
||||
ChangeDate: timestamppb.New(details.EventDate),
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *Server) DeleteWebKey(ctx context.Context, req *connect.Request[webkey.DeleteWebKeyRequest]) (_ *connect.Response[webkey.DeleteWebKeyResponse], err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
deletedAt, err := s.command.DeleteWebKey(ctx, req.Msg.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var deletionDate *timestamppb.Timestamp
|
||||
if !deletedAt.IsZero() {
|
||||
deletionDate = timestamppb.New(deletedAt)
|
||||
}
|
||||
return connect.NewResponse(&webkey.DeleteWebKeyResponse{
|
||||
DeletionDate: deletionDate,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *Server) ListWebKeys(ctx context.Context, _ *connect.Request[webkey.ListWebKeysRequest]) (_ *connect.Response[webkey.ListWebKeysResponse], err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
list, err := s.query.ListWebKeys(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return connect.NewResponse(&webkey.ListWebKeysResponse{
|
||||
WebKeys: webKeyDetailsListToPb(list),
|
||||
}), nil
|
||||
}
|
170
internal/api/grpc/webkey/v2/webkey_converter.go
Normal file
170
internal/api/grpc/webkey/v2/webkey_converter.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package webkey
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/webkey/v2"
|
||||
)
|
||||
|
||||
func createWebKeyRequestToConfig(req *webkey.CreateWebKeyRequest) crypto.WebKeyConfig {
|
||||
switch config := req.GetKey().(type) {
|
||||
case *webkey.CreateWebKeyRequest_Rsa:
|
||||
return rsaToCrypto(config.Rsa)
|
||||
case *webkey.CreateWebKeyRequest_Ecdsa:
|
||||
return ecdsaToCrypto(config.Ecdsa)
|
||||
case *webkey.CreateWebKeyRequest_Ed25519:
|
||||
return new(crypto.WebKeyED25519Config)
|
||||
default:
|
||||
return rsaToCrypto(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func rsaToCrypto(config *webkey.RSA) *crypto.WebKeyRSAConfig {
|
||||
out := new(crypto.WebKeyRSAConfig)
|
||||
|
||||
switch config.GetBits() {
|
||||
case webkey.RSABits_RSA_BITS_UNSPECIFIED:
|
||||
out.Bits = crypto.RSABits2048
|
||||
case webkey.RSABits_RSA_BITS_2048:
|
||||
out.Bits = crypto.RSABits2048
|
||||
case webkey.RSABits_RSA_BITS_3072:
|
||||
out.Bits = crypto.RSABits3072
|
||||
case webkey.RSABits_RSA_BITS_4096:
|
||||
out.Bits = crypto.RSABits4096
|
||||
default:
|
||||
out.Bits = crypto.RSABits2048
|
||||
}
|
||||
|
||||
switch config.GetHasher() {
|
||||
case webkey.RSAHasher_RSA_HASHER_UNSPECIFIED:
|
||||
out.Hasher = crypto.RSAHasherSHA256
|
||||
case webkey.RSAHasher_RSA_HASHER_SHA256:
|
||||
out.Hasher = crypto.RSAHasherSHA256
|
||||
case webkey.RSAHasher_RSA_HASHER_SHA384:
|
||||
out.Hasher = crypto.RSAHasherSHA384
|
||||
case webkey.RSAHasher_RSA_HASHER_SHA512:
|
||||
out.Hasher = crypto.RSAHasherSHA512
|
||||
default:
|
||||
out.Hasher = crypto.RSAHasherSHA256
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func ecdsaToCrypto(config *webkey.ECDSA) *crypto.WebKeyECDSAConfig {
|
||||
out := new(crypto.WebKeyECDSAConfig)
|
||||
|
||||
switch config.GetCurve() {
|
||||
case webkey.ECDSACurve_ECDSA_CURVE_UNSPECIFIED:
|
||||
out.Curve = crypto.EllipticCurveP256
|
||||
case webkey.ECDSACurve_ECDSA_CURVE_P256:
|
||||
out.Curve = crypto.EllipticCurveP256
|
||||
case webkey.ECDSACurve_ECDSA_CURVE_P384:
|
||||
out.Curve = crypto.EllipticCurveP384
|
||||
case webkey.ECDSACurve_ECDSA_CURVE_P512:
|
||||
out.Curve = crypto.EllipticCurveP512
|
||||
default:
|
||||
out.Curve = crypto.EllipticCurveP256
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func webKeyDetailsListToPb(list []query.WebKeyDetails) []*webkey.WebKey {
|
||||
out := make([]*webkey.WebKey, len(list))
|
||||
for i := range list {
|
||||
out[i] = webKeyDetailsToPb(&list[i])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func webKeyDetailsToPb(details *query.WebKeyDetails) *webkey.WebKey {
|
||||
out := &webkey.WebKey{
|
||||
Id: details.KeyID,
|
||||
CreationDate: timestamppb.New(details.CreationDate),
|
||||
ChangeDate: timestamppb.New(details.ChangeDate),
|
||||
State: webKeyStateToPb(details.State),
|
||||
}
|
||||
|
||||
switch config := details.Config.(type) {
|
||||
case *crypto.WebKeyRSAConfig:
|
||||
out.Key = &webkey.WebKey_Rsa{
|
||||
Rsa: webKeyRSAConfigToPb(config),
|
||||
}
|
||||
case *crypto.WebKeyECDSAConfig:
|
||||
out.Key = &webkey.WebKey_Ecdsa{
|
||||
Ecdsa: webKeyECDSAConfigToPb(config),
|
||||
}
|
||||
case *crypto.WebKeyED25519Config:
|
||||
out.Key = &webkey.WebKey_Ed25519{
|
||||
Ed25519: new(webkey.ED25519),
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func webKeyStateToPb(state domain.WebKeyState) webkey.State {
|
||||
switch state {
|
||||
case domain.WebKeyStateUnspecified:
|
||||
return webkey.State_STATE_UNSPECIFIED
|
||||
case domain.WebKeyStateInitial:
|
||||
return webkey.State_STATE_INITIAL
|
||||
case domain.WebKeyStateActive:
|
||||
return webkey.State_STATE_ACTIVE
|
||||
case domain.WebKeyStateInactive:
|
||||
return webkey.State_STATE_INACTIVE
|
||||
case domain.WebKeyStateRemoved:
|
||||
return webkey.State_STATE_REMOVED
|
||||
default:
|
||||
return webkey.State_STATE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func webKeyRSAConfigToPb(config *crypto.WebKeyRSAConfig) *webkey.RSA {
|
||||
out := new(webkey.RSA)
|
||||
|
||||
switch config.Bits {
|
||||
case crypto.RSABitsUnspecified:
|
||||
out.Bits = webkey.RSABits_RSA_BITS_UNSPECIFIED
|
||||
case crypto.RSABits2048:
|
||||
out.Bits = webkey.RSABits_RSA_BITS_2048
|
||||
case crypto.RSABits3072:
|
||||
out.Bits = webkey.RSABits_RSA_BITS_3072
|
||||
case crypto.RSABits4096:
|
||||
out.Bits = webkey.RSABits_RSA_BITS_4096
|
||||
}
|
||||
|
||||
switch config.Hasher {
|
||||
case crypto.RSAHasherUnspecified:
|
||||
out.Hasher = webkey.RSAHasher_RSA_HASHER_UNSPECIFIED
|
||||
case crypto.RSAHasherSHA256:
|
||||
out.Hasher = webkey.RSAHasher_RSA_HASHER_SHA256
|
||||
case crypto.RSAHasherSHA384:
|
||||
out.Hasher = webkey.RSAHasher_RSA_HASHER_SHA384
|
||||
case crypto.RSAHasherSHA512:
|
||||
out.Hasher = webkey.RSAHasher_RSA_HASHER_SHA512
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func webKeyECDSAConfigToPb(config *crypto.WebKeyECDSAConfig) *webkey.ECDSA {
|
||||
out := new(webkey.ECDSA)
|
||||
|
||||
switch config.Curve {
|
||||
case crypto.EllipticCurveUnspecified:
|
||||
out.Curve = webkey.ECDSACurve_ECDSA_CURVE_UNSPECIFIED
|
||||
case crypto.EllipticCurveP256:
|
||||
out.Curve = webkey.ECDSACurve_ECDSA_CURVE_P256
|
||||
case crypto.EllipticCurveP384:
|
||||
out.Curve = webkey.ECDSACurve_ECDSA_CURVE_P384
|
||||
case crypto.EllipticCurveP512:
|
||||
out.Curve = webkey.ECDSACurve_ECDSA_CURVE_P512
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
494
internal/api/grpc/webkey/v2/webkey_converter_test.go
Normal file
494
internal/api/grpc/webkey/v2/webkey_converter_test.go
Normal file
@@ -0,0 +1,494 @@
|
||||
package webkey
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/webkey/v2"
|
||||
)
|
||||
|
||||
func Test_createWebKeyRequestToConfig(t *testing.T) {
|
||||
type args struct {
|
||||
req *webkey.CreateWebKeyRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want crypto.WebKeyConfig
|
||||
}{
|
||||
{
|
||||
name: "RSA",
|
||||
args: args{&webkey.CreateWebKeyRequest{
|
||||
Key: &webkey.CreateWebKeyRequest_Rsa{
|
||||
Rsa: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_3072,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA384,
|
||||
},
|
||||
},
|
||||
}},
|
||||
want: &crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits3072,
|
||||
Hasher: crypto.RSAHasherSHA384,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ECDSA",
|
||||
args: args{&webkey.CreateWebKeyRequest{
|
||||
Key: &webkey.CreateWebKeyRequest_Ecdsa{
|
||||
Ecdsa: &webkey.ECDSA{
|
||||
Curve: webkey.ECDSACurve_ECDSA_CURVE_P384,
|
||||
},
|
||||
},
|
||||
}},
|
||||
want: &crypto.WebKeyECDSAConfig{
|
||||
Curve: crypto.EllipticCurveP384,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ED25519",
|
||||
args: args{&webkey.CreateWebKeyRequest{
|
||||
Key: &webkey.CreateWebKeyRequest_Ed25519{
|
||||
Ed25519: &webkey.ED25519{},
|
||||
},
|
||||
}},
|
||||
want: &crypto.WebKeyED25519Config{},
|
||||
},
|
||||
{
|
||||
name: "default",
|
||||
args: args{&webkey.CreateWebKeyRequest{}},
|
||||
want: &crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits2048,
|
||||
Hasher: crypto.RSAHasherSHA256,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := createWebKeyRequestToConfig(tt.args.req)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_webKeyRSAConfigToCrypto(t *testing.T) {
|
||||
type args struct {
|
||||
config *webkey.RSA
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *crypto.WebKeyRSAConfig
|
||||
}{
|
||||
{
|
||||
name: "unspecified",
|
||||
args: args{&webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_UNSPECIFIED,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_UNSPECIFIED,
|
||||
}},
|
||||
want: &crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits2048,
|
||||
Hasher: crypto.RSAHasherSHA256,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "2048, RSA256",
|
||||
args: args{&webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_2048,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA256,
|
||||
}},
|
||||
want: &crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits2048,
|
||||
Hasher: crypto.RSAHasherSHA256,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "3072, RSA384",
|
||||
args: args{&webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_3072,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA384,
|
||||
}},
|
||||
want: &crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits3072,
|
||||
Hasher: crypto.RSAHasherSHA384,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "4096, RSA512",
|
||||
args: args{&webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_4096,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA512,
|
||||
}},
|
||||
want: &crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits4096,
|
||||
Hasher: crypto.RSAHasherSHA512,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid",
|
||||
args: args{&webkey.RSA{
|
||||
Bits: 99,
|
||||
Hasher: 99,
|
||||
}},
|
||||
want: &crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits2048,
|
||||
Hasher: crypto.RSAHasherSHA256,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := rsaToCrypto(tt.args.config)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_webKeyECDSAConfigToCrypto(t *testing.T) {
|
||||
type args struct {
|
||||
config *webkey.ECDSA
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *crypto.WebKeyECDSAConfig
|
||||
}{
|
||||
{
|
||||
name: "unspecified",
|
||||
args: args{&webkey.ECDSA{
|
||||
Curve: webkey.ECDSACurve_ECDSA_CURVE_UNSPECIFIED,
|
||||
}},
|
||||
want: &crypto.WebKeyECDSAConfig{
|
||||
Curve: crypto.EllipticCurveP256,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "P256",
|
||||
args: args{&webkey.ECDSA{
|
||||
Curve: webkey.ECDSACurve_ECDSA_CURVE_P256,
|
||||
}},
|
||||
want: &crypto.WebKeyECDSAConfig{
|
||||
Curve: crypto.EllipticCurveP256,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "P384",
|
||||
args: args{&webkey.ECDSA{
|
||||
Curve: webkey.ECDSACurve_ECDSA_CURVE_P384,
|
||||
}},
|
||||
want: &crypto.WebKeyECDSAConfig{
|
||||
Curve: crypto.EllipticCurveP384,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "P512",
|
||||
args: args{&webkey.ECDSA{
|
||||
Curve: webkey.ECDSACurve_ECDSA_CURVE_P512,
|
||||
}},
|
||||
want: &crypto.WebKeyECDSAConfig{
|
||||
Curve: crypto.EllipticCurveP512,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid",
|
||||
args: args{&webkey.ECDSA{
|
||||
Curve: 99,
|
||||
}},
|
||||
want: &crypto.WebKeyECDSAConfig{
|
||||
Curve: crypto.EllipticCurveP256,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := ecdsaToCrypto(tt.args.config)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_webKeyDetailsListToPb(t *testing.T) {
|
||||
list := []query.WebKeyDetails{
|
||||
{
|
||||
KeyID: "key1",
|
||||
CreationDate: time.Unix(123, 456),
|
||||
ChangeDate: time.Unix(789, 0),
|
||||
Sequence: 123,
|
||||
State: domain.WebKeyStateActive,
|
||||
Config: &crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits3072,
|
||||
Hasher: crypto.RSAHasherSHA384,
|
||||
},
|
||||
},
|
||||
{
|
||||
KeyID: "key2",
|
||||
CreationDate: time.Unix(123, 456),
|
||||
ChangeDate: time.Unix(789, 0),
|
||||
Sequence: 123,
|
||||
State: domain.WebKeyStateActive,
|
||||
Config: &crypto.WebKeyED25519Config{},
|
||||
},
|
||||
}
|
||||
want := []*webkey.WebKey{
|
||||
{
|
||||
Id: "key1",
|
||||
CreationDate: ×tamppb.Timestamp{Seconds: 123, Nanos: 456},
|
||||
ChangeDate: ×tamppb.Timestamp{Seconds: 789, Nanos: 0},
|
||||
State: webkey.State_STATE_ACTIVE,
|
||||
Key: &webkey.WebKey_Rsa{
|
||||
Rsa: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_3072,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA384,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Id: "key2",
|
||||
CreationDate: ×tamppb.Timestamp{Seconds: 123, Nanos: 456},
|
||||
ChangeDate: ×tamppb.Timestamp{Seconds: 789, Nanos: 0},
|
||||
State: webkey.State_STATE_ACTIVE,
|
||||
Key: &webkey.WebKey_Ed25519{
|
||||
Ed25519: &webkey.ED25519{},
|
||||
},
|
||||
},
|
||||
}
|
||||
got := webKeyDetailsListToPb(list)
|
||||
assert.Equal(t, want, got)
|
||||
}
|
||||
|
||||
func Test_webKeyDetailsToPb(t *testing.T) {
|
||||
type args struct {
|
||||
details *query.WebKeyDetails
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *webkey.WebKey
|
||||
}{
|
||||
{
|
||||
name: "RSA",
|
||||
args: args{&query.WebKeyDetails{
|
||||
KeyID: "keyID",
|
||||
CreationDate: time.Unix(123, 456),
|
||||
ChangeDate: time.Unix(789, 0),
|
||||
Sequence: 123,
|
||||
State: domain.WebKeyStateActive,
|
||||
Config: &crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits3072,
|
||||
Hasher: crypto.RSAHasherSHA384,
|
||||
},
|
||||
}},
|
||||
want: &webkey.WebKey{
|
||||
Id: "keyID",
|
||||
CreationDate: ×tamppb.Timestamp{Seconds: 123, Nanos: 456},
|
||||
ChangeDate: ×tamppb.Timestamp{Seconds: 789, Nanos: 0},
|
||||
State: webkey.State_STATE_ACTIVE,
|
||||
Key: &webkey.WebKey_Rsa{
|
||||
Rsa: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_3072,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA384,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ECDSA",
|
||||
args: args{&query.WebKeyDetails{
|
||||
KeyID: "keyID",
|
||||
CreationDate: time.Unix(123, 456),
|
||||
ChangeDate: time.Unix(789, 0),
|
||||
Sequence: 123,
|
||||
State: domain.WebKeyStateActive,
|
||||
Config: &crypto.WebKeyECDSAConfig{
|
||||
Curve: crypto.EllipticCurveP384,
|
||||
},
|
||||
}},
|
||||
want: &webkey.WebKey{
|
||||
Id: "keyID",
|
||||
CreationDate: ×tamppb.Timestamp{Seconds: 123, Nanos: 456},
|
||||
ChangeDate: ×tamppb.Timestamp{Seconds: 789, Nanos: 0},
|
||||
State: webkey.State_STATE_ACTIVE,
|
||||
Key: &webkey.WebKey_Ecdsa{
|
||||
Ecdsa: &webkey.ECDSA{
|
||||
Curve: webkey.ECDSACurve_ECDSA_CURVE_P384,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ED25519",
|
||||
args: args{&query.WebKeyDetails{
|
||||
KeyID: "keyID",
|
||||
CreationDate: time.Unix(123, 456),
|
||||
ChangeDate: time.Unix(789, 0),
|
||||
Sequence: 123,
|
||||
State: domain.WebKeyStateActive,
|
||||
Config: &crypto.WebKeyED25519Config{},
|
||||
}},
|
||||
want: &webkey.WebKey{
|
||||
Id: "keyID",
|
||||
CreationDate: ×tamppb.Timestamp{Seconds: 123, Nanos: 456},
|
||||
ChangeDate: ×tamppb.Timestamp{Seconds: 789, Nanos: 0},
|
||||
State: webkey.State_STATE_ACTIVE,
|
||||
Key: &webkey.WebKey_Ed25519{
|
||||
Ed25519: &webkey.ED25519{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := webKeyDetailsToPb(tt.args.details)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_webKeyStateToPb(t *testing.T) {
|
||||
type args struct {
|
||||
state domain.WebKeyState
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want webkey.State
|
||||
}{
|
||||
{
|
||||
name: "unspecified",
|
||||
args: args{domain.WebKeyStateUnspecified},
|
||||
want: webkey.State_STATE_UNSPECIFIED,
|
||||
},
|
||||
{
|
||||
name: "initial",
|
||||
args: args{domain.WebKeyStateInitial},
|
||||
want: webkey.State_STATE_INITIAL,
|
||||
},
|
||||
{
|
||||
name: "active",
|
||||
args: args{domain.WebKeyStateActive},
|
||||
want: webkey.State_STATE_ACTIVE,
|
||||
},
|
||||
{
|
||||
name: "inactive",
|
||||
args: args{domain.WebKeyStateInactive},
|
||||
want: webkey.State_STATE_INACTIVE,
|
||||
},
|
||||
{
|
||||
name: "removed",
|
||||
args: args{domain.WebKeyStateRemoved},
|
||||
want: webkey.State_STATE_REMOVED,
|
||||
},
|
||||
{
|
||||
name: "invalid",
|
||||
args: args{99},
|
||||
want: webkey.State_STATE_UNSPECIFIED,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := webKeyStateToPb(tt.args.state)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_webKeyRSAConfigToPb(t *testing.T) {
|
||||
type args struct {
|
||||
config *crypto.WebKeyRSAConfig
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *webkey.RSA
|
||||
}{
|
||||
{
|
||||
name: "2048, RSA256",
|
||||
args: args{&crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits2048,
|
||||
Hasher: crypto.RSAHasherSHA256,
|
||||
}},
|
||||
want: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_2048,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA256,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "3072, RSA384",
|
||||
args: args{&crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits3072,
|
||||
Hasher: crypto.RSAHasherSHA384,
|
||||
}},
|
||||
want: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_3072,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA384,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "4096, RSA512",
|
||||
args: args{&crypto.WebKeyRSAConfig{
|
||||
Bits: crypto.RSABits4096,
|
||||
Hasher: crypto.RSAHasherSHA512,
|
||||
}},
|
||||
want: &webkey.RSA{
|
||||
Bits: webkey.RSABits_RSA_BITS_4096,
|
||||
Hasher: webkey.RSAHasher_RSA_HASHER_SHA512,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := webKeyRSAConfigToPb(tt.args.config)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_webKeyECDSAConfigToPb(t *testing.T) {
|
||||
type args struct {
|
||||
config *crypto.WebKeyECDSAConfig
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *webkey.ECDSA
|
||||
}{
|
||||
{
|
||||
name: "P256",
|
||||
args: args{&crypto.WebKeyECDSAConfig{
|
||||
Curve: crypto.EllipticCurveP256,
|
||||
}},
|
||||
want: &webkey.ECDSA{
|
||||
Curve: webkey.ECDSACurve_ECDSA_CURVE_P256,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "P384",
|
||||
args: args{&crypto.WebKeyECDSAConfig{
|
||||
Curve: crypto.EllipticCurveP384,
|
||||
}},
|
||||
want: &webkey.ECDSA{
|
||||
Curve: webkey.ECDSACurve_ECDSA_CURVE_P384,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "P512",
|
||||
args: args{&crypto.WebKeyECDSAConfig{
|
||||
Curve: crypto.EllipticCurveP512,
|
||||
}},
|
||||
want: &webkey.ECDSA{
|
||||
Curve: webkey.ECDSACurve_ECDSA_CURVE_P512,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := webKeyECDSAConfigToPb(tt.args.config)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
@@ -1,17 +1,22 @@
|
||||
package webkey
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc"
|
||||
"net/http"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/api/grpc/server"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
webkey "github.com/zitadel/zitadel/pkg/grpc/webkey/v2beta"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/webkey/v2beta/webkeyconnect"
|
||||
)
|
||||
|
||||
var _ webkeyconnect.WebKeyServiceHandler = (*Server)(nil)
|
||||
|
||||
type Server struct {
|
||||
webkey.UnimplementedWebKeyServiceServer
|
||||
command *command.Commands
|
||||
query *query.Queries
|
||||
}
|
||||
@@ -26,10 +31,6 @@ func CreateServer(
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) RegisterServer(grpcServer *grpc.Server) {
|
||||
webkey.RegisterWebKeyServiceServer(grpcServer, s)
|
||||
}
|
||||
|
||||
func (s *Server) AppName() string {
|
||||
return webkey.WebKeyService_ServiceDesc.ServiceName
|
||||
}
|
||||
@@ -45,3 +46,11 @@ func (s *Server) AuthMethods() authz.MethodMapping {
|
||||
func (s *Server) RegisterGateway() server.RegisterGatewayFunc {
|
||||
return webkey.RegisterWebKeyServiceHandler
|
||||
}
|
||||
|
||||
func (s *Server) RegisterConnectServer(interceptors ...connect.Interceptor) (string, http.Handler) {
|
||||
return webkeyconnect.NewWebKeyServiceHandler(s, connect.WithInterceptors(interceptors...))
|
||||
}
|
||||
|
||||
func (s *Server) FileDescriptor() protoreflect.FileDescriptor {
|
||||
return webkey.File_zitadel_webkey_v2beta_webkey_service_proto
|
||||
}
|
||||
|
@@ -3,46 +3,47 @@ package webkey
|
||||
import (
|
||||
"context"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||
webkey "github.com/zitadel/zitadel/pkg/grpc/webkey/v2beta"
|
||||
)
|
||||
|
||||
func (s *Server) CreateWebKey(ctx context.Context, req *webkey.CreateWebKeyRequest) (_ *webkey.CreateWebKeyResponse, err error) {
|
||||
func (s *Server) CreateWebKey(ctx context.Context, req *connect.Request[webkey.CreateWebKeyRequest]) (_ *connect.Response[webkey.CreateWebKeyResponse], err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
webKey, err := s.command.CreateWebKey(ctx, createWebKeyRequestToConfig(req))
|
||||
webKey, err := s.command.CreateWebKey(ctx, createWebKeyRequestToConfig(req.Msg))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &webkey.CreateWebKeyResponse{
|
||||
return connect.NewResponse(&webkey.CreateWebKeyResponse{
|
||||
Id: webKey.KeyID,
|
||||
CreationDate: timestamppb.New(webKey.ObjectDetails.EventDate),
|
||||
}, nil
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *Server) ActivateWebKey(ctx context.Context, req *webkey.ActivateWebKeyRequest) (_ *webkey.ActivateWebKeyResponse, err error) {
|
||||
func (s *Server) ActivateWebKey(ctx context.Context, req *connect.Request[webkey.ActivateWebKeyRequest]) (_ *connect.Response[webkey.ActivateWebKeyResponse], err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
details, err := s.command.ActivateWebKey(ctx, req.GetId())
|
||||
details, err := s.command.ActivateWebKey(ctx, req.Msg.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &webkey.ActivateWebKeyResponse{
|
||||
return connect.NewResponse(&webkey.ActivateWebKeyResponse{
|
||||
ChangeDate: timestamppb.New(details.EventDate),
|
||||
}, nil
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *Server) DeleteWebKey(ctx context.Context, req *webkey.DeleteWebKeyRequest) (_ *webkey.DeleteWebKeyResponse, err error) {
|
||||
func (s *Server) DeleteWebKey(ctx context.Context, req *connect.Request[webkey.DeleteWebKeyRequest]) (_ *connect.Response[webkey.DeleteWebKeyResponse], err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
deletedAt, err := s.command.DeleteWebKey(ctx, req.GetId())
|
||||
deletedAt, err := s.command.DeleteWebKey(ctx, req.Msg.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -51,12 +52,12 @@ func (s *Server) DeleteWebKey(ctx context.Context, req *webkey.DeleteWebKeyReque
|
||||
if !deletedAt.IsZero() {
|
||||
deletionDate = timestamppb.New(deletedAt)
|
||||
}
|
||||
return &webkey.DeleteWebKeyResponse{
|
||||
return connect.NewResponse(&webkey.DeleteWebKeyResponse{
|
||||
DeletionDate: deletionDate,
|
||||
}, nil
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *Server) ListWebKeys(ctx context.Context, _ *webkey.ListWebKeysRequest) (_ *webkey.ListWebKeysResponse, err error) {
|
||||
func (s *Server) ListWebKeys(ctx context.Context, _ *connect.Request[webkey.ListWebKeysRequest]) (_ *connect.Response[webkey.ListWebKeysResponse], err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
@@ -65,7 +66,7 @@ func (s *Server) ListWebKeys(ctx context.Context, _ *webkey.ListWebKeysRequest)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &webkey.ListWebKeysResponse{
|
||||
return connect.NewResponse(&webkey.ListWebKeysResponse{
|
||||
WebKeys: webKeyDetailsListToPb(list),
|
||||
}, nil
|
||||
}), nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user