2020-02-15 22:13:50 +00:00
|
|
|
package sigcred
|
|
|
|
|
2020-04-11 23:10:18 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"dehub.dev/src/dehub.git/typeobj"
|
|
|
|
)
|
2020-02-15 22:13:50 +00:00
|
|
|
|
2020-04-26 20:23:03 +00:00
|
|
|
// CredentialUnion represents a credential, signifying a user's approval of a
|
|
|
|
// payload. Exactly one field tagged with "type" should be set.
|
|
|
|
type CredentialUnion struct {
|
2020-02-15 22:13:50 +00:00
|
|
|
PGPSignature *CredentialPGPSignature `type:"pgp_signature"`
|
|
|
|
|
2020-04-26 20:23:03 +00:00
|
|
|
// AccountID specifies the account which generated this CredentialUnion.
|
2020-04-11 23:10:18 +00:00
|
|
|
//
|
2020-04-26 20:23:03 +00:00
|
|
|
// NOTE that credentials produced by the direct implementations of Signifier
|
|
|
|
// won't fill in this field, unless specifically documented. The Signifier
|
|
|
|
// produced by the Signifier() method of SignifierUnion _will_ fill this
|
|
|
|
// field in, however.
|
2020-04-11 23:10:18 +00:00
|
|
|
AccountID string `yaml:"account,omitempty"`
|
2020-04-12 17:59:23 +00:00
|
|
|
|
|
|
|
// AnonID specifies an identifier for the anonymous user which produced this
|
|
|
|
// credential. This field is mutually exclusive with AccountID, and won't be
|
2020-04-26 20:23:03 +00:00
|
|
|
// set by any Signifier implementation unless specifically documented.
|
2020-04-12 17:59:23 +00:00
|
|
|
AnonID string `yaml:"-"`
|
2020-02-15 22:13:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// MarshalYAML implements the yaml.Marshaler interface.
|
2020-04-26 20:23:03 +00:00
|
|
|
func (c CredentialUnion) MarshalYAML() (interface{}, error) {
|
2020-02-15 22:13:50 +00:00
|
|
|
return typeobj.MarshalYAML(c)
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
2020-04-26 20:23:03 +00:00
|
|
|
func (c *CredentialUnion) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
2020-02-15 22:13:50 +00:00
|
|
|
return typeobj.UnmarshalYAML(c, unmarshal)
|
|
|
|
}
|
2020-04-11 23:10:18 +00:00
|
|
|
|
2020-04-26 20:23:03 +00:00
|
|
|
// ErrNotSelfVerifying is returned from the SelfVerify method of CredentialUnion
|
|
|
|
// when the credential does not implement the SelfVerifyingCredential interface.
|
|
|
|
// It may also be returned from the SelfVerify method of the
|
|
|
|
// SelfVerifyingCredential itself, if the credential can only self-verify under
|
2020-04-11 23:10:18 +00:00
|
|
|
// certain circumstances.
|
|
|
|
type ErrNotSelfVerifying struct {
|
|
|
|
// Subject is a descriptor of the value which could not be verified. It may
|
|
|
|
// be a type name or some other identifying piece of information.
|
|
|
|
Subject string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e ErrNotSelfVerifying) Error() string {
|
|
|
|
return fmt.Sprintf("%s cannot verify itself", e.Subject)
|
|
|
|
}
|
|
|
|
|
2020-04-26 20:23:03 +00:00
|
|
|
// SelfVerify will attempt to cast the credential as a SelfVerifyingCredential,
|
2020-04-11 23:10:18 +00:00
|
|
|
// and returns the result of the SelfVerify method being called on it.
|
2020-04-26 20:23:03 +00:00
|
|
|
func (c CredentialUnion) SelfVerify(data []byte) error {
|
2020-04-11 23:10:18 +00:00
|
|
|
el, _, err := typeobj.Element(c)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
} else if selfVerifyingCred, ok := el.(SelfVerifyingCredential); !ok {
|
2020-04-26 20:23:03 +00:00
|
|
|
return ErrNotSelfVerifying{Subject: fmt.Sprintf("credential of type %T", el)}
|
2020-04-11 23:10:18 +00:00
|
|
|
} else if err := selfVerifyingCred.SelfVerify(data); err != nil {
|
2020-04-26 20:23:03 +00:00
|
|
|
return fmt.Errorf("self-verifying credential of type %T: %w", el, err)
|
2020-04-11 23:10:18 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// SelfVerifyingCredential is one which is able to prove its own authenticity by
|
|
|
|
// some means or another. It is not required for a Credential to implement this
|
|
|
|
// interface.
|
|
|
|
type SelfVerifyingCredential interface {
|
|
|
|
// SelfVerify should return nil if the Credential has successfully verified
|
|
|
|
// that it has accredited the given data, or an error describing why it
|
|
|
|
// could not do so. It may return ErrNotSelfVerifying if the Credential can
|
|
|
|
// only self-verify under certain circumstances, and those circumstances are
|
|
|
|
// not met.
|
|
|
|
SelfVerify(data []byte) error
|
|
|
|
}
|