From 445e6f921e16227e17845543e781b0310676c208 Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 9 Jan 2025 21:23:32 -0800 Subject: [PATCH 1/3] Add Library Registry access control system Background ---------- The Arduino Library Registry repository receives thousands of pull requests from a large number of community contributors. The great majority of these contributors behave in a responsible manner. Unfortunately this repository is regularly the subject of irresponsible behavior. The small number of people who behave irresponsibly consume a significant amount of the finite maintenance resources available for maintenance of Arduino's repositories. Communication is always the first measure taken in these cases. This is done automatically by the bot, and then by the registry maintainer when it becomes clear that the user has disregarded the comments from the bot. Unfortunately it is regularly the case that the user simply disregards all communication and continues their pattern of irresponsible behavior unchecked. Alternatives ------------ GitHub provides tools for dealing with harmful behavior: - Report user - Block user Reporting a user is the appropriate measure in cases of malicious behavior, and the account is usually banned from the site relatively quickly after a legitimate report is made. However, the irresponsible behavior in the registry repository is not overtly malicious and so reporting the user in these cases would not be appropriate or effective. At first glance, the block feature seems ideal. However, it can only be done at an organization-wide level, and by an organization administrator. The repository maintainer is not an organization administrator, so this makes the feature inconvenient to use. There is no sign of these users interacting with other repositories in the `arduino` organization, and so there is no benefit to blocking them at organization scope. In addition, in order to make it more difficult to circumvent the access restriction, we need the ability to block requests for libraries owned by an entity who has established a pattern of irresponsible behavior, regardless of which user submits the request. So the tools provided by GitHub are not suitable and a bespoke system must be implemented. Access Levels ------------- Allow: the user may submit requests for any library, even if registry privileges have been revoked for the owner of the library's repository. This access level will only be granted to registry maintainers, in order to allow them to make exceptions for specific libraries owned by an entity whose privileges have been revoked. Default: the user may submit requests for any library, unless registry privileges have been revoked for the owner of the library's repository. Deny: the user may not submit requests. Requests from users with "default" access level for any library repository owned by the entity (user or organization) are denied. --- go.mod | 2 +- main.go | 124 +++++++++++++++--- tests/test_all.py | 123 ++++++++++++++++- .../.github/workflows/assets/accesslist.yml | 4 + tests/testdata/all-owner-access-deny/diff.txt | 8 ++ .../all-owner-access-deny/repositories.txt | 2 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 4 + .../testdata/some-owner-access-deny/diff.txt | 9 ++ .../some-owner-access-deny/repositories.txt | 2 + .../.github/workflows/assets/accesslist.yml | 8 ++ .../testdata/submitter-access-allow/diff.txt | 8 ++ .../submitter-access-allow/repositories.txt | 2 + .../.github/workflows/assets/accesslist.yml | 4 + tests/testdata/submitter-access-deny/diff.txt | 8 ++ .../submitter-access-deny/repositories.txt | 2 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + .../.github/workflows/assets/accesslist.yml | 1 + 34 files changed, 305 insertions(+), 24 deletions(-) create mode 100644 tests/testdata/all-owner-access-deny/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/all-owner-access-deny/diff.txt create mode 100644 tests/testdata/all-owner-access-deny/repositories.txt create mode 100644 tests/testdata/already-in-library-manager/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/duplicates-in-submission/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/list-deleted-diff/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/list-rename-diff/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/modification/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/multi-file-diff/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/no-final-newline-diff/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/no-library-properties/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/no-tags/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/non-list-diff/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/not-git-clone-url/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/not-supported-git-host/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/removal/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/some-owner-access-deny/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/some-owner-access-deny/diff.txt create mode 100644 tests/testdata/some-owner-access-deny/repositories.txt create mode 100644 tests/testdata/submitter-access-allow/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/submitter-access-allow/diff.txt create mode 100644 tests/testdata/submitter-access-allow/repositories.txt create mode 100644 tests/testdata/submitter-access-deny/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/submitter-access-deny/diff.txt create mode 100644 tests/testdata/submitter-access-deny/repositories.txt create mode 100644 tests/testdata/type-arduino/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/type-contributed/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/type-partner/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/type-recommended/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/url-404/.github/workflows/assets/accesslist.yml create mode 100644 tests/testdata/url-error/.github/workflows/assets/accesslist.yml diff --git a/go.mod b/go.mod index 9aa595d..bcf77bd 100644 --- a/go.mod +++ b/go.mod @@ -7,10 +7,10 @@ require ( github.com/arduino/go-properties-orderedmap v1.8.1 github.com/sourcegraph/go-diff v0.7.0 github.com/stretchr/testify v1.10.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/main.go b/main.go index db99b43..2ebb289 100644 --- a/main.go +++ b/main.go @@ -34,6 +34,7 @@ import ( "strings" "github.com/sourcegraph/go-diff/diff" + "gopkg.in/yaml.v3" "github.com/arduino/go-paths-helper" properties "github.com/arduino/go-properties-orderedmap" @@ -67,6 +68,29 @@ var recommendedOrganizations []string = []string{ "github.com/adafruit", } +// accessType is the type of the access control level. +type accessType string + +const ( + // Allow allows unrestricted access. The entity can make requests even for library repositories whose owner is denied + // access. + Allow accessType = "allow" + // Default gives default access. The entity can make requests as long as the owner of the library's repository is not + // denied access. + Default = "default" + // Deny denies all access. The entity is not permitted to make requests, and registration of libraries from + // repositories they own is not permitted. + Deny = "deny" +) + +// accessDataType is the type of the access control data. +type accessDataType struct { + Access accessType `yaml:"access"` // Access level. + Host string `yaml:"host"` // Account host (e.g., `github.com`). + Name string `yaml:"name"` // User or organization account name. + Reference string `yaml:"reference"` // URL that provides additional information about the access control entry. +} + // request is the type of the request data. type request struct { Type string `json:"type"` // Request type. @@ -89,14 +113,23 @@ type submissionType struct { } // Command line flags. +// Path of the access control file, relative to repopath. +var accesslistArgument = flag.String("accesslist", "", "") var diffPathArgument = flag.String("diffpath", "", "") var repoPathArgument = flag.String("repopath", "", "") var listNameArgument = flag.String("listname", "", "") +// GitHub username of the user making the submission. +var submitterArgument = flag.String("submitter", "", "") + func main() { // Validate flag input. flag.Parse() + if *accesslistArgument == "" { + errorExit("--accesslist flag is required") + } + if *diffPathArgument == "" { errorExit("--diffpath flag is required") } @@ -109,8 +142,18 @@ func main() { errorExit("--listname flag is required") } + if *submitterArgument == "" { + errorExit("--submitter flag is required") + } + + accesslistPath := paths.New(*repoPathArgument, *accesslistArgument) + exist, err := accesslistPath.ExistCheck() + if !exist { + errorExit("Access control file not found") + } + diffPath := paths.New(*diffPathArgument) - exist, err := diffPath.ExistCheck() + exist, err = diffPath.ExistCheck() if !exist { errorExit("diff file not found") } @@ -121,23 +164,59 @@ func main() { errorExit(fmt.Sprintf("list file %s not found", listPath)) } - // Parse the PR diff. - rawDiff, err := diffPath.ReadFile() + rawAccessList, err := accesslistPath.ReadFile() if err != nil { panic(err) } + + // Unmarshal access control file. + var accessList []accessDataType + err = yaml.Unmarshal(rawAccessList, &accessList) + if err != nil { + errorExit(fmt.Sprintf("Access control file has invalid format:\n\n%s", err)) + } + var req request var submissionURLs []string - req.Type, req.Error, req.ArduinoLintLibraryManagerSetting, submissionURLs = parseDiff(rawDiff, *listNameArgument) + + // Determine access level of submitter. + var submitterAccess accessType = Default + for _, accessData := range accessList { + if accessData.Host == "github.com" && *submitterArgument == accessData.Name { + submitterAccess = accessData.Access + if submitterAccess == Deny { + req.Type = "declined" + req.Error = fmt.Sprintf("Library registry privileges for @%s have been revoked.%%0ASee: %s", *submitterArgument, accessData.Reference) + } + break + } + } + + if req.Error == "" { + // Parse the PR diff. + rawDiff, err := diffPath.ReadFile() + if err != nil { + panic(err) + } + req.Type, req.Error, req.ArduinoLintLibraryManagerSetting, submissionURLs = parseDiff(rawDiff, *listNameArgument) + } // Process the submissions. var indexEntries []string var indexerLogsURLs []string + allowedSubmissions := false for _, submissionURL := range submissionURLs { - submission, indexEntry := populateSubmission(submissionURL, listPath) + submission, indexEntry, allowed := populateSubmission(submissionURL, listPath, accessList, submitterAccess) req.Submissions = append(req.Submissions, submission) indexEntries = append(indexEntries, indexEntry) indexerLogsURLs = append(indexerLogsURLs, indexerLogsURL(submission.NormalizedURL)) + if allowed { + allowedSubmissions = true + } + } + if len(submissionURLs) > 0 && !allowedSubmissions { + // If none of the submissions are allowed, decline the request. + req.Type = "declined" } // Check for duplicates within the submission itself. @@ -240,7 +319,7 @@ func parseDiff(rawDiff []byte, listName string) (string, string, string, []strin } // populateSubmission does the checks on the submission that aren't provided by Arduino Lint and gathers the necessary data on it. -func populateSubmission(submissionURL string, listPath *paths.Path) (submissionType, string) { +func populateSubmission(submissionURL string, listPath *paths.Path, accessList []accessDataType, submitterAccess accessType) (submissionType, string, bool) { indexSourceSeparator := "|" var submission submissionType @@ -250,18 +329,18 @@ func populateSubmission(submissionURL string, listPath *paths.Path) (submissionT submissionURLObject, err := url.Parse(submission.SubmissionURL) if err != nil { submission.Error = fmt.Sprintf("Invalid submission URL (%s)", err) - return submission, "" + return submission, "", true } // Check if URL is accessible. httpResponse, err := http.Get(submissionURLObject.String()) if err != nil { submission.Error = fmt.Sprintf("Unable to load submission URL: %s", err) - return submission, "" + return submission, "", true } if httpResponse.StatusCode != http.StatusOK { submission.Error = "Unable to load submission URL. Is the repository public?" - return submission, "" + return submission, "", true } // Resolve redirects and normalize. @@ -269,10 +348,21 @@ func populateSubmission(submissionURL string, listPath *paths.Path) (submissionT submission.NormalizedURL = normalizedURLObject.String() + if submitterAccess != Allow { + // Check library repository owner access. + for _, accessData := range accessList { + ownerSlug := fmt.Sprintf("%s/%s", accessData.Host, accessData.Name) + if accessData.Access == Deny && uRLIsUnder(normalizedURLObject, []string{ownerSlug}) { + submission.Error = fmt.Sprintf("Library registry privileges for library repository owner `%s` have been revoked.%%0ASee: %s", ownerSlug, accessData.Reference) + return submission, "", false + } + } + } + // Check if URL is from a supported Git host. if !uRLIsUnder(normalizedURLObject, supportedHosts) { submission.Error = fmt.Sprintf("`%s` is not currently supported as a Git hosting website for Library Manager.%%0A%%0ASee: https://github.com/arduino/library-registry/blob/main/FAQ.md#what-are-the-requirements-for-a-library-to-be-added-to-library-manager", normalizedURLObject.Host) - return submission, "" + return submission, "", true } // Check if URL is a Git repository @@ -280,7 +370,7 @@ func populateSubmission(submissionURL string, listPath *paths.Path) (submissionT if err != nil { if _, ok := err.(*exec.ExitError); ok { submission.Error = "Submission URL is not a Git clone URL (e.g., `https://github.com/arduino-libraries/Servo`)." - return submission, "" + return submission, "", true } panic(err) @@ -299,7 +389,7 @@ func populateSubmission(submissionURL string, listPath *paths.Path) (submissionT normalizedListURLObject := normalizeURL(listURLObject) if normalizedListURLObject.String() == normalizedURLObject.String() { submission.Error = "Submission URL is already in the Library Manager index." - return submission, "" + return submission, "", true } } @@ -344,7 +434,7 @@ func populateSubmission(submissionURL string, listPath *paths.Path) (submissionT } if string(tagList) == "" { submission.Error = "The repository has no tags. You need to create a [release](https://docs.github.com/en/github/administering-a-repository/managing-releases-in-a-repository) or [tag](https://git-scm.com/docs/git-tag) that matches the `version` value in the library's library.properties file." - return submission, "" + return submission, "", true } latestTag, err := exec.Command("git", "describe", "--tags", strings.TrimSpace(string(tagList))).Output() if err != nil { @@ -362,18 +452,18 @@ func populateSubmission(submissionURL string, listPath *paths.Path) (submissionT libraryPropertiesPath := submissionClonePath.Join("library.properties") if !libraryPropertiesPath.Exist() { submission.Error = "Library is missing a library.properties metadata file.%0A%0ASee: https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata" - return submission, "" + return submission, "", true } libraryProperties, err := properties.LoadFromPath(libraryPropertiesPath) if err != nil { submission.Error = fmt.Sprintf("Invalid library.properties file: %s%%0A%%0ASee: https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata", err) - return submission, "" + return submission, "", true } var ok bool submission.Name, ok = libraryProperties.GetOk("name") if !ok { submission.Error = "library.properties is missing a name field.%0A%0ASee: https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata" - return submission, "" + return submission, "", true } // Assemble Library Manager index source entry string @@ -386,7 +476,7 @@ func populateSubmission(submissionURL string, listPath *paths.Path) (submissionT indexSourceSeparator, ) - return submission, indexEntry + return submission, indexEntry, true } // normalizeURL converts the URL into the standardized format used in the index. diff --git a/tests/test_all.py b/tests/test_all.py index 449c3e8..3bb45f2 100644 --- a/tests/test_all.py +++ b/tests/test_all.py @@ -22,27 +22,61 @@ @pytest.mark.parametrize( "repopath_folder_name," + "submitter," "expected_type," "expected_error," "expected_submissions," "expected_indexentry," "expected_indexerlogsurls", [ - ("list-deleted-diff", "other", "", None, "", ""), - ("multi-file-diff", "other", "", None, "", ""), - ("non-list-diff", "other", "", None, "", ""), - ("list-rename-diff", "other", "", None, "", ""), + ( + "submitter-access-allow", + "AllowUser", + "submission", + "", + [ + { + "submissionURL": "https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library", + "normalizedURL": "https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library.git", + "repositoryName": "SparkFun_Ublox_Arduino_Library", + "name": "SparkFun u-blox Arduino Library", + "official": False, + "tag": "v1.8.11", + "error": "", + } + ], + "https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library.git|Contributed|SparkFun u-blox Arduino Library" + "", + "http://downloads.arduino.cc/libraries/logs/github.com/sparkfun/SparkFun_Ublox_Arduino_Library/", + ), + ( + "submitter-access-deny", + "DenyUser", + "declined", + "Library registry privileges for @DenyUser have been revoked.%0ASee: https://example.com", + None, + "", + "", + ), + ("list-deleted-diff", "FooUser", "other", "", None, "", ""), + ("list-deleted-diff", "FooUser", "other", "", None, "", ""), + ("list-deleted-diff", "FooUser", "other", "", None, "", ""), + ("multi-file-diff", "FooUser", "other", "", None, "", ""), + ("non-list-diff", "FooUser", "other", "", None, "", ""), + ("list-rename-diff", "FooUser", "other", "", None, "", ""), ( "no-final-newline-diff", + "FooUser", "invalid", "Pull request removes newline from the end of a file.%0APlease add a blank line to the end of the file.", None, "", "", ), - ("removal", "removal", "", None, "", ""), + ("removal", "FooUser", "removal", "", None, "", ""), ( "modification", + "FooUser", "modification", "", [ @@ -61,6 +95,7 @@ ), ( "url-error", + "FooUser", "submission", "", [ @@ -79,6 +114,7 @@ ), ( "url-404", + "FooUser", "submission", "", [ @@ -95,8 +131,59 @@ "", "http://downloads.arduino.cc/libraries/logs//", ), + ( + "all-owner-access-deny", + "FooUser", + "declined", + "", + [ + { + "submissionURL": "https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library", + "normalizedURL": "https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library.git", + "repositoryName": "", + "name": "", + "official": False, + "tag": "", + "error": "Library registry privileges for library repository owner `github.com/sparkfun` have been" + " revoked.%0ASee: https://example.com", + }, + ], + "", + "http://downloads.arduino.cc/libraries/logs/github.com/sparkfun/SparkFun_Ublox_Arduino_Library/", + ), + ( + "some-owner-access-deny", + "FooUser", + "submission", + "", + [ + { + "submissionURL": "https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library", + "normalizedURL": "https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library.git", + "repositoryName": "", + "name": "", + "official": False, + "tag": "", + "error": "Library registry privileges for library repository owner `github.com/sparkfun` have been" + " revoked.%0ASee: https://example.com", + }, + { + "submissionURL": "https://github.com/adafruit/Adafruit_TinyFlash", + "normalizedURL": "https://github.com/adafruit/Adafruit_TinyFlash.git", + "repositoryName": "Adafruit_TinyFlash", + "name": "Adafruit TinyFlash", + "official": False, + "tag": "1.0.4", + "error": "", + }, + ], + "%0Ahttps://github.com/adafruit/Adafruit_TinyFlash.git|Recommended|Adafruit TinyFlash", + "http://downloads.arduino.cc/libraries/logs/github.com/sparkfun/SparkFun_Ublox_Arduino_Library/%0Ahttp://do" + "wnloads.arduino.cc/libraries/logs/github.com/adafruit/Adafruit_TinyFlash/", + ), ( "not-supported-git-host", + "FooUser", "submission", "", [ @@ -117,6 +204,7 @@ ), ( "not-git-clone-url", + "FooUser", "submission", "", [ @@ -136,6 +224,7 @@ ), ( "already-in-library-manager", + "FooUser", "submission", "", [ @@ -154,6 +243,7 @@ ), ( "type-arduino", + "FooUser", "submission", "", [ @@ -172,6 +262,7 @@ ), ( "type-partner", + "FooUser", "submission", "", [ @@ -190,6 +281,7 @@ ), ( "type-recommended", + "FooUser", "submission", "", [ @@ -208,6 +300,7 @@ ), ( "type-contributed", + "FooUser", "submission", "", [ @@ -227,6 +320,7 @@ ), ( "no-tags", + "FooUser", "submission", "", [ @@ -247,6 +341,7 @@ ), ( "no-library-properties", + "FooUser", "submission", "", [ @@ -266,6 +361,7 @@ ), ( "duplicates-in-submission", + "FooUser", "submission", "", [ @@ -298,17 +394,32 @@ def test_request( run_command, repopath_folder_name, + submitter, expected_type, expected_error, expected_submissions, expected_indexentry, expected_indexerlogsurls, ): + accesslist = ".github/workflows/assets/accesslist.yml" diffpath = test_data_path.joinpath(repopath_folder_name, "diff.txt") repopath = test_data_path.joinpath(repopath_folder_name) listname = "repositories.txt" - result = run_command(cmd=["--diffpath", diffpath, "--repopath", repopath, "--listname", listname]) + result = run_command( + cmd=[ + "--accesslist", + accesslist, + "--diffpath", + diffpath, + "--repopath", + repopath, + "--listname", + listname, + "--submitter", + submitter, + ] + ) assert result.ok request = json.loads(result.stdout) diff --git a/tests/testdata/all-owner-access-deny/.github/workflows/assets/accesslist.yml b/tests/testdata/all-owner-access-deny/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..68b906c --- /dev/null +++ b/tests/testdata/all-owner-access-deny/.github/workflows/assets/accesslist.yml @@ -0,0 +1,4 @@ +- host: github.com + name: sparkfun + access: deny + reference: https://example.com diff --git a/tests/testdata/all-owner-access-deny/diff.txt b/tests/testdata/all-owner-access-deny/diff.txt new file mode 100644 index 0000000..fd58d54 --- /dev/null +++ b/tests/testdata/all-owner-access-deny/diff.txt @@ -0,0 +1,8 @@ +diff --git a/repositories.txt b/repositories.txt +index c080a7a..1194257 100644 +--- a/repositories.txt ++++ b/repositories.txt +@@ -1,2 +1,3 @@ ++https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library + https://github.com/arduino-libraries/Servo + https://github.com/arduino-libraries/Stepper diff --git a/tests/testdata/all-owner-access-deny/repositories.txt b/tests/testdata/all-owner-access-deny/repositories.txt new file mode 100644 index 0000000..c080a7a --- /dev/null +++ b/tests/testdata/all-owner-access-deny/repositories.txt @@ -0,0 +1,2 @@ +https://github.com/arduino-libraries/Servo +https://github.com/arduino-libraries/Stepper diff --git a/tests/testdata/already-in-library-manager/.github/workflows/assets/accesslist.yml b/tests/testdata/already-in-library-manager/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/already-in-library-manager/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/duplicates-in-submission/.github/workflows/assets/accesslist.yml b/tests/testdata/duplicates-in-submission/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/duplicates-in-submission/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/list-deleted-diff/.github/workflows/assets/accesslist.yml b/tests/testdata/list-deleted-diff/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/list-deleted-diff/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/list-rename-diff/.github/workflows/assets/accesslist.yml b/tests/testdata/list-rename-diff/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/list-rename-diff/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/modification/.github/workflows/assets/accesslist.yml b/tests/testdata/modification/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/modification/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/multi-file-diff/.github/workflows/assets/accesslist.yml b/tests/testdata/multi-file-diff/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/multi-file-diff/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/no-final-newline-diff/.github/workflows/assets/accesslist.yml b/tests/testdata/no-final-newline-diff/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/no-final-newline-diff/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/no-library-properties/.github/workflows/assets/accesslist.yml b/tests/testdata/no-library-properties/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/no-library-properties/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/no-tags/.github/workflows/assets/accesslist.yml b/tests/testdata/no-tags/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/no-tags/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/non-list-diff/.github/workflows/assets/accesslist.yml b/tests/testdata/non-list-diff/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/non-list-diff/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/not-git-clone-url/.github/workflows/assets/accesslist.yml b/tests/testdata/not-git-clone-url/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/not-git-clone-url/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/not-supported-git-host/.github/workflows/assets/accesslist.yml b/tests/testdata/not-supported-git-host/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/not-supported-git-host/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/removal/.github/workflows/assets/accesslist.yml b/tests/testdata/removal/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/removal/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/some-owner-access-deny/.github/workflows/assets/accesslist.yml b/tests/testdata/some-owner-access-deny/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..68b906c --- /dev/null +++ b/tests/testdata/some-owner-access-deny/.github/workflows/assets/accesslist.yml @@ -0,0 +1,4 @@ +- host: github.com + name: sparkfun + access: deny + reference: https://example.com diff --git a/tests/testdata/some-owner-access-deny/diff.txt b/tests/testdata/some-owner-access-deny/diff.txt new file mode 100644 index 0000000..29df5b1 --- /dev/null +++ b/tests/testdata/some-owner-access-deny/diff.txt @@ -0,0 +1,9 @@ +diff --git a/repositories.txt b/repositories.txt +index c080a7a..1194257 100644 +--- a/repositories.txt ++++ b/repositories.txt +@@ -1,2 +1,3 @@ ++https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library ++https://github.com/adafruit/Adafruit_TinyFlash + https://github.com/arduino-libraries/Servo + https://github.com/arduino-libraries/Stepper diff --git a/tests/testdata/some-owner-access-deny/repositories.txt b/tests/testdata/some-owner-access-deny/repositories.txt new file mode 100644 index 0000000..c080a7a --- /dev/null +++ b/tests/testdata/some-owner-access-deny/repositories.txt @@ -0,0 +1,2 @@ +https://github.com/arduino-libraries/Servo +https://github.com/arduino-libraries/Stepper diff --git a/tests/testdata/submitter-access-allow/.github/workflows/assets/accesslist.yml b/tests/testdata/submitter-access-allow/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..65f9ff0 --- /dev/null +++ b/tests/testdata/submitter-access-allow/.github/workflows/assets/accesslist.yml @@ -0,0 +1,8 @@ +- host: github.com + name: AllowUser + access: allow + reference: https://example.com +- host: github.com + name: sparkfun + access: deny + reference: https://example.com diff --git a/tests/testdata/submitter-access-allow/diff.txt b/tests/testdata/submitter-access-allow/diff.txt new file mode 100644 index 0000000..fd58d54 --- /dev/null +++ b/tests/testdata/submitter-access-allow/diff.txt @@ -0,0 +1,8 @@ +diff --git a/repositories.txt b/repositories.txt +index c080a7a..1194257 100644 +--- a/repositories.txt ++++ b/repositories.txt +@@ -1,2 +1,3 @@ ++https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library + https://github.com/arduino-libraries/Servo + https://github.com/arduino-libraries/Stepper diff --git a/tests/testdata/submitter-access-allow/repositories.txt b/tests/testdata/submitter-access-allow/repositories.txt new file mode 100644 index 0000000..c080a7a --- /dev/null +++ b/tests/testdata/submitter-access-allow/repositories.txt @@ -0,0 +1,2 @@ +https://github.com/arduino-libraries/Servo +https://github.com/arduino-libraries/Stepper diff --git a/tests/testdata/submitter-access-deny/.github/workflows/assets/accesslist.yml b/tests/testdata/submitter-access-deny/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..c853a65 --- /dev/null +++ b/tests/testdata/submitter-access-deny/.github/workflows/assets/accesslist.yml @@ -0,0 +1,4 @@ +- host: github.com + name: DenyUser + access: deny + reference: https://example.com diff --git a/tests/testdata/submitter-access-deny/diff.txt b/tests/testdata/submitter-access-deny/diff.txt new file mode 100644 index 0000000..fd58d54 --- /dev/null +++ b/tests/testdata/submitter-access-deny/diff.txt @@ -0,0 +1,8 @@ +diff --git a/repositories.txt b/repositories.txt +index c080a7a..1194257 100644 +--- a/repositories.txt ++++ b/repositories.txt +@@ -1,2 +1,3 @@ ++https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library + https://github.com/arduino-libraries/Servo + https://github.com/arduino-libraries/Stepper diff --git a/tests/testdata/submitter-access-deny/repositories.txt b/tests/testdata/submitter-access-deny/repositories.txt new file mode 100644 index 0000000..c080a7a --- /dev/null +++ b/tests/testdata/submitter-access-deny/repositories.txt @@ -0,0 +1,2 @@ +https://github.com/arduino-libraries/Servo +https://github.com/arduino-libraries/Stepper diff --git a/tests/testdata/type-arduino/.github/workflows/assets/accesslist.yml b/tests/testdata/type-arduino/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/type-arduino/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/type-contributed/.github/workflows/assets/accesslist.yml b/tests/testdata/type-contributed/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/type-contributed/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/type-partner/.github/workflows/assets/accesslist.yml b/tests/testdata/type-partner/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/type-partner/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/type-recommended/.github/workflows/assets/accesslist.yml b/tests/testdata/type-recommended/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/type-recommended/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/url-404/.github/workflows/assets/accesslist.yml b/tests/testdata/url-404/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/url-404/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] diff --git a/tests/testdata/url-error/.github/workflows/assets/accesslist.yml b/tests/testdata/url-error/.github/workflows/assets/accesslist.yml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/tests/testdata/url-error/.github/workflows/assets/accesslist.yml @@ -0,0 +1 @@ +[] From 746755e5e4ecff729660e206dbf806d09d194013 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 10 Jan 2025 04:55:37 -0800 Subject: [PATCH 2/3] Add dependency license metadata cache for `gopkg.in/yaml.v3` The `gopkg.in/yaml.v3` package has been added as a project dependency, so information about its license must be added to the license metadata cache. --- .../go/gopkg.in/yaml.v3.dep.yml | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 .licenses/library-registry-submission-parser/go/gopkg.in/yaml.v3.dep.yml diff --git a/.licenses/library-registry-submission-parser/go/gopkg.in/yaml.v3.dep.yml b/.licenses/library-registry-submission-parser/go/gopkg.in/yaml.v3.dep.yml new file mode 100644 index 0000000..e77248e --- /dev/null +++ b/.licenses/library-registry-submission-parser/go/gopkg.in/yaml.v3.dep.yml @@ -0,0 +1,80 @@ +--- +name: gopkg.in/yaml.v3 +version: v3.0.1 +type: go +summary: Package yaml implements YAML support for the Go language. +homepage: https://pkg.go.dev/gopkg.in/yaml.v3 +license: other +licenses: +- sources: LICENSE + text: |2 + + This project is covered by two different licenses: MIT and Apache. + + #### MIT License #### + + The following files were ported to Go from C files of libyaml, and thus + are still covered by their original MIT license, with the additional + copyright staring in 2011 when the project was ported over: + + apic.go emitterc.go parserc.go readerc.go scannerc.go + writerc.go yamlh.go yamlprivateh.go + + Copyright (c) 2006-2010 Kirill Simonov + Copyright (c) 2006-2011 Kirill Simonov + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + ### Apache License ### + + All the remaining project files are covered by the Apache license: + + Copyright (c) 2011-2019 Canonical Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +- sources: README.md + text: |- + The yaml package is licensed under the MIT and Apache License 2.0 licenses. + Please see the LICENSE file for details. +notices: +- sources: NOTICE + text: |- + Copyright 2011-2016 Canonical Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 16c5fb4413e47229a04226c4192a2b3de3ae8f0f Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 10 Jan 2025 04:58:20 -0800 Subject: [PATCH 3/3] Manually define dependency license metadata that was not detected The "Licensed" dependency license checker tool uses the licensee tool to automatically determine the license type based on metadata provided by the dependency author. This must be in a standardized format without any modifications. In cases where that wasn't done, it is necessary to determine the license type and update the dependency license metadata cache in the `.licenses` folder manually. The Licensed tool will check this data whenever the dependency version is updated to make sure the license hasn't changed. --- .../go/gopkg.in/yaml.v3.dep.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.licenses/library-registry-submission-parser/go/gopkg.in/yaml.v3.dep.yml b/.licenses/library-registry-submission-parser/go/gopkg.in/yaml.v3.dep.yml index e77248e..09288ff 100644 --- a/.licenses/library-registry-submission-parser/go/gopkg.in/yaml.v3.dep.yml +++ b/.licenses/library-registry-submission-parser/go/gopkg.in/yaml.v3.dep.yml @@ -4,7 +4,9 @@ version: v3.0.1 type: go summary: Package yaml implements YAML support for the Go language. homepage: https://pkg.go.dev/gopkg.in/yaml.v3 -license: other +# Apache-2.0 subsumes MIT +# https://www.gnu.org/licenses/license-compatibility.html#combining +license: apache-2.0 licenses: - sources: LICENSE text: |2