diff --git a/pkg/jsonsign/signhandler/sig.go b/pkg/jsonsign/signhandler/sig.go index 3ecf8d9dc..3be3a1d5d 100644 --- a/pkg/jsonsign/signhandler/sig.go +++ b/pkg/jsonsign/signhandler/sig.go @@ -255,5 +255,13 @@ func (h *Handler) Sign(bb *schema.Builder) (string, error) { ServerMode: true, SecretKeyringPath: h.secretRing, } + claimTime, err := bb.Blob().ClaimDate() + if err != nil { + if !schema.IsMissingField(err) { + return "", err + } + } else { + sreq.SignatureTime = claimTime + } return sreq.Sign() } diff --git a/pkg/schema/blob.go b/pkg/schema/blob.go index d664da902..eb6a6c4bf 100644 --- a/pkg/schema/blob.go +++ b/pkg/schema/blob.go @@ -27,6 +27,19 @@ import ( "camlistore.org/pkg/blobref" ) +// A MissingFieldError represents a missing JSON field in a schema blob. +type MissingFieldError string + +func (e MissingFieldError) Error() string { + return fmt.Sprintf("schema: missing field %q", string(e)) +} + +// IsMissingField returns whether error is of type MissingFieldError. +func IsMissingField(err error) bool { + _, ok := err.(MissingFieldError) + return ok +} + // AnyBlob represents any type of schema blob. type AnyBlob interface { Blob() *Blob @@ -73,6 +86,17 @@ func (b *Blob) FileName() string { return b.ss.FileNameString() } +// ClaimDate returns the "claimDate" field. +// If there is no claimDate, the error will be a MissingFieldError. +func (b *Blob) ClaimDate() (time.Time, error) { + var ct time.Time + claimDate := b.ss.ClaimDate + if claimDate == "" { + return ct, MissingFieldError("claimDate") + } + return time.Parse(time.RFC3339, claimDate) +} + // ByteParts returns the "parts" field. The caller owns the returned // slice. func (b *Blob) ByteParts() []BytesPart {