Skip to content

Commit

Permalink
apply feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
fredcarle committed Dec 13, 2024
1 parent 720433d commit b7c20da
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 266 deletions.
20 changes: 20 additions & 0 deletions acp/identity/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/cyware/ssi-sdk/did/key"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jws"
"github.com/lestrrat-go/jwx/v2/jwt"
"github.com/sourcenetwork/immutable"
acptypes "github.com/sourcenetwork/sourcehub/x/acp/bearer_token"
Expand Down Expand Up @@ -183,3 +184,22 @@ func (identity Identity) NewToken(

return signedToken, nil
}

// VerifyAuthToken verifies that the jwt auth token is valid and that the signature
// matches the identity of the subject.
func VerifyAuthToken(ident Identity, audience string) error {
_, err := jwt.Parse([]byte(ident.BearerToken), jwt.WithVerify(false), jwt.WithAudience(audience))
if err != nil {
return err
}

_, err = jws.Verify(
[]byte(ident.BearerToken),
jws.WithKey(BearerTokenSignatureScheme, ident.PublicKey.ToECDSA()),
)
if err != nil {
return err
}

return nil
}
22 changes: 1 addition & 21 deletions http/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
"net/http"
"strings"

"github.com/lestrrat-go/jwx/v2/jws"
"github.com/lestrrat-go/jwx/v2/jwt"
"github.com/sourcenetwork/immutable"

acpIdentity "github.com/sourcenetwork/defradb/acp/identity"
Expand All @@ -30,24 +28,6 @@ const (
authSchemaPrefix = "Bearer "
)

// verifyAuthToken verifies that the jwt auth token is valid and that the signature
// matches the identity of the subject.
func verifyAuthToken(identity acpIdentity.Identity, audience string) error {
_, err := jwt.Parse([]byte(identity.BearerToken), jwt.WithVerify(false), jwt.WithAudience(audience))
if err != nil {
return err
}

_, err = jws.Verify(
[]byte(identity.BearerToken),
jws.WithKey(acpIdentity.BearerTokenSignatureScheme, identity.PublicKey.ToECDSA()),
)
if err != nil {
return err
}
return nil
}

// AuthMiddleware authenticates an actor and sets their identity for all subsequent actions.
func AuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
Expand All @@ -63,7 +43,7 @@ func AuthMiddleware(next http.Handler) http.Handler {
return
}

