Envelope

Envelope is the data structure that defines the input data and the operations that will be executed on that data.

// Envelope can contain both encrypted and unencrypted data
// and the operations to be performed on it.
type Envelope struct {
    // Data contains information that can be encrypted or decrypted.
    Data map[string]string `json:"data"`

    // Operations that are applied (in order) to the envelope's Data.
    Operations []Operation `json:"ops,omitempty"`
}

// Operation describes a mutation performed on data. Only a single operation
// can be performed at a time.
type Operation struct {
    // DataLocation specifies which data operations should be performed on.
    DataLocation

    // Encrypt uses a cipher on a plaintext.
    Encrypt *Encrypt `json:"encrypt,omitempty"`

    // Decrypt uses a cipher on a ciphertext.
    Decrypt *Decrypt `json:"decrypt,omitempty"`

    // Errors from executing an operation.
    Errors []OperationError `json:"errors,omitempty"`
}

// DataLocation provides a mapping for operations of the data section.
type DataLocation struct {
    // Source is the field name in data of the plaintext.
    Source string `json:"src"`

    // Destination is the field name in data that the ciphertext is written to.
    Destination string `json:"dest"`
}
import (
    "reflect"
    "github.com/ume/api/pkg/mirror"
)

func HandleFormSubmission(form *Form) {
    // form = {name: Ada, email: [email protected]}
    formData := form.ToMap()
    envelope := mirror.Envelope{
        Data: formData,
        Operations: []mirror.Operation{
            {
                DataLocation: mirror.DataLocation{Source: "*"},
                Encrypt: &mirror.Encrypt{
                    KeySpec: &mirror.KeySpec{SensitivityLevel: "low"},
                },
            },
        },
    }

    envelope.Expand()
    envelope.Execute()

    originalName := form.Get("name")
    originalEmail := form.Get("email")

    if assertNotEqual(originalName, envelope.Data["name"]) &&
        assertNotEqual(originalEmail, envelope.Data["email"]) {
        // Form data was successfully encrypted
    }
}

func assertNotEqual(expected, actual interface{}) bool {
    isEqual := reflect.DeepEqual(expected, actual)

    return !isEqual
}

Before

{
  "data": {
    "name": "Ada",
    "email": "[email protected]"
  },
  "ops": [
    {
      "src": "*",
      "encrypt": {
        "key_spec": { "sensitivity_level": "low" }
      }
    }
  ]
}

After

{
  "data": {
    "name": "8J-c902frj3vm2sicz",
    "email": "8J-mdkso02ef20213l"
  },
  "ops": []
}