themis_contract

package
v0.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2020 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Update

func Update(loc string, ctx *Context) error

Update will attempt to load the contract at the given location and update the hashes to its parameters and/or template file(s). It necessarily does not do any integrity checks on the parameters and/or template files prior to loading them.

func ValidProfileParamNames

func ValidProfileParamNames() []string

func ValidSignatureParamNames

func ValidSignatureParamNames() []string

Types

type Cache

type Cache interface {
	// FromGit will ensure that the file/folder referenced by the given Git URL
	// is in the cache. On success, returns the file system path to the
	// file/folder requested in the URL.
	FromGit(u *GitURL) (string, error)

	// FromWeb will ensure that the file referenced by the given URL is in the
	// cache. On success, returns the file system path to the file requested in
	// the URL.
	FromWeb(u *url.URL) (string, error)

	// LocalPathForGitURL must return the local filesystem path where the
	// contents of the specified Git repo will be cached.
	LocalPathForGitURL(u *GitURL) string
}

Cache allows us to store and access local copies of remote files/folders.

type Context

type Context struct {
	// contains filtered or unexported fields
}

Context give us all of the necessary configuration/information to facilitate all of our contracting functionality. TODO: Create a file reference resolver interface member to allow for mocking and better testing. TODO: Look at splitting this up as per TODO on InitContext.

func InitContext

func InitContext(home string, autoCommit, autoPush bool) (*Context, error)

InitContext creates a contracting context using the given Themis Contract home directory (usually located at `~/.themis/contract`). TODO: Perhaps this, or parts of this, should exist as its own standalone CLI command? e.g. "themis-contract init"

func (*Context) ActiveProfile

func (ctx *Context) ActiveProfile() *Profile

func (*Context) AddProfile

func (ctx *Context) AddProfile(name, sigID, contractsRepo string) (*Profile, error)

AddProfile will add a profile with the given name and signature ID. The ID of the profile will be derived from its name (slugified).

func (*Context) AddSignature

func (ctx *Context) AddSignature(name, email, sigImage string) (*Signature, error)

func (*Context) CurSignature

func (ctx *Context) CurSignature() (*Signature, error)

CurSignature returns the current signature for the currently selected profile.

func (*Context) GetProfileByID

func (ctx *Context) GetProfileByID(id string) (*Profile, error)

GetProfileByID is a shortcut method to load a profile from our current context whose ID matches the given one.

func (*Context) GetSignatureByID

func (ctx *Context) GetSignatureByID(id string) (*Signature, error)

func (*Context) Profiles

func (ctx *Context) Profiles() []*Profile

Profiles returns all available profiles in this context.

func (*Context) RemoveProfile

func (ctx *Context) RemoveProfile(id string) error

func (*Context) RemoveSignature

func (ctx *Context) RemoveSignature(id string) error

RemoveSignature will attempt to delete the signature with the given ID. If any profiles are still using this signature, the signature will be detached from them and a warning will be generated notifying the user of this.

func (*Context) RenameProfile

func (ctx *Context) RenameProfile(srcID, destName string) error

func (*Context) RenameSignature

func (ctx *Context) RenameSignature(srcID, destName string) error

func (*Context) SetProfileParam

func (ctx *Context) SetProfileParam(profile *Profile, param, val string) error

SetProfileParam will attempt to set the given property of the specified profile to the supplied value. It does not automatically save the profile after setting the value.

func (*Context) SetSignatureParam

func (ctx *Context) SetSignatureParam(sig *Signature, param, val string) error

func (*Context) Signatures

func (ctx *Context) Signatures() ([]*Signature, error)

Signatures returns a list of signatures sorted by signature name.

func (*Context) UseProfile

func (ctx *Context) UseProfile(id string) (*Profile, error)

func (*Context) WithAutoPush

func (ctx *Context) WithAutoPush(autoPush bool) *Context

type Contract

type Contract struct {
	ParamsFile *FileRef  `json:"params" yaml:"params" toml:"params"`       // Where to find the parameters file for the contract.
	Template   *Template `json:"template" yaml:"template" toml:"template"` // The details of the contract text template to use when rendering the contract.
	Upstream   *FileRef  `json:"upstream" yaml:"upstream" toml:"upstream"` // The upstream contract from which this contract has been derived (if any).
	// contains filtered or unexported fields
}