err = verifyAuthToken(ident, strings.ToLower(req.Host))
err = acpIdentity.VerifyAuthToken(ident, strings.ToLower(req.Host))
if err != nil {
http.Error(rw, "forbidden", http.StatusForbidden)
return
Expand Down
6 changes: 3 additions & 3 deletions http/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestVerifyAuthToken(t *testing.T) {
err = identity.UpdateToken(time.Hour, immutable.Some(audience), immutable.None[string]())
require.NoError(t, err)

err = verifyAuthToken(identity, audience)
err = acpIdentity.VerifyAuthToken(identity, audience)
require.NoError(t, err)
}

Expand All @@ -48,7 +48,7 @@ func TestVerifyAuthTokenErrorsWithNonMatchingAudience(t *testing.T) {
err = identity.UpdateToken(time.Hour, immutable.Some("valid"), immutable.None[string]())
require.NoError(t, err)

err = verifyAuthToken(identity, "invalid")
err = acpIdentity.VerifyAuthToken(identity, "invalid")
assert.Error(t, err)
}

Expand All @@ -65,6 +65,6 @@ func TestVerifyAuthTokenErrorsWithExpired(t *testing.T) {
err = identity.UpdateToken(-time.Hour, immutable.Some(audience), immutable.None[string]())
require.NoError(t, err)

err = verifyAuthToken(identity, "123abc")
err = acpIdentity.VerifyAuthToken(identity, "123abc")
assert.Error(t, err)
}
2 changes: 1 addition & 1 deletion internal/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ func (db *db) GetNodeIdentity(_ context.Context) (immutable.Option[identity.Publ
return immutable.None[identity.PublicRawIdentity](), nil
}

func (db *db) GetIdentityToken(_ context.Context, audience immutable.Option[string]) ([]byte, error) {
func (db *db) GetNodeIdentityToken(_ context.Context, audience immutable.Option[string]) ([]byte, error) {
if db.nodeIdentity.HasValue() {
return db.nodeIdentity.Value().NewToken(time.Hour*24, audience, immutable.None[string]())
}
Expand Down
2 changes: 1 addition & 1 deletion internal/db/permission/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func CheckAccessOfDocOnCollectionWithACP(
// Unrestricted Access to document if:
// - (2) is false.
// - Document is public (unregistered), whether signatured request or not doesn't matter.
func CheckAccessDocAccessWithDID(
func CheckDocAccessWithDID(
ctx context.Context,
did string,
acpSystem acp.ACP,
Expand Down
31 changes: 0 additions & 31 deletions net/acp.go

This file was deleted.

25 changes: 16 additions & 9 deletions net/dialer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"context"
"testing"

"github.com/sourcenetwork/defradb/acp"
"github.com/sourcenetwork/immutable"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand All @@ -30,17 +31,19 @@ func TestDial_WithConnectedPeer_NoError(t *testing.T) {
db1.Blockstore(),
db1.Encstore(),
db1.Events(),
immutable.None[ACP](),
immutable.None[acp.ACP](),
nil,
WithListenAddresses("/ip4/127.0.0.1/tcp/0"),
)
assert.NoError(t, err)
defer n1.Close()
n2, err := NewPeer(
ctx,
db2.Blockstore(),
db1.Encstore(),
db2.Encstore(),
db2.Events(),
immutable.None[ACP](),
immutable.None[acp.ACP](),
nil,
WithListenAddresses("/ip4/127.0.0.1/tcp/0"),
)
assert.NoError(t, err)
Expand All @@ -64,17 +67,19 @@ func TestDial_WithConnectedPeerAndSecondConnection_NoError(t *testing.T) {
db1.Blockstore(),
db1.Encstore(),
db1.Events(),
immutable.None[ACP](),
immutable.None[acp.ACP](),
nil,
WithListenAddresses("/ip4/127.0.0.1/tcp/0"),
)
assert.NoError(t, err)
defer n1.Close()
n2, err := NewPeer(
ctx,
db2.Blockstore(),
db1.Encstore(),
db2.Encstore(),
db2.Events(),
immutable.None[ACP](),
immutable.None[acp.ACP](),
nil,
WithListenAddresses("/ip4/127.0.0.1/tcp/0"),
)
assert.NoError(t, err)
Expand All @@ -101,17 +106,19 @@ func TestDial_WithConnectedPeerAndSecondConnectionWithConnectionShutdown_Closing
db1.Blockstore(),
db1.Encstore(),
db1.Events(),
immutable.None[ACP](),
immutable.None[acp.ACP](),
nil,
WithListenAddresses("/ip4/127.0.0.1/tcp/0"),
)
assert.NoError(t, err)
defer n1.Close()
n2, err := NewPeer(
ctx,
db2.Blockstore(),
db1.Encstore(),
db2.Encstore(),
db2.Events(),
immutable.None[ACP](),
immutable.None[acp.ACP](),
nil,
WithListenAddresses("/ip4/127.0.0.1/tcp/0"),
)
assert.NoError(t, err)
Expand Down
47 changes: 10 additions & 37 deletions net/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,10 @@ import (
const (
grpcServiceName = "defradb.net.Service"

serviceGetDocGraphName = "/" + grpcServiceName + "/GetDocGraph"
servicePushDocGraphName = "/" + grpcServiceName + "/PushDocGraph"
serviceGetLogName = "/" + grpcServiceName + "/GetLog"
servicePushLogName = "/" + grpcServiceName + "/PushLog"
serviceGetHeadLogName = "/" + grpcServiceName + "/GetHeadLog"
serviceGetIdentityName = "/" + grpcServiceName + "/GetIdentity"
servicePushLogName = "/" + grpcServiceName + "/PushLog"
serviceGetIdentityName = "/" + grpcServiceName + "/GetIdentity"
)

type getDocGraphRequest struct{}

type getDocGraphReply struct{}

type getHeadLogRequest struct{}

type getHeadLogReply struct{}

type getLogRequest struct{}

type getLogReply struct{}

type pushDocGraphRequest struct{}

type pushDocGraphReply struct{}

type pushLogRequest struct {
DocID string
CID []byte
Expand All @@ -65,17 +45,10 @@ type getIdentityReply struct {
}

type serviceServer interface {
// GetDocGraph from this peer.
GetDocGraph(context.Context, *getDocGraphRequest) (*getDocGraphReply, error)
// PushDocGraph to this peer.
PushDocGraph(context.Context, *pushDocGraphRequest) (*pushDocGraphReply, error)
// GetLog from this peer.
GetLog(context.Context, *getLogRequest) (*getLogReply, error)
// PushLog to this peer.
PushLog(context.Context, *pushLogRequest) (*pushLogReply, error)
// GetHeadLog from this peer
GetHeadLog(context.Context, *getHeadLogRequest) (*getHeadLogReply, error)
GetIdentity(context.Context, *getIdentityRequest) (*getIdentityReply, error)
// pushLogHandler handles a push log request to sync blocks.
pushLogHandler(context.Context, *pushLogRequest) (*pushLogReply, error)
// getIdentityHandler handles an indentity request and returns the local node's identity.
getIdentityHandler(context.Context, *getIdentityRequest) (*getIdentityReply, error)
}

func getIdentityHandler(
Expand All @@ -89,14 +62,14 @@ func getIdentityHandler(
return nil, err
}
if interceptor == nil {
return srv.(serviceServer).GetIdentity(ctx, in)
return srv.(serviceServer).getIdentityHandler(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: serviceGetIdentityName,
}
handler := func(ctx context.Context, req any) (any, error) {
return srv.(serviceServer).GetIdentity(ctx, req.(*getIdentityRequest))
return srv.(serviceServer).getIdentityHandler(ctx, req.(*getIdentityRequest))
}
return interceptor(ctx, in, info, handler)
}
Expand All @@ -112,14 +85,14 @@ func pushLogHandler(
return nil, err
}
if interceptor == nil {
return srv.(serviceServer).PushLog(ctx, in)
return srv.(serviceServer).pushLogHandler(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: servicePushLogName,
}
handler := func(ctx context.Context, req any) (any, error) {
return srv.(serviceServer).PushLog(ctx, req.(*pushLogRequest))
return srv.(serviceServer).pushLogHandler(ctx, req.(*pushLogRequest))
}
return interceptor(ctx, in, info, handler)
}
Expand Down
19 changes: 17 additions & 2 deletions net/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,25 @@ import (
"github.com/sourcenetwork/immutable"
"google.golang.org/grpc"

"github.com/sourcenetwork/defradb/acp"
"github.com/sourcenetwork/defradb/acp/identity"
"github.com/sourcenetwork/defradb/client"
"github.com/sourcenetwork/defradb/datastore"
"github.com/sourcenetwork/defradb/errors"
"github.com/sourcenetwork/defradb/event"
corenet "github.com/sourcenetwork/defradb/internal/core/net"
)

// DB hold the database related methods that are required by Peer.
type DB interface {
// GetCollections returns the list of collections according to the given options.
GetCollections(ctx context.Context, opts client.CollectionFetchOptions) ([]client.Collection, error)
// GetNodeIndentityToken returns an identity token for the given audience.
GetNodeIdentityToken(ctx context.Context, audience immutable.Option[string]) ([]byte, error)
// GetNodeIdentity returns the node's public raw identity.
GetNodeIdentity(ctx context.Context) (immutable.Option[identity.PublicRawIdentity], error)
}

// Peer is a DefraDB Peer node which exposes all the LibP2P host/peer functionality
// to the underlying DefraDB instance.
type Peer struct {
Expand All @@ -62,7 +74,8 @@ type Peer struct {
// peer DAG service
bserv blockservice.BlockService

acp immutable.Option[ACP]
acp immutable.Option[acp.ACP]
db DB

bootCloser io.Closer
}
Expand All @@ -73,7 +86,8 @@ func NewPeer(
blockstore datastore.Blockstore,
encstore datastore.Blockstore,
bus *event.Bus,
acp immutable.Option[ACP],
acp immutable.Option[acp.ACP],
db DB,
opts ...NodeOpt,
) (p *Peer, err error) {
ctx, cancel := context.WithCancel(ctx)
Expand Down Expand Up @@ -124,6 +138,7 @@ func NewPeer(
cancel: cancel,
bus: bus,
acp: acp,
db: db,
p2pRPC: grpc.NewServer(options.GRPCServerOptions...),
}

Expand Down
Loading

0 comments on commit b7c20da

Please sign in to comment.