Skip to content

Commit a22d36d

Browse files
Merge pull request #4937 from linuxfoundation/unicron-add-remove-co-authored-by-option-prod
Update comment message, add test case, fix vulnerablities
2 parents 4e5da38 + aeaa56d commit a22d36d

28 files changed

Lines changed: 4106 additions & 837 deletions

.gitignore

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
*.pem
44
.mypy_cache
55

6+
# Go binaries
7+
cla-backend-legacy/bin/
8+
cla-backend-legacy/legacy-api
9+
cla-backend-legacy/legacy-api-local
10+
cla-backend-legacy/bin/legacy-api-lambda
11+
612
# Logs
713
logs
814
*.log
@@ -234,6 +240,7 @@ Desktop.ini
234240

235241
# Build files
236242
dist/*
243+
bin/*
237244

238245
# Playground tmp files
239246
.playground
@@ -269,4 +276,12 @@ cla-backend-go/golang-api.log
269276
utils/otel_dd_go/otel_dd
270277
audit.json
271278
spans*.json
272-
api_usage.csv
279+
*api_usage.csv
280+
281+
*.exe
282+
*.exe~
283+
*.dll
284+
*.so
285+
*.dylib
286+
*.test
287+
*.out

cla-backend-go/github/github_repository.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ Supported |Co-authored-by:| formats include:
5353
4) |Anything <other-email>| - it will locate your GitHub user by |other-email| part but only if that email was used before for any other CLA as a main commit author.
5454
5) |login <any-valid-email>| - it will locate your GitHub user by |login| part, note that |login| part must be at least 3 characters long.
5555
56+
Alternatively, if the co-author should not be included, remove the |Co-authored-by:| line from the commit message.
57+
5658
Please update your commit message(s) by doing |git commit --amend| and then |git push [--force]| and then request re-running CLA check via commenting on this pull request:
5759
5860
|||
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright The Linux Foundation and each contributor to CommunityBridge.
2+
// SPDX-License-Identifier: MIT
3+
4+
package github
5+
6+
import (
7+
"testing"
8+
9+
gh "github.com/google/go-github/v37/github"
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
func TestGetCommentBodyIncludesCoAuthorRemovalGuidance(t *testing.T) {
14+
signed := []*UserCommitSummary{{
15+
SHA: "abc1234xyz-123",
16+
CommitAuthor: &gh.User{
17+
ID: gh.Int64(1234),
18+
Login: gh.String("login_value"),
19+
Name: gh.String("author name"),
20+
Email: gh.String("foo@bar.com"),
21+
},
22+
Affiliated: true,
23+
Authorized: true,
24+
}}
25+
26+
missing := []*UserCommitSummary{{
27+
SHA: "some_other_sha",
28+
CommitAuthor: &gh.User{
29+
ID: gh.Int64(123456),
30+
Login: gh.String("login_value2"),
31+
Name: gh.String("author name2"),
32+
Email: gh.String("foo2@bar.com"),
33+
},
34+
Affiliated: false,
35+
Authorized: false,
36+
}}
37+
38+
body := getCommentBody("github", "https://foo.com", signed, missing, true)
39+
40+
assert.Contains(t, body, "One or more co-authors of this pull request were not found")
41+
assert.Contains(t, body, "Alternatively, if the co-author should not be included, remove the `Co-authored-by:` line from the commit message.")
42+
assert.NotContains(t, body, "|Co-authored-by:|")
43+
}
44+
45+
func TestGetCommentBodyOmitsCoAuthorRemovalGuidanceWhenNoCoAuthorIsMissing(t *testing.T) {
46+
missing := []*UserCommitSummary{{
47+
SHA: "some_other_sha",
48+
CommitAuthor: &gh.User{
49+
ID: gh.Int64(123456),
50+
Login: gh.String("login_value2"),
51+
Name: gh.String("author name2"),
52+
Email: gh.String("foo2@bar.com"),
53+
},
54+
Affiliated: false,
55+
Authorized: false,
56+
}}
57+
58+
body := getCommentBody("github", "https://foo.com", nil, missing, false)
59+
60+
assert.NotContains(t, body, "One or more co-authors of this pull request were not found")
61+
assert.NotContains(t, body, "Alternatively, if the co-author should not be included, remove the `Co-authored-by:` line from the commit message.")
62+
}

cla-backend-go/go.mod

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// SPDX-License-Identifier: MIT
33
module github.com/linuxfoundation/easycla/cla-backend-go
44

5-
go 1.24
5+
go 1.24.0
6+
7+
toolchain go1.24.4
68

79
replace github.com/awslabs/aws-lambda-go-api-proxy => github.com/LF-Engineering/aws-lambda-go-api-proxy v0.3.2
810

@@ -68,12 +70,12 @@ require (
6870
require (
6971
github.com/aws/aws-sdk-go-v2/service/s3 v1.53.1
7072
github.com/bradleyfalzon/ghinstallation/v2 v2.2.0
71-
github.com/golang-jwt/jwt v3.2.2+incompatible
72-
github.com/golang-jwt/jwt/v4 v4.5.0
73+
github.com/golang-jwt/jwt/v4 v4.5.2
7374
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0
7475
go.opentelemetry.io/otel v1.40.0
7576
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0
7677
go.opentelemetry.io/otel/sdk v1.40.0
78+
go.opentelemetry.io/otel/trace v1.40.0
7779
)
7880

7981
require (
@@ -131,7 +133,6 @@ require (
131133
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
132134
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect
133135
go.opentelemetry.io/otel/metric v1.40.0 // indirect
134-
go.opentelemetry.io/otel/trace v1.40.0 // indirect
135136
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
136137
golang.org/x/text v0.33.0 // indirect
137138
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect

cla-backend-go/go.sum

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,9 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V
285285
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
286286
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
287287
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
288-
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
289-
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
290-
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
291288
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
289+
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
290+
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
292291
github.com/golang/dep v0.5.4/go.mod h1:6RZ2Wai7dSWk7qL55sDYk+8UPFqcW7all2KDBraPPFA=
293292
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
294293
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=

cla-backend-go/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@
2626
"serverless-layers": "^2.6.1",
2727
"serverless-plugin-tracing": "^2.0.0",
2828
"serverless-prune-plugin": "^2.0.2",
29+
"simple-git": "^3.33.0",
2930
"xml2js": "^0.6.0",
3031
"yarn-audit-fix": "^9.3.10"
3132
},
3233
"resolutions": {
3334
"axios": "^0.30.3",
35+
"tar": "^7.5.10",
3436
"ansi-regex": "^5.0.1",
3537
"aws-sdk": "^2.1329.0",
3638
"cookiejar": "^2.1.4",
@@ -44,11 +46,10 @@
4446
"normalize-url": "^4.5.1",
4547
"qs": "^6.14.2",
4648
"set-value": "^4.0.1",
47-
"simple-git": "^3.16.0",
49+
"simple-git": "^3.33.0",
4850
"ws": ">=7.5.10",
4951
"xmlhttprequest-ssl": "^1.6.2",
5052
"form-data": "^4.0.4",
51-
"tar": "^7.5.8",
5253
"minimatch": "^10.2.1",
5354
"fast-xml-parser": "^5.3.6"
5455
}

cla-backend-go/telemetry/datadog_otlp.go

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,11 @@ func InitDatadogOTel(cfg DatadogOTelConfig) error {
132132

133133
// WrapHTTPHandler instruments inbound HTTP requests using otelhttp and produces spans.
134134
func WrapHTTPHandler(next http.Handler) http.Handler {
135-
// Regexes mirror ./utils/count_apis.sh so OTel span names group the same way as the offline API log rollups:
136-
// - collapse multiple slashes
137-
// - trim trailing slash
138-
// - mask common asset extensions -> ".{asset}"
139-
// - normalize Swagger assets "/vN/swagger.{asset}" -> "/vN/swagger" (keep version; do NOT map to /v*)
140-
// - mask UUIDs, numeric IDs, Salesforce IDs, LFX IDs, and literal "null" segments
141135
reMultiSlash := regexp.MustCompile(`/{2,}`)
142136
reAssetExt := regexp.MustCompile(`\.(png|svg|css|js|json|xml|htm|html)$`)
143137
reSwaggerAsset := regexp.MustCompile(`^(/v[0-9]+)/swagger\.\{asset\}$`)
144-
// UUIDs: classify valid vs invalid (E2E often probes invalid IDs)
138+
reSwaggerJSONResource := regexp.MustCompile(`^(/v[0-9]+/swagger\.json)/.+$`)
139+
reSwaggerTemplatedResource := regexp.MustCompile(`^(/v[0-9]+/swagger\.\{asset\})/.+$`)
145140
reUUIDValid := regexp.MustCompile(`[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}`)
146141
reUUIDLike := regexp.MustCompile(`/[0-9A-Za-z]{8}-[0-9A-Za-z]{4}-[0-9A-Za-z]{4}-[0-9A-Za-z]{4}-[0-9A-Za-z]{12}(/|$)`)
147142
reUUIDHexDash36 := regexp.MustCompile(`/[0-9a-fA-F-]{36}(/|$)`)
@@ -151,8 +146,15 @@ func WrapHTTPHandler(next http.Handler) http.Handler {
151146
reLFXIDValid := regexp.MustCompile(`/lf[A-Za-z0-9]{16,22}(/|$)`)
152147
reLFXIDLike := regexp.MustCompile(`/lf[^/]{1,32}(/|$)`)
153148
reNull := regexp.MustCompile(`/null(/|$)`)
149+
reUndefined := regexp.MustCompile(`/undefined(/|$)`)
154150
reInvalidUUIDSeg := regexp.MustCompile(`/(?:invalid-uuid(?:-format)?|not-a-uuid)(/|$)`)
155151
reInvalidSFIDSeg := regexp.MustCompile(`/invalid-sfid(?:-format)?(/|$)`)
152+
reUsersUsername := regexp.MustCompile(`^(/v[0-9]+/users/username)/[^/]+$`)
153+
reCompanyName := regexp.MustCompile(`^(/v[0-9]+/company/name)/[^/]+$`)
154+
reCompanyUserCLAManagerDesignee := regexp.MustCompile(`^(/v[0-9]+/company/[^/]+/user)/[^/]+(/claGroupID/[^/]+/is-cla-manager-designee)$`)
155+
reProjectCLAManagerUser := regexp.MustCompile(`^(/v[0-9]+/company/[^/]+/project/[^/]+/cla-manager)/[^/]+$`)
156+
reRepositoryProviderGithubSignNumeric := regexp.MustCompile(`^(/v[0-9]+/repository-provider/github/sign/[^/]+)/[0-9]+(/[^/]+)$`)
157+
reSignedIndividualGithubNumeric := regexp.MustCompile(`^(/v[0-9]+/signed/individual/[^/]+)/[0-9]+(/[^/]+)$`)
156158

157159
boolishTrue := func(v string) bool {
158160
switch strings.ToLower(strings.TrimSpace(v)) {
@@ -177,29 +179,32 @@ func WrapHTTPHandler(next http.Handler) http.Handler {
177179
p = strings.TrimSuffix(p, "/")
178180
}
179181

180-
// Asset extensions (including swagger.json/xml/html) -> ".{asset}"
182+
p = reSwaggerJSONResource.ReplaceAllString(p, "$1/{resource}")
183+
p = reSwaggerTemplatedResource.ReplaceAllString(p, "$1/{resource}")
184+
p = reUsersUsername.ReplaceAllString(p, "$1/{name}")
185+
p = reCompanyName.ReplaceAllString(p, "$1/{name}")
186+
p = reCompanyUserCLAManagerDesignee.ReplaceAllString(p, "$1/{name}$2")
187+
p = reProjectCLAManagerUser.ReplaceAllString(p, "$1/{name}")
188+
p = reRepositoryProviderGithubSignNumeric.ReplaceAllString(p, "$1/{n}$2")
189+
p = reSignedIndividualGithubNumeric.ReplaceAllString(p, "$1/{n}$2")
181190
p = reAssetExt.ReplaceAllString(p, ".{asset}")
182-
183-
// Keep the version (/v1, /v2, ...) but normalize swagger asset paths.
184191
if m := reSwaggerAsset.FindStringSubmatch(p); m != nil {
185192
p = m[1] + "/swagger"
186193
}
187194

188-
// Dynamic segment masking (use template placeholders, not "*")
189-
// UUIDs: valid vs invalid
190195
p = reUUIDValid.ReplaceAllString(p, "{uuid}")
191196
p = reUUIDLike.ReplaceAllString(p, "/{invalid-uuid}$1")
192197
p = reUUIDHexDash36.ReplaceAllString(p, "/{invalid-uuid}$1")
193-
p = reNumericID.ReplaceAllString(p, "/{id}$1")
194-
p = reNumericID.ReplaceAllString(p, "/{id}$1")
195-
// Salesforce IDs: valid vs invalid
198+
for prev := ""; p != prev; {
199+
prev = p
200+
p = reNumericID.ReplaceAllString(p, "/{id}$1")
201+
}
196202
p = reSFIDValid.ReplaceAllString(p, "/{sfid}$1")
197203
p = reSFIDLike.ReplaceAllString(p, "/{invalid-sfid}$1")
198-
// LFX IDs: valid vs invalid
199204
p = reLFXIDValid.ReplaceAllString(p, "/{lfxid}$1")
200205
p = reLFXIDLike.ReplaceAllString(p, "/{invalid-lfxid}$1")
201206
p = reNull.ReplaceAllString(p, "/{null}$1")
202-
// Known "invalid" test tokens (Cypress) -> placeholders
207+
p = reUndefined.ReplaceAllString(p, "/{undefined}$1")
203208
p = reInvalidUUIDSeg.ReplaceAllString(p, "/{invalid-uuid}$1")
204209
p = reInvalidSFIDSeg.ReplaceAllString(p, "/{invalid-sfid}$1")
205210

cla-backend-go/v2/sign/jwt.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package sign
66
import (
77
"time"
88

9-
"github.com/golang-jwt/jwt"
9+
"github.com/golang-jwt/jwt/v4"
1010
log "github.com/linuxfoundation/easycla/cla-backend-go/logging"
1111
"github.com/linuxfoundation/easycla/cla-backend-go/utils"
1212
"github.com/sirupsen/logrus"

cla-backend-go/yarn.lock

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2385,13 +2385,20 @@ dayjs@^1.11.8:
23852385
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
23862386
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
23872387

2388-
debug@4, debug@^4.1.1, debug@^4.3.4, debug@^4.3.5:
2388+
debug@4, debug@^4.1.1, debug@^4.3.4:
23892389
version "4.4.0"
23902390
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
23912391
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
23922392
dependencies:
23932393
ms "^2.1.3"
23942394

2395+
debug@^4.4.0:
2396+
version "4.4.3"
2397+
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
2398+
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
2399+
dependencies:
2400+
ms "^2.1.3"
2401+
23952402
decompress-response@^6.0.0:
23962403
version "6.0.0"
23972404
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
@@ -4783,14 +4790,14 @@ signal-exit@^3.0.2, signal-exit@^3.0.7:
47834790
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
47844791
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
47854792

4786-
simple-git@^3.16.0:
4787-
version "3.27.0"
4788-
resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-3.27.0.tgz#f4b09e807bda56a4a3968f635c0e4888d3decbd5"
4789-
integrity sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==
4793+
simple-git@^3.16.0, simple-git@^3.33.0:
4794+
version "3.33.0"
4795+
resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-3.33.0.tgz#b903dc70f5b93535a4f64ff39172da43058cfb88"
4796+
integrity sha512-D4V/tGC2sjsoNhoMybKyGoE+v8A60hRawKQ1iFRA1zwuDgGZCBJ4ByOzZ5J8joBbi4Oam0qiPH+GhzmSBwbJng==
47904797
dependencies:
47914798
"@kwsites/file-exists" "^1.1.1"
47924799
"@kwsites/promise-deferred" "^1.1.1"
4793-
debug "^4.3.5"
4800+
debug "^4.4.0"
47944801

47954802
slash@^3.0.0:
47964803
version "3.0.0"
@@ -5032,10 +5039,10 @@ tar-stream@^2.1.0, tar-stream@^2.2.0:
50325039
inherits "^2.0.3"
50335040
readable-stream "^3.1.1"
50345041

5035-
tar@^6.1.15, tar@^7.5.8:
5036-
version "7.5.9"
5037-
resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.9.tgz#817ac12a54bc4362c51340875b8985d7dc9724b8"
5038-
integrity sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==
5042+
tar@^6.1.15, tar@^7.5.10:
5043+
version "7.5.11"
5044+
resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.11.tgz#1250fae45d98806b36d703b30973fa8e0a6d8868"
5045+
integrity sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==
50395046
dependencies:
50405047
"@isaacs/fs-minipass" "^4.0.0"
50415048
chownr "^3.0.0"

0 commit comments

Comments
 (0)