1
0
Fork 0
mirror of https://github.com/gocsaf/csaf.git synced 2025-12-22 11:55:40 +01:00

Added files from the first prototype.

This commit is contained in:
Sascha L. Teichmann 2021-11-16 13:58:54 +01:00
parent c2a483fc95
commit fed66c4e27
13 changed files with 1529 additions and 0 deletions

View file

@ -0,0 +1,126 @@
package main
import (
"bytes"
"context"
"encoding/json"
"errors"
"time"
"github.com/PaesslerAG/gval"
"github.com/PaesslerAG/jsonpath"
"github.com/intevation/csaf_trusted/csaf"
)
const (
idExpr = `$.document.tracking.id`
titleExpr = `$.document.title`
publisherExpr = `$.document.publisher`
initialReleaseDateExpr = `$.document.tracking.initial_release_date`
currentReleaseDateExpr = `$.document.tracking.current_release_date`
tlpLabelExpr = `$.document.distribution.tlp.label`
summaryExpr = `$.document.notes[? @.category=="summary" || @.type=="summary"].text`
)
type extraction struct {
id string
title string
publisher *csaf.CSAFPublisher
initialReleaseDate time.Time
currentReleaseDate time.Time
summary string
tlpLabel string
}
func newExtraction(content interface{}) (*extraction, error) {
builder := gval.Full(jsonpath.Language())
e := new(extraction)
for _, fn := range []func(*gval.Language, interface{}) error{
extractText(idExpr, &e.id),
extractText(titleExpr, &e.title),
extractTime(currentReleaseDateExpr, &e.currentReleaseDate),
extractTime(initialReleaseDateExpr, &e.initialReleaseDate),
extractText(summaryExpr, &e.summary),
extractText(tlpLabelExpr, &e.tlpLabel),
e.extractPublisher,
} {
if err := fn(&builder, content); err != nil {
return nil, err
}
}
return e, nil
}
func extractText(
expr string,
store *string,
) func(*gval.Language, interface{}) error {
return func(builder *gval.Language, content interface{}) error {
eval, err := builder.NewEvaluable(expr)
if err != nil {
return err
}
s, err := eval(context.Background(), content)
if text, ok := s.(string); ok && err == nil {
*store = text
}
return nil
}
}
func extractTime(
expr string,
store *time.Time,
) func(*gval.Language, interface{}) error {
return func(builder *gval.Language, content interface{}) error {
eval, err := builder.NewEvaluable(expr)
if err != nil {
return err
}
s, err := eval(context.Background(), content)
if err != nil {
return err
}
text, ok := s.(string)
if !ok {
return errors.New("not a string")
}
date, err := time.Parse(dateFormat, text)
if err == nil {
*store = date.UTC()
}
return err
}
}
func (e *extraction) extractPublisher(
builder *gval.Language,
content interface{},
) error {
eval, err := builder.NewEvaluable(publisherExpr)
if err != nil {
return err
}
p, err := eval(context.Background(), content)
if err != nil {
return err
}
// XXX: It's a bit cumbersome to serialize and deserialize
// it into our own structure.
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
if err := enc.Encode(p); err != nil {
return err
}
e.publisher = new(csaf.CSAFPublisher)
if err := json.Unmarshal(buf.Bytes(), e.publisher); err != nil {
return err
}
return e.publisher.Validate()
}