Contract encapsulates all of the relevant data we need in order to deal with the contract (rendering, signature management, etc.).

func Load

func Load(loc string, ctx *Context) (*Contract, error)

Load will parse the contract at the given location into memory. If the location given is remote, the remote contract will be fetched and cached first prior to being opened. All components of the contract, including parameters file and template, will also be fetched if remote.

func New

func New(contractPath, upstreamLoc, gitRemote string, ctx *Context) (*Contract, error)

New creates a new contract in the configured path from the specified upstream contract.

func (*Contract) Compile

func (c *Contract) Compile(output string, ctx *Context) error

Compile takes a parsed contract and attempts to generate the output artifact that constitutes the final contract (as a PDF file).

func (*Contract) Execute

func (c *Contract) Execute(sigID, output string, ctx *Context) error

Execute is a convenience function that will automatically sign and compile the contract. If Git auto-commit and auto-push are on, it also automatically commits changes and pushes them to the source repository.

func (*Contract) FindSignatoryByEmail

func (c *Contract) FindSignatoryByEmail(email string) *Signatory

func (*Contract) FindSignatoryById

func (c *Contract) FindSignatoryById(id string) *Signatory

func (*Contract) Path

func (c *Contract) Path() *FileRef

Path returns the file reference for this contract.

func (*Contract) Render

func (c *Contract) Render(output string) error

Render takes the current contract template and renders it using the current parameters. The output file is the same format as the template, just with all of the parameters substituted in.

func (*Contract) Save

func (c *Contract) Save(ctx *Context) error

Save will write the contract with its current configuration to its local path.

func (*Contract) Sign

func (c *Contract) Sign(signatoryId string, ctx *Context) error

Sign attempts to sign the contract on behalf of the signatory with the given ID. If `sigId` is empty (""), it attempts to infer the signatory on behalf of whom you want to sign based on the default signatory for your current profile.

func (*Contract) Signatories

func (c *Contract) Signatories() []*Signatory

func (*Contract) String

func (c *Contract) String() string

func (*Contract) UpstreamDiff

func (c *Contract) UpstreamDiff(diffProg string, ctx *Context) (*Diff, error)

type Diff

type Diff struct {
	ParamsDiff   string
	TemplateDiff string
}

Diff captures the differences between a contract and its upstream.

type FSCache

type FSCache struct {
	// contains filtered or unexported fields
}

FSCache allows us to cache files and folders we've fetched from remote sources. It caches them locally in the file system.

func OpenFSCache

func OpenFSCache(root string) (*FSCache, error)

OpenFSCache will open an existing file cache at the given path in the file system, or will create the relevant paths/files to facilitate the cache.

func (*FSCache) FromGit

func (c *FSCache) FromGit(u *GitURL) (string, error)

func (*FSCache) FromWeb

func (c *FSCache) FromWeb(u *url.URL) (string, error)

FromWeb attempts to fetch the file at the given URL, caching it locally in the file system. TODO: Implement caching (right now we always just fetch the file).

func (*FSCache) LocalPathForGitURL

func (c *FSCache) LocalPathForGitURL(u *GitURL) string

type FileRef

type FileRef struct {
	Location string `json:"location" yaml:"location" toml:"location"` // A URL or file system path indicating the location of the file.
	Hash     string `json:"hash" yaml:"hash" toml:"hash"`             // The SHA256 hash of the file.
	// contains filtered or unexported fields
}

FileRef is a reference to a local or remote file. It includes an integrity check by way of a mandatory SHA256 hash in the `hash` field.

func LocalFileRef

func LocalFileRef(path string) (*FileRef, error)

LocalFileRef creates a FileRef assuming that the file is in the local file system and is accessible.

func ResolveFileRef

func ResolveFileRef(loc, expectedHash string, checkHash bool, ctx *Context) (resolved *FileRef, err error)

ResolveFileRef will attempt to resolve the file at the given location. If it is a remote file, it will be fetched from its location and cached locally using the given cache.

func ResolveRelFileRef

