Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 46 additions & 14 deletions languages/go/goeql/goeql.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type EncryptedColumn struct {
P string `json:"p"`
I TableColumn `json:"i"`
V int `json:"v"`
Q any `json:"q"`
}

// EncryptedText is a string value to be encrypted
Expand All @@ -45,7 +46,7 @@ type EncryptedBool bool

// Serialize turns a EncryptedText value into a jsonb payload for CipherStash Proxy
func (et EncryptedText) Serialize(table string, column string) ([]byte, error) {
val, err := ToEncryptedColumn(string(et), table, column)
val, err := ToEncryptedColumn(string(et), table, column, nil)
if err != nil {
return nil, fmt.Errorf("error serializing: %v", err)
}
Expand All @@ -68,7 +69,7 @@ func (et *EncryptedText) Deserialize(data []byte) (EncryptedText, error) {

// Serialize turns a EncryptedJsonb value into a jsonb payload for CipherStash Proxy
func (ej EncryptedJsonb) Serialize(table string, column string) ([]byte, error) {
val, err := ToEncryptedColumn(map[string]any(ej), table, column)
val, err := ToEncryptedColumn(map[string]any(ej), table, column, nil)
if err != nil {
return nil, fmt.Errorf("error serializing: %v", err)
}
Expand Down Expand Up @@ -96,7 +97,7 @@ func (ej *EncryptedJsonb) Deserialize(data []byte) (EncryptedJsonb, error) {

// Serialize turns a EncryptedInt value into a jsonb payload for CipherStash Proxy
func (et EncryptedInt) Serialize(table string, column string) ([]byte, error) {
val, err := ToEncryptedColumn(int(et), table, column)
val, err := ToEncryptedColumn(int(et), table, column, nil)
if err != nil {
return nil, fmt.Errorf("error serializing: %v", err)
}
Expand All @@ -123,7 +124,7 @@ func (et *EncryptedInt) Deserialize(data []byte) (EncryptedInt, error) {

// Serialize turns a EncryptedBool value into a jsonb payload for CipherStash Proxy
func (eb EncryptedBool) Serialize(table string, column string) ([]byte, error) {
val, err := ToEncryptedColumn(bool(eb), table, column)
val, err := ToEncryptedColumn(bool(eb), table, column, nil)
if err != nil {
return nil, fmt.Errorf("error serializing: %v", err)
}
Expand All @@ -149,9 +150,29 @@ func (eb *EncryptedBool) Deserialize(data []byte) (EncryptedBool, error) {
return false, fmt.Errorf("invalid format: missing 'p' field")
}

// SerializeQuery produces a jsonb payload used by EQL query functions to perform search operations like equality checks, range queries, and unique constraints.
func SerializeQuery(value any, table string, column string) ([]byte, error) {
query, err := ToEncryptedColumn(value, table, column)
// serializes a plaintext value used in a match query
func MatchQuery(value any, table string, column string) ([]byte, error) {
return serializeQuery(value, table, column, "match")
}

// serializes a plaintext value used in an ore query
func OreQuery(value any, table string, column string) ([]byte, error) {
return serializeQuery(value, table, column, "ore")
}

// serializes a plaintext value used in a unique query
func UniqueQuery(value any, table string, column string) ([]byte, error) {
return serializeQuery(value, table, column, "unique")
}

// serializes a plaintext value used in a jsonb query
func JsonbQuery(value any, table string, column string) ([]byte, error) {
return serializeQuery(value, table, column, "ste_vec")
}

// serializeQuery produces a jsonb payload used by EQL query functions to perform search operations like equality checks, range queries, and unique constraints.
func serializeQuery(value any, table string, column string, queryType any) ([]byte, error) {
query, err := ToEncryptedColumn(value, table, column, queryType)
if err != nil {
return nil, fmt.Errorf("error converting to EncryptedColumn: %v", err)
}
Expand All @@ -165,15 +186,26 @@ func SerializeQuery(value any, table string, column string) ([]byte, error) {
}

// ToEncryptedColumn converts a plaintext value to a string, and returns the EncryptedColumn struct for inserting into a database.
func ToEncryptedColumn(value any, table string, column string) (EncryptedColumn, error) {
str, err := convertToString(value)
if err != nil {
return EncryptedColumn{}, fmt.Errorf("error: %v", err)
}
func ToEncryptedColumn(value any, table string, column string, queryType any) (EncryptedColumn, error) {
if queryType == nil {
str, err := convertToString(value)
if err != nil {
return EncryptedColumn{}, fmt.Errorf("error: %v", err)
}

data := EncryptedColumn{K: "pt", P: str, I: TableColumn{T: table, C: column}, V: 1, Q: nil}

data := EncryptedColumn{K: "pt", P: str, I: TableColumn{T: table, C: column}, V: 1}
return data, nil
} else {
str, err := convertToString(value)
if err != nil {
return EncryptedColumn{}, fmt.Errorf("error: %v", err)
}

return data, nil
data := EncryptedColumn{K: "pt", P: str, I: TableColumn{T: table, C: column}, V: 1, Q: queryType}

return data, nil
}
}

func convertToString(value any) (string, error) {
Expand Down
121 changes: 96 additions & 25 deletions languages/go/goeql/goeql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,34 +210,105 @@ func TestEncryptedBool_Deserialize(t *testing.T) {
}
}

// Test SerializeQuery Function
func TestSerializeQuery(t *testing.T) {
tests := []struct {
value interface{}
table string
column string
expectedP string
}{
{value: "test_string", table: "table1", column: "column1", expectedP: "test_string"},
{value: 123, table: "table2", column: "column2", expectedP: "123"},
{value: true, table: "table3", column: "column3", expectedP: "true"},
{value: map[string]interface{}{"key": "value"}, table: "table4", column: "column4", expectedP: `{"key":"value"}`},
func TestMatchQuerySerialization(t *testing.T) {
value := "test_string"
table := "table1"
column := "column1"
expectedP := "test_string"
expectedQ := "match"

serializedData, err := MatchQuery(value, table, column)
if err != nil {
t.Fatalf("SerializeQuery returned error: %v", err)
}

for _, tt := range tests {
serializedData, err := SerializeQuery(tt.value, tt.table, tt.column)
if err != nil {
t.Fatalf("SerializeQuery returned error: %v", err)
}
var ec EncryptedColumn
if err := json.Unmarshal(serializedData, &ec); err != nil {
t.Fatalf("Error unmarshaling serialized data: %v", err)
}

var ec EncryptedColumn
if err := json.Unmarshal(serializedData, &ec); err != nil {
t.Fatalf("Error unmarshaling serialized data: %v", err)
}
if ec.P != expectedP {
t.Errorf("Expected P to be '%s', got '%s'", expectedP, ec.P)
}

if ec.P != tt.expectedP {
t.Errorf("Expected P to be '%s', got '%s'", tt.expectedP, ec.P)
}
if ec.Q != expectedQ {
t.Errorf("Expected Q to be '%s', got '%s'", expectedQ, ec.Q)
}
}
func TestOreQuerySerialization(t *testing.T) {
value := 123
table := "table1"
column := "column1"
expectedP := "123"
expectedQ := "ore"

serializedData, err := OreQuery(value, table, column)
if err != nil {
t.Fatalf("SerializeQuery returned error: %v", err)
}

var ec EncryptedColumn
if err := json.Unmarshal(serializedData, &ec); err != nil {
t.Fatalf("Error unmarshaling serialized data: %v", err)
}

if ec.P != expectedP {
t.Errorf("Expected P to be '%s', got '%s'", expectedP, ec.P)
}

if ec.Q != expectedQ {
t.Errorf("Expected Q to be '%s', got '%s'", expectedQ, ec.Q)
}
}

func TestUniqueQuerySerialization(t *testing.T) {
value := true
table := "table1"
column := "column1"
expectedP := "true"
expectedQ := "unique"

serializedData, err := UniqueQuery(value, table, column)
if err != nil {
t.Fatalf("SerializeQuery returned error: %v", err)
}

var ec EncryptedColumn
if err := json.Unmarshal(serializedData, &ec); err != nil {
t.Fatalf("Error unmarshaling serialized data: %v", err)
}

if ec.P != expectedP {
t.Errorf("Expected P to be '%s', got '%s'", expectedP, ec.P)
}

if ec.Q != expectedQ {
t.Errorf("Expected Q to be '%s', got '%s'", expectedQ, ec.Q)
}
}

func TestJsonbQuerySerialization(t *testing.T) {
value := map[string]interface{}{"key": "value"}
table := "table1"
column := "column1"
expectedP := `{"key":"value"}`
expectedQ := "ste_vec"

serializedData, err := JsonbQuery(value, table, column)
if err != nil {
t.Fatalf("SerializeQuery returned error: %v", err)
}

var ec EncryptedColumn
if err := json.Unmarshal(serializedData, &ec); err != nil {
t.Fatalf("Error unmarshaling serialized data: %v", err)
}

if ec.P != expectedP {
t.Errorf("Expected P to be '%s', got '%s'", expectedP, ec.P)
}
if ec.Q != expectedQ {
t.Errorf("Expected Q to be '%s', got '%s'", expectedQ, ec.Q)
}
}

Expand All @@ -257,7 +328,7 @@ func TestToEncryptedColumn(t *testing.T) {
}

for _, tt := range tests {
ec, err := ToEncryptedColumn(tt.value, tt.table, tt.column)
ec, err := ToEncryptedColumn(tt.value, tt.table, tt.column, nil)
if err != nil {
t.Fatalf("ToEncryptedColumn returned error: %v", err)
}
Expand Down
Loading
Loading