Skip to content

Commit

Permalink
add interface for ClientEncryption (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
SVilgelm authored Aug 10, 2023
1 parent 82edc28 commit dcfa7c9
Show file tree
Hide file tree
Showing 6 changed files with 754 additions and 6 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ lint:

tidy:
@echo "$(OK_COLOR)==> Updating go.mod...$(NO_COLOR)"
@go mod tidy -compat=1.19
@go mod tidy -compat=1.21

run-mockgen:
@mockgen -destination=mocks/gomock/mocks.go -package mocks . ChangeStream,Client,Collection,Cursor,Database,IndexView,Session,SingleResult,SessionContext
@mockgen -destination=mocks/gomock/mocks.go -package mocks . ChangeStream,Client,Collection,Cursor,Database,IndexView,Session,SingleResult,SessionContext,ClientEncryption

run-mockery:
@mockery --all --srcpkg github.com/sv-tools/mongoifc --output mocks/mockery --disable-version-string --case underscore
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ This is the main reason of wrapping the original objects and using the `mongoifc
- [x] SingleResult: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SingleResult
- [x] IndexView: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#IndexView
- [x] SessionContext: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SessionContext
- [x] ClientEncryption: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#ClientEncryption

## Mocks

Expand Down
17 changes: 14 additions & 3 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ type Client interface {
Connect(ctx context.Context) error
Database(name string, opts ...*options.DatabaseOptions) Database
Disconnect(ctx context.Context) error
ListDatabaseNames(ctx context.Context, filter interface{}, opts ...*options.ListDatabasesOptions) ([]string, error)
ListDatabaseNames(
ctx context.Context,
filter interface{},
opts ...*options.ListDatabasesOptions,
) ([]string, error)
ListDatabases(
ctx context.Context,
filter interface{},
Expand All @@ -25,8 +29,15 @@ type Client interface {
Ping(ctx context.Context, rp *readpref.ReadPref) error
StartSession(opts ...*options.SessionOptions) (Session, error)
Timeout() *time.Duration
UseSession(ctx context.Context, fn func(sc SessionContext) error) error
UseSessionWithOptions(ctx context.Context, opts *options.SessionOptions, fn func(sc SessionContext) error) error
UseSession(
ctx context.Context,
fn func(sc SessionContext) error,
) error
UseSessionWithOptions(
ctx context.Context,
opts *options.SessionOptions,
fn func(sc SessionContext) error,
) error
Watch(
ctx context.Context,
pipeline interface{},
Expand Down
160 changes: 160 additions & 0 deletions client_encryption.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package mongoifc

import (
"context"

"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

// ClientEncryption is an interface for `mongo.ClientEncryption` structure
// Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#ClientEncryption
type ClientEncryption interface {
AddKeyAltName(
ctx context.Context,
id primitive.Binary,
keyAltName string,
) SingleResult
Close(ctx context.Context) error
CreateDataKey(
ctx context.Context,
kmsProvider string,
opts ...*options.DataKeyOptions,
) (primitive.Binary, error)
CreateEncryptedCollection(
ctx context.Context,
db Database,
coll string,
createOpts *options.CreateCollectionOptions,
kmsProvider string,
masterKey interface{},
) (Collection, bson.M, error)
Decrypt(ctx context.Context, val primitive.Binary) (bson.RawValue, error)
DeleteKey(ctx context.Context, id primitive.Binary) (*mongo.DeleteResult, error)
Encrypt(
ctx context.Context,
val bson.RawValue,
opts ...*options.EncryptOptions,
) (primitive.Binary, error)
EncryptExpression(
ctx context.Context,
expr interface{},
result interface{},
opts ...*options.EncryptOptions,
) error
GetKey(ctx context.Context, id primitive.Binary) SingleResult
GetKeyByAltName(ctx context.Context, keyAltName string) SingleResult
GetKeys(ctx context.Context) (Cursor, error)
RemoveKeyAltName(
ctx context.Context,
id primitive.Binary,
keyAltName string,
) SingleResult
RewrapManyDataKey(
ctx context.Context,
filter interface{},
opts ...*options.RewrapManyDataKeyOptions,
) (*mongo.RewrapManyDataKeyResult, error)
}

type clientEncryption struct {
ce *mongo.ClientEncryption
}

func (c *clientEncryption) AddKeyAltName(ctx context.Context, id primitive.Binary, keyAltName string) SingleResult {
return wrapSingleResult(c.ce.AddKeyAltName(ctx, id, keyAltName))
}

func (c *clientEncryption) Close(ctx context.Context) error {
return c.ce.Close(ctx)
}

func (c *clientEncryption) CreateDataKey(
ctx context.Context,
kmsProvider string,
opts ...*options.DataKeyOptions,
) (primitive.Binary, error) {
return c.ce.CreateDataKey(ctx, kmsProvider, opts...)
}

func (c *clientEncryption) CreateEncryptedCollection(
ctx context.Context,
db Database,
coll string,
createOpts *options.CreateCollectionOptions,
kmsProvider string,
masterKey interface{},
) (Collection, bson.M, error) {
col, doc, err := c.ce.CreateEncryptedCollection(ctx, UnWrapDatabase(db), coll, createOpts, kmsProvider, masterKey)
if err != nil {
return nil, nil, err
}
return wrapCollection(col, db.(*database)), doc, err
}

func (c *clientEncryption) Decrypt(ctx context.Context, val primitive.Binary) (bson.RawValue, error) {
return c.ce.Decrypt(ctx, val)
}

func (c *clientEncryption) DeleteKey(ctx context.Context, id primitive.Binary) (*mongo.DeleteResult, error) {
return c.ce.DeleteKey(ctx, id)
}

func (c *clientEncryption) Encrypt(
ctx context.Context,
val bson.RawValue,
opts ...*options.EncryptOptions,
) (primitive.Binary, error) {
return c.ce.Encrypt(ctx, val, opts...)
}

func (c *clientEncryption) EncryptExpression(
ctx context.Context,
expr interface{},
result interface{},
opts ...*options.EncryptOptions,
) error {
return c.ce.EncryptExpression(ctx, expr, result, opts...)
}

func (c *clientEncryption) GetKey(ctx context.Context, id primitive.Binary) SingleResult {
return wrapSingleResult(c.ce.GetKey(ctx, id))
}

func (c *clientEncryption) GetKeyByAltName(ctx context.Context, keyAltName string) SingleResult {
return wrapSingleResult(c.ce.GetKeyByAltName(ctx, keyAltName))
}

func (c *clientEncryption) GetKeys(ctx context.Context) (Cursor, error) {
cr, err := c.ce.GetKeys(ctx)
if err != nil {
return nil, err
}
return wrapCursor(cr), nil
}

func (c *clientEncryption) RemoveKeyAltName(
ctx context.Context,
id primitive.Binary,
keyAltName string,
) SingleResult {
return wrapSingleResult(c.ce.RemoveKeyAltName(ctx, id, keyAltName))
}

func (c *clientEncryption) RewrapManyDataKey(
ctx context.Context,
filter interface{},
opts ...*options.RewrapManyDataKeyOptions,
) (*mongo.RewrapManyDataKeyResult, error) {
return c.ce.RewrapManyDataKey(ctx, filter, opts...)
}

func NewClientEncryption(keyVaultClient Client, opts ...*options.ClientEncryptionOptions) (ClientEncryption, error) {
ce, err := mongo.NewClientEncryption(UnWrapClient(keyVaultClient), opts...)
if err != nil {
return nil, err
}
return &clientEncryption{ce: ce}, nil
}
Loading

0 comments on commit dcfa7c9

Please sign in to comment.