package sigcred import ( "fmt" "dehub.dev/src/dehub.git/typeobj" ) // Credential represents a credential which has been attached to a commit which // hopefully will allow it to be included in the main. Exactly one field tagged // with "type" should be set. type Credential struct { PGPSignature *CredentialPGPSignature `type:"pgp_signature"` // AccountID specifies the account which generated this Credential. // // NOTE that the Credentials produced by the Signifier.Sign method do not // fill this field in, and it may be empty in cases where a non-account user // has added a credential to a commit. AccountID string `yaml:"account,omitempty"` } // MarshalYAML implements the yaml.Marshaler interface. func (c Credential) MarshalYAML() (interface{}, error) { return typeobj.MarshalYAML(c) } // UnmarshalYAML implements the yaml.Unmarshaler interface. func (c *Credential) UnmarshalYAML(unmarshal func(interface{}) error) error { return typeobj.UnmarshalYAML(c, unmarshal) } // ErrNotSelfVerifying is returned from the SelfVerify method of Credential 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 // 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) } // SelfVerify will attempt to cast the Credential as a SelfVerifyingCredential, // and returns the result of the SelfVerify method being called on it. func (c Credential) SelfVerify(data []byte) error { el, _, err := typeobj.Element(c) if err != nil { return err } else if selfVerifyingCred, ok := el.(SelfVerifyingCredential); !ok { return ErrNotSelfVerifying{Subject: fmt.Sprintf("Credential of type %T", el)} } else if err := selfVerifyingCred.SelfVerify(data); err != nil { return fmt.Errorf("self-verifying Credential of type %T: %w", el, err) } 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 }