-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from ossf/feat/v2
feat: Added go package to support v2 ingestion
- Loading branch information
Showing
10 changed files
with
268 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/ossf/si-tooling | ||
|
||
go 1.23 | ||
|
||
require gopkg.in/yaml.v3 v3.0.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package si | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
|
||
"gopkg.in/yaml.v3" | ||
) | ||
|
||
type FileAPIResponse struct { | ||
ByteContent []byte `json:"content"` | ||
SHA string `json:"sha"` | ||
} | ||
|
||
type SIBuilder struct { | ||
TargetSI SecurityInsights | ||
ParentSI SecurityInsights | ||
} | ||
|
||
func makeApiCall(endpoint, token string) (bytes []byte, err error) { | ||
request, err := http.NewRequest("GET", endpoint, nil) | ||
if err != nil { | ||
return | ||
} | ||
if token != "" { | ||
request.Header.Set("Authorization", "Bearer "+token) | ||
} | ||
client := &http.Client{} | ||
response, err := client.Do(request) | ||
if err != nil { | ||
err = fmt.Errorf("error making http call: %s", err.Error()) | ||
return | ||
} | ||
if response.StatusCode != 200 { | ||
err = fmt.Errorf("unexpected response: %s", response.Status) | ||
return | ||
} | ||
return io.ReadAll(response.Body) | ||
} | ||
|
||
func getGitHubSourceFile(endpoint string) (response FileAPIResponse, err error) { | ||
responseData, err := makeApiCall("https://api.github.com/"+endpoint, "") | ||
if err != nil { | ||
return | ||
} | ||
err = json.Unmarshal(responseData, &response) | ||
return | ||
} | ||
|
||
func Read(owner, repo, path string) (si SecurityInsights, err error) { | ||
var builder SIBuilder | ||
// Get Target SI | ||
response, err := getGitHubSourceFile(fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)) | ||
if err != nil { | ||
err = fmt.Errorf("error reading target SI: %s", err.Error()) | ||
return | ||
} | ||
|
||
err = yaml.Unmarshal(response.ByteContent, &builder.TargetSI) | ||
if err != nil { | ||
err = fmt.Errorf("error unmarshalling target SI: %s", err.Error()) | ||
return | ||
} | ||
|
||
// check for parent SI, read if exists | ||
if builder.TargetSI.Header.ProjectSISource != "" { | ||
response, err = getGitHubSourceFile(builder.TargetSI.Header.ProjectSISource) | ||
if err != nil { | ||
err = fmt.Errorf("error reading parent SI: %s", err.Error()) | ||
return | ||
} | ||
err = yaml.Unmarshal(response.ByteContent, &builder.ParentSI) | ||
if err != nil { | ||
err = fmt.Errorf("error unmarshalling parent SI: %s", err.Error()) | ||
return | ||
} | ||
} | ||
|
||
// Override target SI project data with contents of parent SI project data | ||
builder.TargetSI.Project = builder.ParentSI.Project | ||
|
||
return builder.TargetSI, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package si | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
) | ||
|
||
func TestRead(t *testing.T) { | ||
testData := []struct { | ||
owner string | ||
repo string | ||
path string | ||
}{ | ||
{"ossf", "security-insights-spec", ".github/security-insights.yml"}, | ||
} | ||
|
||
for _, tt := range testData { | ||
t.Run(fmt.Sprintf("Read(%s, %s, %s)", tt.owner, tt.repo, tt.path), func(t *testing.T) { | ||
// TODO: Add real test cases | ||
out, err := Read(tt.owner, tt.repo, tt.path) | ||
if err != nil { | ||
t.Errorf("Read() error = %v", err) | ||
return | ||
} | ||
fmt.Print(out) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package si | ||
|
||
type SecurityInsights struct { | ||
Header Header `yaml:"header"` | ||
Project Project `yaml:"project"` | ||
Repository Repository `yaml:"repository"` | ||
} | ||
|
||
type Header struct { | ||
LastReviewed string `yaml:"last-reviewed"` | ||
LastUpdated string `yaml:"last-updated"` | ||
SchemaVersion string `yaml:"schema-version"` | ||
URL string `yaml:"url"` | ||
Comment string `yaml:"comment"` | ||
ProjectSISource string `yaml:"project-si-source"` | ||
} | ||
|
||
type Assessment struct { | ||
Comment string `yaml:"comment"` | ||
Name string `yaml:"name"` | ||
Evidence string `yaml:"evidence"` | ||
Date string `yaml:"date"` | ||
} | ||
|
||
type Attestation struct { | ||
Name string `yaml:"name"` | ||
Location string `yaml:"location"` | ||
PredicateURI string `yaml:"predicate-uri"` | ||
Comment string `yaml:"comment"` | ||
} | ||
|
||
type Contact struct { | ||
Name string `yaml:"name"` | ||
Primary bool `yaml:"primary"` | ||
Affiliation string `yaml:"affiliation"` | ||
Email string `yaml:"email"` | ||
Social string `yaml:"social"` | ||
} | ||
|
||
type License struct { | ||
URL string `yaml:"url"` | ||
Expression string `yaml:"expression"` | ||
} | ||
|
||
type Link struct { | ||
URI string `yaml:"uri"` | ||
Comment string `yaml:"comment"` | ||
} | ||
|
||
type Project struct { | ||
Name string `yaml:"name"` | ||
Homepage string `yaml:"homepage"` | ||
Roadmap string `yaml:"roadmap"` | ||
Funding string `yaml:"funding"` | ||
Administrators []Contact `yaml:"administrators"` | ||
Repositories []Repo `yaml:"repositories"` | ||
Vulnerability VulnReport `yaml:"vulnerability-reporting"` | ||
Documentation Docs `yaml:"documentation"` | ||
} | ||
|
||
type Repo struct { | ||
Name string `yaml:"name"` | ||
Comment string `yaml:"comment"` | ||
URL string `yaml:"url"` | ||
} | ||
|
||
type VulnReport struct { | ||
ReportsAccepted bool `yaml:"reports-accepted"` | ||
BugBountyAvailable bool `yaml:"bug-bounty-available"` | ||
BugBountyProgram string `yaml:"bug-bounty-program"` | ||
Contact Contact `yaml:"contact"` | ||
Comment string `yaml:"comment"` | ||
SecurityPolicy string `yaml:"security-policy"` | ||
PGPKey string `yaml:"pgp-key"` | ||
InScope []string `yaml:"in-scope"` | ||
OutOfScope []string `yaml:"out-of-scope"` | ||
} | ||
|
||
type Docs struct { | ||
DetailedGuide string `yaml:"detailed-guide"` | ||
CodeOfConduct string `yaml:"code-of-conduct"` | ||
QuickstartGuide string `yaml:"quickstart-guide"` | ||
ReleaseProcess string `yaml:"release-process"` | ||
SignatureVerification string `yaml:"signature-verification"` | ||
} | ||
|
||
type Repository struct { | ||
Status string `yaml:"status"` | ||
URL string `yaml:"url"` | ||
AcceptsChangeRequest bool `yaml:"accepts-change-request"` | ||
AcceptsAutomatedChangeRequest bool `yaml:"accepts-automated-change-request"` | ||
BugFixesOnly bool `yaml:"bug-fixes-only"` | ||
NoThirdPartyPackages bool `yaml:"no-third-party-packages"` | ||
CoreTeam []Contact `yaml:"core-team"` | ||
License License `yaml:"license"` | ||
Security SecurityInfo `yaml:"security"` | ||
Documentation Docs `yaml:"documentation"` | ||
Release Release `yaml:"release"` | ||
} | ||
|
||
type SecurityInfo struct { | ||
Assessments Assessments `yaml:"assessments"` | ||
Champions []Contact `yaml:"champions"` | ||
Tools []Tool `yaml:"tools"` | ||
} | ||
|
||
type Assessments struct { | ||
Self Assessment `yaml:"self"` | ||
ThirdParty []Assessment `yaml:"third-party"` | ||
} | ||
|
||
type Tool struct { | ||
Name string `yaml:"name"` | ||
Type string `yaml:"type"` | ||
Version string `yaml:"version"` | ||
Comment string `yaml:"comment"` | ||
Rulesets []string `yaml:"rulesets"` | ||
Integration Integration `yaml:"integration"` | ||
Results Results `yaml:"results"` | ||
} | ||
|
||
type Integration struct { | ||
Adhoc bool `yaml:"adhoc"` | ||
CI bool `yaml:"ci"` | ||
Release bool `yaml:"release"` | ||
} | ||
|
||
type Results struct { | ||
Adhoc Attestation `yaml:"adhoc"` | ||
CI Attestation `yaml:"ci"` | ||
Release Attestation `yaml:"release"` | ||
} | ||
|
||
type Release struct { | ||
AutomatedPipeline bool `yaml:"automated-pipeline"` | ||
DistributionPoints []Link `yaml:"distribution-points"` | ||
Changelog string `yaml:"changelog"` | ||
License License `yaml:"license"` | ||
Attestations []Attestation `yaml:"attestations"` | ||
} | ||
|
||
type SIHeader struct { | ||
SchemaVersion string `yaml:"schema-version"` | ||
ChangeLogURL string `yaml:"changelog"` | ||
LicenseURL string `yaml:"license"` | ||
} |