func ResolveRelFileRef(abs, rel *FileRef, checkHash bool, ctx *Context) (resolved *FileRef, err error)

ResolveRelFileRef attempts to resolve a file reference relative to another one. Specifically, it will attempt to resolve `rel` against `abs`. TODO: Implement security check here to prevent user escaping to host file system.

func (*FileRef) CopyTo

func (r *FileRef) CopyTo(destPath string) error

CopyTo will attempt to copy the locally cached version of this file to the given destination path. It is assumed that the destination path includes the full file name of the desired destination file.

func (*FileRef) Dir

func (r *FileRef) Dir() string

Dir returns just the directory name portion of the local copy of the file.

func (*FileRef) Ext

func (r *FileRef) Ext() string

Ext returns the extension of the file.

func (*FileRef) Filename

func (r *FileRef) Filename() string

Filename returns just the file name portion of the local copy of the file.

func (*FileRef) IsRelative

func (r *FileRef) IsRelative() bool

IsRelative provides a simple check to see whether this file reference is relative to another file reference.

func (*FileRef) LocalRelPath

func (r *FileRef) LocalRelPath(base string) (string, error)

LocalRelPath returns the path of the local copy of this file relative to the specified base file's path.

func (*FileRef) ReadAll

func (r *FileRef) ReadAll() (string, error)

ReadAll attempts to read the contents of the local copy of the file into memory as a string.

func (*FileRef) String

func (r *FileRef) String() string

func (*FileRef) Type

func (r *FileRef) Type() FileRefType

type FileRefType

type FileRefType string
const (
	ProfileContractRef FileRefType = "profile"
	LocalRef           FileRefType = "local"
	WebRef             FileRefType = "web"
	GitRef             FileRefType = "git"
)

type FileType

type FileType string

FileType indicates the file type of a contract.

const (
	DhallType FileType = "dhall"
	JSONType  FileType = "json"
	YAMLType  FileType = "yaml"
	TOMLType  FileType = "toml"
)

type GitURL

type GitURL struct {
	Proto GitURLProto `json:"proto"` // The protocol by which we want to access the Git repository.
	User  string      `json:"user"`  // The username of the user as whom to clone the repository.
	Host  string      `json:"host"`  // The host URL (e.g. "github.com" or "gitlab.com").
	Port  uint16      `json:"port"`  // The port (default: 22 for SSH, 443 for HTTPS).
	Repo  string      `json:"repo"`  // The repository path (e.g. for GitHub this is `user_name/repo_name.git`).
	Path  string      `json:"path"`  // The file/folder path within the repository.
	Ref   string      `json:"ref"`   // The branch, commit reference or tag, if any.
}

GitURL allows us to parse out the components of a Git repository URL. The format for a Git URL is different to a standard URL, so we unfortunately can't use Golang's standard URL parsing.

func ParseGitURL

func ParseGitURL(rawurl string) (*GitURL, error)

ParseGitURL will parse the specified raw URL into a GitURL object, which breaks down the different components of a Git repository URL. At present, it just always assumes that HTTPS repositories are cloned on port 443 and SSH ones on port 22.

func (*GitURL) RepoURL

func (u *GitURL) RepoURL() string

func (*GitURL) String

func (u *GitURL) String() string

type GitURLProto

type GitURLProto string
const (
	ProtoSSH   GitURLProto = "git"
	ProtoHTTPS GitURLProto = "https"
)

type Profile

type Profile struct {
	Name          string             `json:"name"`                   // A short, descriptive name for the profile.
	ContractsRepo string             `json:"contracts_repo"`         // The default contracts repository for this profile.
	Contracts     []*ProfileContract `json:"contracts,omitempty"`    // A cached list of contracts we've discovered in our contracts repo.
	SignatureID   string             `json:"signature_id,omitempty"` // The ID of the signature to use when signing using this profile.
	// contains filtered or unexported fields
}

Profile is a way of naming and differentiating between rendering configurations used when rendering contracts.

func (*Profile) Display

func (p *Profile) Display() string

Display shows a more human-readable description of the profile than String() does.

func (*Profile) ID

func (p *Profile) ID() string

func (*Profile) Path

func (p *Profile) Path() string

