Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New licences, optional header info, relative path to licence #5

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions assets/rules.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
{
"whitelist": [
"Apache-2.0",
"BSD",
"BSD-2-Clause",
"BSD-2-Clause-FreeBSD",
"BSD-3-Clause",
"Elastic",
"ISC",
"MIT",
"MPL-2.0",
"Public Domain"
],
"yellowlist": [
"EPL-1.0",
"GPL-3.0"
]
}
2 changes: 1 addition & 1 deletion dependency/dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type List struct {
type Info struct {
Name string `json:"name"`
Dir string `json:"-"`
LicenceFile string `json:"-"`
LicenceFile string `json:"licenceFile"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this require providing the full path to the licence file in the module cache directory? The reason for disallowing it was for two reasons:

  • Portability: to prevent OS-specific or user-specific paths from breaking the override rules
  • Security: to prevent someone from accidentally (or intentionally) outputting contents of sensitive files

The workaround for the problem is to define the licenceTextOverrideFile which is handled more securely by chrooting to the project directory (example: https://github.com/elastic/cloud-on-k8s/blob/master/hack/licence-detector/overrides/overrides.json). Will that not work for your use case too?

Copy link
Contributor Author

@kvch kvch Jun 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not have to provide a full path, just a relative one to the root of the directory of the dependency. I am fine with complying with the security requirements you have. However, I would rather not store the licences of our dependencies in the beats repository. I know in general those files are rarely changed, but still. We should not maintain those files. How do you keep the licence files in your repository up to date?

As a middle ground, what do you think about adding an extra check to the path in licenceFile to make sure it is located in the folder of the module? This way we can make sure no sensitive files are published.

I am not sure I understand your concerns about portability. How would this break the override rules?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I didn't realise that the relative path would work because my memory was that it required the full path. That takes away my main concern about portability (although it might still break on Windows but nobody develops on Windows right? 😄 )

+1 on using the same securepath methods on the licence file path to ensure that the file is only within the go module cache.

LicenceType string `json:"licenceType"`
URL string `json:"url"`
Version string `json:"version"`
Expand Down
18 changes: 13 additions & 5 deletions detector/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ const embeddedRulesFile = "go.elastic.co/go-licence-detector:/assets/rules.json"

// rulesFile represents the structure of the rules file.
type rulesFile struct {
Whitelist []string `json:"whitelist"`
Whitelist []string `json:"whitelist"`
Yellowlist []string `json:"yellowlist"`
}

// Rules holds rules for the detector.
type Rules struct {
WhiteList map[string]struct{}
WhiteList map[string]struct{}
YellowList map[string]struct{}
}

// LoadRules loads rules from the given path. Embedded rules file is loaded if the path is empty.
Expand Down Expand Up @@ -66,18 +68,24 @@ func LoadRules(path string) (*Rules, error) {
}

rules := &Rules{
WhiteList: make(map[string]struct{}, len(rf.Whitelist)),
WhiteList: make(map[string]struct{}, len(rf.Whitelist)),
YellowList: make(map[string]struct{}, len(rf.Yellowlist)),
}

for _, w := range rf.Whitelist {
rules.WhiteList[w] = struct{}{}
}

for _, y := range rf.Yellowlist {
rules.YellowList[y] = struct{}{}
}

return rules, nil
}

// IsAllowed returns true if the given licence is allowed by the rules.
func (r *Rules) IsAllowed(licenceID string) bool {
_, ok := r.WhiteList[licenceID]
return ok
_, isWhiteListed := r.WhiteList[licenceID]
_, isYellowListed := r.YellowList[licenceID]
return isWhiteListed || isYellowListed
}
24 changes: 24 additions & 0 deletions render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@ import (
"go.elastic.co/go-licence-detector/dependency"
)

type extraLicenceTextFunc func(dependency.Info) string

var extraTextByLicence = map[string]extraLicenceTextFunc{
"EPL-1.0": func(depInfo dependency.Info) string {
headerStr := `Pursuant to Section 7.1 of EPL v1.0, this library is being distributed under EPL v2.0,
which is available at https://www.eclipse.org/legal/epl-2.0/.
The source code is available at %s with link to the repo for the source code.

`
return fmt.Sprintf(headerStr, depInfo.URL)
},
}

var goModCache = filepath.Join(build.Default.GOPATH, "pkg", "mod")

func Template(dependencies *dependency.List, templatePath, outputPath string) error {
Expand Down Expand Up @@ -84,6 +97,8 @@ func LicenceText(depInfo dependency.Info) string {
}

var buf bytes.Buffer
additonalLicenceText(&buf, depInfo)

if depInfo.LicenceTextOverrideFile != "" {
buf.WriteString("Contents of provided licence file")
} else {
Expand All @@ -105,3 +120,12 @@ func LicenceText(depInfo dependency.Info) string {

return buf.String()
}

func additonalLicenceText(buf *bytes.Buffer, depInfo dependency.Info) {
txtFunc, ok := extraTextByLicence[depInfo.LicenceType]
if !ok {
return
}
txt := txtFunc(depInfo)
buf.WriteString(txt)
}