Documentation
¶
Overview ¶
Package stashgen is the Stack Encrypt code generator for Go, as a library.
A struct's stash tags declare how each field is encrypted. FromTags reads those tags through go/packages and go/types, checks the declaration with an Engine, and returns the file that the command stashgen writes beside the struct: the encrypted type, Encrypt, Decrypt, Fields and the print methods. The command at languages/golang/cmd/stashgen is the go:generate front end for this package.
The generator reads types, not text, and runs none of the package's code. It ignores its own output file when it loads the package, so a stale generated file does not stop it. The same input always gives the same file: fields keep their declared order, and the file carries no version and no time beyond the gensupport.GeneratedVersion1 constant it names.
Generate writes the same file for a type that cannot carry tags, from a policy in package encrypt/policy: a source gives the facts about each field and the policy's rules decide them. A decision spells itself in the tag grammar, so both paths go through one parser and one emitter.
Every refusal about an index, an EQL type or a field type comes from the Engine. The generator holds no copy of the engine's rules.
Index ¶
- func EQLGoName(name string) string
- func Generate(ctx context.Context, source policy.Source, message policy.Message, ...) error
- type Declaration
- type EQLType
- type Engine
- type Field
- type FieldError
- type File
- type GenerateOption
- type GoType
- type Index
- type IndexName
- type Kind
- type ModelRequest
- type Option
- type Request
- type Verb
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EQLGoName ¶
EQLGoName is the Go type name in encrypt/eql of an EQL type the engine names: the same name in every language, save the JSON family, whose Go names start with JSON (Json is JSON), as Go spells initialisms. The generated encrypt/eql package follows the same rule (eql-codegen's go_eql renderer), and its Types table records both names, which is what holds the two in agreement (a test in cmd/stashgen reads it; this package's own tests cannot link encrypt/eql without changing the engine they test).
func Generate ¶
func Generate(ctx context.Context, source policy.Source, message policy.Message, output string, opts ...GenerateOption) error
Generate writes the generated file for a message from a policy to output: the source gives the facts about each field, the message's rules decide each one, and the file is the same one stashgen writes from tags. The generated functions take and return pointers to the message. output goes in a package of your own, not in the package of the generated type, so the generate program never imports a file that it wrote.
Every field of the message needs a decision. A field that no rule decides stops the generator with the field's name and its annotations, and so does a field that a rule refuses with Fail.
Types ¶
type Declaration ¶
type Declaration struct {
// Type is the Go type the declaration is for, as the generator prints it
// in an error: "User" or "crm.Contact".
Type string
// Context is the context of every field, from the `context=` tag; ""
// when ContextField is set.
Context string
// ContextField is the declaration name of the field whose value is the
// context of every other field, from the `context_field` tag; "" when
// the context comes from Context. The field is a string, stored as it
// is, in the clear and unauthenticated like a passthrough.
ContextField string
// Opaque seals the whole struct as one value. The fields then carry no
// tags and no indexes.
Opaque bool
// Fields are the struct's fields in declared order, omitted ones included.
Fields []Field
}
Declaration is how each field of one struct is encrypted: the context of the struct, and the verb, indexes and EQL type of each field. The generator builds it from the stash tags, the engine checks it, and the generated file holds it as data that only generated code uses.
type EQLType ¶
type EQLType struct {
// Name is the Go type name in encrypt/eql, and the value of encrypt_into.
Name string
// Plaintext is the kind of Go value the type seals.
Plaintext Kind
// Indexes are the terms the type carries.
Indexes []IndexName
// Query is the Go type name of the type's query value, such as
// TextEqQuery, or "" for a type with no terms.
Query string
// Producible says whether this build of the engine produces the type;
// Reason says why not when it does not.
Producible bool
Reason string
}
EQLType is one EQL type the engine produces, such as TextEq.
type Engine ¶
type Engine interface {
// EQLTypes lists the EQL types the engine can produce: each name, its
// plaintext kind, its indexes and its query type.
EQLTypes(ctx context.Context) ([]EQLType, error)
// Check refuses a declaration the engine cannot run: an index or an EQL
// type that does not apply to a field's Go type, a field type it cannot
// seal, an EQL type it cannot produce, or an index option it cannot
// carry. The error names the field.
Check(ctx context.Context, d Declaration) error
}
Engine answers the generator's questions about what the Rust engine can do. The generator holds no copy of the engine's rules: every refusal about an index, an EQL type or a field type comes from here.
GuestEngine is the SDK's implementation: the WASI guest that package encrypt embeds, asked through se_plan_check and se_targets.
type Field ¶
type Field struct {
// Name is the field's name in the declaration, which is its column name.
// An omitted field's Name is its Go name in snake case.
Name string
// GoName is the field's name in the Go struct.
GoName string
// GoType is the field's Go type, for the engine's checks.
GoType GoType
// Verb says what happens to the field.
Verb Verb
// Indexes are the indexes the tag names, for EncryptIndex and Index.
Indexes []Index
// EQLType is the EQL type an EncryptInto field seals into.
EQLType string
// Identity is the field's part of its context when it differs from Name:
// a column that was renamed keeps the identity it was first written
// under. "" means Name. Only a policy sets it.
Identity string
}
Field is one field of a declaration.
func (Field) HasCiphertext ¶
HasCiphertext reports whether the field's outputs include a ciphertext.
type FieldError ¶
type FieldError struct {
// Type is the Go type the field belongs to: "User" or "crm.Contact".
Type string
// Field is the Go name of the field, or "" for a mistake about the type.
Field string
// Reason says what is wrong, without the type and field.
Reason string
}
FieldError is a mistake in one field's declaration. Every refusal names the type and the field, and never a value.
func (*FieldError) Error ¶
func (e *FieldError) Error() string
type File ¶
type File struct {
// Path is where the file goes.
Path string
// Content is the formatted Go source.
Content []byte
// Notices are what the generator prints to stderr: the unexported fields
// it ignored, and a type that prints its sealed fields.
Notices []string
}
File is a generated file, ready to write.
func FromTags ¶
FromTags generates the file for the struct named in the request. It loads the package with go/packages and reads types, not text; it runs none of the package's code; it checks the declaration with the engine; and it returns the file without writing it. The same request always gives the same file.
type GenerateOption ¶
type GenerateOption func(*generateConfig)
GenerateOption configures Generate.
func WithEngine ¶
func WithEngine(e Engine) GenerateOption
WithEngine checks the declaration with this engine instead of the one the SDK embeds.
func WithName ¶
func WithName(name string) GenerateOption
WithName gives the generated names a prefix, as -name does on the tag path: WithName("Individual") writes EncryptIndividual, DecryptIndividual and IndividualFields. A package holds one Encrypt, so the second message generated into one package needs a name.
func WithNotices ¶
func WithNotices(w io.Writer) GenerateOption
WithNotices sends the generator's notices here instead of stderr.
type GoType ¶
type GoType struct {
// Name is the type as Go source in the field's package: "string",
// "int64", "[]string", "time.Time", "crm.Address".
Name string
// Kind is the type's underlying kind.
Kind Kind
// Basic is the underlying basic type's name for a scalar kind — "uint8",
// "int", "string" — which decides the wire type the field seals as.
Basic string
// Elem is the element type of a slice, map or pointer, and nil otherwise.
Elem *GoType
// Fields are the fields of a struct kind, in declared order.
Fields []GoType
}
GoType describes a field's Go type to the engine without go/types.
type IndexName ¶
type IndexName string
IndexName is the tag word for an index. The words are the Rust API's.
type Kind ¶
type Kind uint8
Kind is the underlying kind of a Go type, as far as the engine needs it.
const ( // KindOther is a kind the engine cannot seal: a channel, a function, an // interface, a complex number, or a struct with an unexported field. KindOther Kind = iota KindString KindBool KindInt KindUint KindFloat // KindBytes is []byte. KindBytes KindSlice KindMap KindPointer // KindStruct is a struct whose fields are all exported. KindStruct )
type ModelRequest ¶
type ModelRequest struct {
// Name is the suffix of the generated functions: EncryptName, DecryptName.
Name string
// Type is the model struct, in this package or as P.T.
Type string
// Declares is a struct in this package that carries the tags for a Type
// that cannot, or "".
Declares string
}
ModelRequest is one -model flag: a struct with one field for each column, for separate columns.
func ParseModelFlag ¶
func ParseModelFlag(s string) (ModelRequest, error)
ParseModelFlag reads a -model flag: Name=R or Name=R:D.
type Request ¶
type Request struct {
// Dir is the directory of the package. "" is the working directory.
Dir string
// Type is the struct that carries the stash tags.
Type string
// Name, when set, writes EncryptName, DecryptName and NameFields.
Name string
// For, as P.F, is the type in another package that Type declares for.
For string
// Models are the -model flags.
Models []ModelRequest
// Redact writes String and LogValue methods on Type.
Redact bool
// Output is the file to write, relative to Dir. "" is the type's name in
// lower case with _stash.go.
Output string
}
Request is one run of the generator over one tagged struct. The command fills it from its flags.
func (Request) OutputPath ¶
OutputPath is the file the request writes, relative to Dir.
type Verb ¶
type Verb uint8
Verb is what happens to a field.
const ( // VerbOmit leaves the field out: it does not cross the binding. VerbOmit Verb = iota // VerbPassthrough stores the field as it is. VerbPassthrough // VerbEncrypt seals the field with no index. VerbEncrypt // VerbEncryptIndex seals the field and derives each index beside it. VerbEncryptIndex // VerbIndex derives the indexes alone, with no ciphertext. VerbIndex // VerbEncryptInto seals the field into one EQL value. VerbEncryptInto // VerbContextField stores the field as it is, and its value is the // context every other field is sealed under. VerbContextField )
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package enginetest is a static stand-in for the Rust engine in the generator's tests.
|
Package enginetest is a static stand-in for the Rust engine in the generator's tests. |