func (*Profile) Save

func (p *Profile) Save() error

func (*Profile) String

func (p *Profile) String() string

func (*Profile) SyncContractsRepo

func (p *Profile) SyncContractsRepo(ctx *Context) error

type ProfileByName

type ProfileByName []*Profile

func (ProfileByName) Len

func (p ProfileByName) Len() int

func (ProfileByName) Less

func (p ProfileByName) Less(i, j int) bool

func (ProfileByName) Swap

func (p ProfileByName) Swap(i, j int)

type ProfileContract

type ProfileContract struct {
	ID string `json:"id"` // A unique identifier for this contract.
	// contains filtered or unexported fields
}

ProfileContract

func (*ProfileContract) URL

func (c *ProfileContract) URL() string

type ProfileContractByID

type ProfileContractByID []*ProfileContract

func (ProfileContractByID) Len

func (c ProfileContractByID) Len() int

func (ProfileContractByID) Less

func (c ProfileContractByID) Less(i, j int) bool

func (ProfileContractByID) Swap

func (c ProfileContractByID) Swap(i, j int)

type ProfileDB

type ProfileDB struct {
	ActiveProfileID string `json:"active_profile_id"` // The ID of the profile currently active. Can be empty if none active.
	// contains filtered or unexported fields
}

ProfileDB allows us to manage our local database of profiles.

type ProfileParameter

type ProfileParameter string
const (
	ProfileSignatureID   ProfileParameter = "signature-id"
	ProfileContractsRepo ProfileParameter = "contracts-repo"
)

type Signatory

type Signatory struct {
	Id    string `json:"id" yaml:"id" toml:"id"`
	Name  string `json:"name" yaml:"name" toml:"name"`
	Email string `json:"email" yaml:"email" toml:"email"`

	Signature  string `json:"signature,omitempty" yaml:"signature,omitempty" toml:"signature,omitempty"`       // The path to the image to use for this person's signature.
	SignedDate string `json:"signed_date,omitempty" yaml:"signed_date,omitempty" toml:"signed_date,omitempty"` // The date on which the signature was created.
}

Signatory captures the minimum amount of information about a specific signatory who is required to sign a contract.

func (*Signatory) String

func (s *Signatory) String() string

type Signature

type Signature struct {
	Name      string `json:"name"`  // A short, descriptive name for the signature.
	Email     string `json:"email"` // The e-mail address associated with a specific signature.
	ImagePath string `json:"image"` // The filesystem path to the image constituting the image-based signature.
	// contains filtered or unexported fields
}

Signature is what we apply to a contract to sign it. TODO: Investigate GPG-based signing.

func (*Signature) Display

func (s *Signature) Display() string

func (*Signature) Save

func (s *Signature) Save() error

func (*Signature) String

func (s *Signature) String() string

type SignatureByName

type SignatureByName []*Signature

func (SignatureByName) Len

func (n SignatureByName) Len() int

func (SignatureByName) Less

func (n SignatureByName) Less(i, j int) bool

func (SignatureByName) Swap

func (n SignatureByName) Swap(i, j int)

type SignatureDB

type SignatureDB struct {
	// contains filtered or unexported fields
}

SignatureDB is a local database of signatures which can be applied to contracts when signing.

type SignatureParameter

type SignatureParameter string
const (
	SignatureEmail SignatureParameter = "email"
	SignatureImage SignatureParameter = "image"

	SignatureTimestampFormat = "2 January 2006"
)

type Template

type Template struct {
	Format TemplateFormat `json:"format" yaml:"format" toml:"format"`
	File   *FileRef       `json:"file" yaml:"file" toml:"file"`
}

Template refers to the contract text template to use when rendering a contract. TODO: Use a list of files for the template as opposed to a single one to allow for complex templates.

func (*Template) String

func (t *Template) String() string

type TemplateFormat

type TemplateFormat string

TemplateFormat is a string-based enumeration type.

const (
	Mustache TemplateFormat = "Mustache"
)

For this version of the prototype, we currently only support Mustache templating. TODO: Consider whether Handlebars support is actually required. TODO: Consider Jinja2-like support (e.g. Pongo2: https://github.com/flosch/pongo2).

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL