1
0
Fork 0
mirror of https://github.com/gocsaf/csaf.git synced 2025-12-22 18:15:42 +01:00

Implement validation for ROLIE json schema

This commit is contained in:
Fadi Abbud 2022-05-16 11:15:46 +02:00
parent c4deef74eb
commit 726711c688
3 changed files with 291 additions and 2 deletions

View file

@ -453,14 +453,37 @@ func (p *processor) processROLIEFeed(feed string) error {
feed, res.StatusCode, res.Status) feed, res.StatusCode, res.Status)
return errContinue return errContinue
} }
rfeed, err := func() (*csaf.ROLIEFeed, error) {
rfeed, rolieDoc, err := func() (*csaf.ROLIEFeed, interface{}, error) {
defer res.Body.Close() defer res.Body.Close()
return csaf.LoadROLIEFeed(res.Body) all, err := io.ReadAll(res.Body)
if err != nil {
return nil, nil, err
}
feed, err := csaf.LoadROLIEFeed(bytes.NewReader(all))
if err != nil {
return nil, nil, err
}
var rolieDoc interface{}
err = json.NewDecoder(bytes.NewReader(all)).Decode(&rolieDoc)
return feed, rolieDoc, err
}() }()
if err != nil { if err != nil {
p.badProviderMetadata.add("Loading ROLIE feed failed: %v.", err) p.badProviderMetadata.add("Loading ROLIE feed failed: %v.", err)
return errContinue return errContinue
} }
errors, err := csaf.ValidateROLIE(rolieDoc)
if err != nil {
return err
}
if len(errors) > 0 {
p.badProviderMetadata.add("%s: Validating against JSON schema failed:", feed)
for _, msg := range errors {
p.badProviderMetadata.add(strings.ReplaceAll(msg, `%`, `%%`))
}
}
base, err := util.BaseURL(feed) base, err := util.BaseURL(feed)
if err != nil { if err != nil {
p.badProviderMetadata.add("Bad base path: %v", err) p.badProviderMetadata.add("Bad base path: %v", err)

View file

@ -0,0 +1,255 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/oasis-tcs/csaf/master/csaf_2.0/json_schema/ROLIE_feed_json_schema.json",
"title": "ROLIE Feed auxiliary Schema",
"description": "Representation of CSAF ROLIE feed as a JSON document.",
"$defs": {
"json_link_t": {
"title": "JSON Link",
"description": "Contains the URL of the JSON file.",
"type": "string",
"format": "uri",
"pattern": "^https://.+\\.json$"
},
"link_t": {
"title": "List of Links",
"description": "Contains a list of links related to the current context.",
"type": "array",
"prefixItems": [
{
"title": "Link",
"description": "Specifies the JSON link.",
"type": "object",
"required": ["rel", "href"],
"properties": {
"href": {
"title": "Hyper reference",
"description": "Contains the URL of the JSON file.",
"$ref": "#/$defs/json_link_t"
},
"rel": {
"title": "Relationship",
"description": "Contains the relationship value of the link.",
"type": "string",
"enum": ["self"]
}
}
}
],
"minItems": 1,
"uniqueItems": true,
"items": {
"title": "Link",
"description": "Specifies a single link.",
"type": "object",
"required": ["rel", "href"],
"properties": {
"href": {
"title": "Hyper reference",
"description": "Contains the URL of the link.",
"type": "string",
"format": "uri"
},
"rel": {
"title": "Relationship",
"description": "Contains the relationship value of the link.",
"type": "string",
"minLength": 1
}
}
}
}
},
"type": "object",
"required": ["feed"],
"properties": {
"feed": {
"title": "CSAF ROLIE feed",
"description": "Contains all information of the feed.",
"type": "object",
"required": ["id", "title", "link", "category", "updated", "entry"],
"properties": {
"id": {
"title": "ID",
"description": "Contains a unique identifier for this ROLIE feed.",
"type": "string",
"pattern": "^[a-zA-Z0-9+\\-_\\.]+$",
"minLength": 1
},
"title": {
"title": "Feed title",
"description": "Contains the title for this ROLIE feed.",
"type": "string",
"minLength": 1
},
"link": {
"title": "List of Links",
"description": "Contains a list of links related to this feed.",
"$ref": "#/$defs/link_t"
},
"category": {
"title": "List of Categories",
"description": "Contains a list of categories related to this feed.",
"type": "array",
"prefixItems": [
{
"title": "CSAF ROLIE category",
"description": "Contains the required ROLIE category value.",
"type": "object",
"required": ["scheme", "term"],
"properties": {
"scheme": {
"title": "Scheme",
"description": "Contains the URI of the scheme to use.",
"type": "string",
"enum": ["urn:ietf:params:rolie:category:information-type"]
},
"term": {
"title": "Term",
"description": "Contains the term that is valid in the context of the scheme.",
"type": "string",
"enum": ["csaf"]
}
}
}
],
"minItems": 1,
"uniqueItems": true,
"items": {
"title": "Category",
"description": "Specifies a single category.",
"type": "object",
"required": ["scheme", "term"],
"properties": {
"scheme": {
"title": "Scheme",
"description": "Contains the URI of the scheme to use.",
"type": "string",
"format": "uri"
},
"term": {
"title": "Term",
"description": "Contains the term that is valid in the context of the scheme.",
"type": "string",
"minLength": 1
}
}
}
},
"updated": {
"title": "Updated",
"description": "Contains the date and time this feed was updated the last time.",
"type": "string",
"format": "date-time"
},
"entry": {
"title": "List of Entries",
"description": "Contains a list of feed entries.",
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"title": "Entry",
"description": "Contains all information for a single feed entry.",
"type": "object",
"required": [
"id",
"title",
"link",
"published",
"updated",
"content",
"format"
],
"properties": {
"id": {
"title": "ID",
"description": "Contains the document tracking ID of the CSAF document.",
"type": "string",
"pattern": "^[\\S](.*[\\S])?$",
"minLength": 1
},
"title": {
"title": "Title",
"description": "Contains the document title of the CSAF document.",
"type": "string",
"minLength": 1
},
"link": {
"title": "List of Links",
"description": "Contains a list of links related to this entry.",
"$ref": "#/$defs/link_t"
},
"published": {
"title": "Published",
"description": "Contains the date and time this entry was initially added to the feed.",
"type": "string",
"format": "date-time"
},
"updated": {
"title": "Updated",
"description": "Contains the date and time this entry was the last time updated in the feed.",
"type": "string",
"format": "date-time"
},
"summary": {
"title": "",
"description": "",
"type": "object",
"properties": {
"content": {
"title": "",
"description": "",
"type": "string",
"minLength": 1
}
}
},
"content": {
"title": "Content of the entry",
"description": "Contains information about the content.",
"type": "object",
"required": ["type", "src"],
"properties": {
"src": {
"title": "Source Code",
"description": "Contains a link to the source code of the file",
"$ref": "#/$defs/json_link_t"
},
"type": {
"title": "MIME type",
"description": "Contains the MIME type of the content.",
"type": "string",
"enum": ["application/json"]
}
}
},
"format": {
"title": "",
"description": "",
"type": "object",
"required": ["schema", "version"],
"properties": {
"schema": {
"title": "Schema of the entry",
"description": "Contains the schema the CSAF document is valid against.",
"type": "string",
"enum": [
"https://docs.oasis-open.org/csaf/csaf/v2.0/csaf_json_schema.json"
]
},
"version": {
"title": "CSAF Version",
"description": "Contains the CSAF version the document was written in.",
"type": "string",
"enum": ["2.0"]
}
}
}
}
}
}
}
}
}
}

View file

@ -36,10 +36,14 @@ var providerSchema []byte
//go:embed schema/aggregator_json_schema.json //go:embed schema/aggregator_json_schema.json
var aggregatorSchema []byte var aggregatorSchema []byte
//go:embed schema/ROLIE_feed_json_schema.json
var rolieSchema []byte
var ( var (
compiledCSAFSchema compiledSchema compiledCSAFSchema compiledSchema
compiledProviderSchema compiledSchema compiledProviderSchema compiledSchema
compiledAggregatorSchema compiledSchema compiledAggregatorSchema compiledSchema
compiledRolieSchema compiledSchema
) )
func init() { func init() {
@ -58,6 +62,9 @@ func init() {
{"https://docs.oasis-open.org/csaf/csaf/v2.0/provider_json_schema.json", providerSchema}, {"https://docs.oasis-open.org/csaf/csaf/v2.0/provider_json_schema.json", providerSchema},
{"https://docs.oasis-open.org/csaf/csaf/v2.0/csaf_json_schema.json", csafSchema}, {"https://docs.oasis-open.org/csaf/csaf/v2.0/csaf_json_schema.json", csafSchema},
}) })
compiledRolieSchema.compiler([]schemaData{
{"https://raw.githubusercontent.com/tschmidtb51/csaf/ROLIE-schema/csaf_2.0/json_schema/ROLIE_feed_json_schema.json", rolieSchema},
})
} }
type schemaData struct { type schemaData struct {
@ -161,3 +168,7 @@ func ValidateProviderMetadata(doc interface{}) ([]string, error) {
func ValidateAggregator(doc interface{}) ([]string, error) { func ValidateAggregator(doc interface{}) ([]string, error) {
return compiledAggregatorSchema.validate(doc) return compiledAggregatorSchema.validate(doc)
} }
func ValidateROLIE(doc interface{}) ([]string, error) {
return compiledRolieSchema.validate(doc)
}