Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d78333e1b5 | |||
| af77a4aad0 | |||
| 21258f4160 | |||
| 65305ed9f6 | |||
| 156aaac745 | |||
| 531d17bd3a | |||
| c13c56283d | |||
| 56cd1df414 | |||
| 67972683ea | |||
| a2266b4e28 | |||
| b1675194ca | |||
| 4086895249 | |||
| 10902f802a | |||
| 2a3f8942ee | |||
| d1cbc54fc6 | |||
| 5a86c18302 | |||
| 622700b6ec | |||
| 15ed428e28 | |||
| 6f801f64c7 | |||
| 3485a6dab1 | |||
| 34f5db64ae | |||
| 91bd843ba7 | |||
| 584ab043a2 | |||
| 7578a3a56e | |||
| 800ac30ea0 | |||
| abdff53d5d | |||
| a002ba9a75 | |||
| cec1543894 | |||
| e217e2fbfd | |||
| 4116a24b1c | |||
| a6902ae9cb | |||
| 6dd24d17d4 | |||
| 5b2b434a8a | |||
| 1c1f034468 | |||
| 661e62f006 | |||
| 92244019a9 | |||
| dfc5a9f5db | |||
| f5ecbc857b | |||
| 42975c6d1e | |||
| 0507f0eb87 | |||
| 531e3ef6c3 | |||
| 97ce27153a | |||
| 1c89e79c2d | |||
| 461f1a631e | |||
| 2fbf86a6ab | |||
| 458c79165a | |||
| 1db22599af | |||
| 562f3aaa2a | |||
| 2c1d8fbba4 | |||
| f1cb933a5a | |||
| 256ae20079 | |||
| 5fce8f9f18 | |||
| 304abb9ca9 | |||
| a8c27b9510 | |||
| c451f9daf8 |
@@ -0,0 +1,88 @@
|
||||
name: Performance Test
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
speed:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.18'
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.head_ref }}
|
||||
|
||||
- name: Run Head
|
||||
run: |
|
||||
go build -o current .
|
||||
repo_tmp=$(mktemp -d)
|
||||
git clone https://github.com/trufflesecurity/trufflehog.git $repo_tmp
|
||||
|
||||
user_time_sum=0
|
||||
|
||||
for i in {1..5}
|
||||
do
|
||||
tmpfile=$(mktemp)
|
||||
/usr/bin/time -o $tmpfile $GITHUB_WORKSPACE/current git "file://$repo_tmp" --no-verification --no-update > out.txt
|
||||
cat $tmpfile
|
||||
time_output=$(cat $tmpfile)
|
||||
rm $tmpfile
|
||||
user_time=$(echo $time_output | awk '{print $1}' | sed 's/user//')
|
||||
|
||||
# Add the user time to the sum
|
||||
user_time_sum=$(echo "$user_time_sum + $user_time" | bc)
|
||||
done
|
||||
|
||||
average_user_time=$(echo "scale=3; $user_time_sum / 5" | bc)
|
||||
echo HEAD_TIME=$average_user_time >> $GITHUB_ENV
|
||||
|
||||
- name: Figure out previous tag
|
||||
run: |
|
||||
git fetch --tags
|
||||
git tag -l --sort=-v:refname | head -n 1 > previous_tag.txt
|
||||
echo PREVIOUS_TAG=$(cat previous_tag.txt) >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ env.PREVIOUS_TAG }}
|
||||
|
||||
- name: Run Previous
|
||||
run: |
|
||||
go build -o previous .
|
||||
repo_tmp=$(mktemp -d)
|
||||
git clone https://github.com/trufflesecurity/trufflehog.git $repo_tmp
|
||||
|
||||
user_time_sum=0
|
||||
|
||||
for i in {1..5}
|
||||
do
|
||||
tmpfile=$(mktemp)
|
||||
/usr/bin/time -o $tmpfile $GITHUB_WORKSPACE/previous git "file://$repo_tmp" --no-verification --no-update > out.txt
|
||||
cat $tmpfile
|
||||
time_output=$(cat $tmpfile)
|
||||
rm $tmpfile
|
||||
user_time=$(echo $time_output | awk '{print $1}' | sed 's/user//')
|
||||
|
||||
# Add the user time to the sum
|
||||
user_time_sum=$(echo "$user_time_sum + $user_time" | bc)
|
||||
done
|
||||
|
||||
average_user_time=$(echo "scale=3; $user_time_sum / 5" | bc)
|
||||
echo PREVIOUS_TIME=$average_user_time >> $GITHUB_ENV
|
||||
|
||||
- name: Compare Results
|
||||
run: |
|
||||
echo "head ($GITHUB_SHA) avg time (n=5): $HEAD_TIME"
|
||||
echo "$PREVIOUS_TAG avg time (n=5): $PREVIOUS_TIME"
|
||||
if [ $(echo "$HEAD_TIME > $PREVIOUS_TIME * 1.1" | bc) -eq 1 ]
|
||||
then
|
||||
echo "HEAD run time is at least 10% slower than PREVIOUS run time"
|
||||
exit 1
|
||||
fi
|
||||
@@ -29,3 +29,4 @@ jobs:
|
||||
path: ./
|
||||
base: ${{ github.event.repository.default_branch }}
|
||||
head: HEAD
|
||||
extra_args: --only-verified
|
||||
|
||||
@@ -17,10 +17,10 @@ require (
|
||||
github.com/bill-rich/disk-buffer-reader v0.1.7
|
||||
github.com/bill-rich/go-syslog v0.0.0-20220413021637-49edb52a574c
|
||||
github.com/bitfinexcom/bitfinex-api-go v0.0.0-20210608095005-9e0b26f200fb
|
||||
github.com/bradleyfalzon/ghinstallation/v2 v2.2.0
|
||||
github.com/bradleyfalzon/ghinstallation/v2 v2.4.0
|
||||
github.com/crewjam/rfc5424 v0.1.0
|
||||
github.com/denisenkom/go-mssqldb v0.12.3
|
||||
github.com/envoyproxy/protoc-gen-validate v0.10.1
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.0
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/felixge/fgprof v0.9.3
|
||||
github.com/getsentry/sentry-go v0.20.0
|
||||
@@ -35,16 +35,16 @@ require (
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/google/go-github/v42 v42.0.0
|
||||
github.com/googleapis/gax-go/v2 v2.8.0
|
||||
github.com/googleapis/gax-go/v2 v2.7.1
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2
|
||||
github.com/jlaffaye/ftp v0.1.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/jpillora/overseer v1.1.6
|
||||
github.com/kylelemons/godebug v1.1.0
|
||||
github.com/lib/pq v1.10.7
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.7
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.8
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/paulbellamy/ratecounter v0.2.0
|
||||
github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9
|
||||
@@ -53,14 +53,14 @@ require (
|
||||
github.com/sergi/go-diff v1.3.1
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502
|
||||
github.com/xanzy/go-gitlab v0.81.0
|
||||
go.mongodb.org/mongo-driver v1.11.3
|
||||
github.com/xanzy/go-gitlab v0.83.0
|
||||
go.mongodb.org/mongo-driver v1.11.4
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/crypto v0.7.0
|
||||
golang.org/x/crypto v0.8.0
|
||||
golang.org/x/exp v0.0.0-20221018205818-5c77f4b2bbd7
|
||||
golang.org/x/oauth2 v0.6.0
|
||||
golang.org/x/oauth2 v0.7.0
|
||||
golang.org/x/sync v0.1.0
|
||||
golang.org/x/text v0.8.0
|
||||
golang.org/x/text v0.9.0
|
||||
google.golang.org/api v0.114.0
|
||||
google.golang.org/protobuf v1.30.0
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||
@@ -88,7 +88,11 @@ require (
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/benbjohnson/clock v1.1.0 // indirect
|
||||
github.com/bodgit/plumbing v1.2.0 // indirect
|
||||
github.com/bodgit/sevenzip v1.3.0 // indirect
|
||||
github.com/bodgit/windows v1.0.0 // indirect
|
||||
github.com/cloudflare/circl v1.1.0 // indirect
|
||||
github.com/connesc/cipherio v0.2.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||
github.com/dsnet/compress v0.0.1 // indirect
|
||||
@@ -103,7 +107,7 @@ require (
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-github/v50 v50.1.0 // indirect
|
||||
github.com/google/go-github/v52 v52.0.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
@@ -126,7 +130,7 @@ require (
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.2 // indirect
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/onsi/gomega v1.23.0 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.14 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
@@ -142,11 +146,12 @@ require (
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/mod v0.9.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.7.0 // indirect
|
||||
golang.org/x/tools v0.8.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230320184635-7606e756e683 // indirect
|
||||
|
||||
@@ -1,17 +1,34 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
|
||||
cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY=
|
||||
cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
|
||||
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/iam v0.12.0 h1:DRtTY29b75ciH6Ov1PHb4/iat2CLCvrOm40Q0a6DFpE=
|
||||
cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY=
|
||||
cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/secretmanager v1.10.0 h1:pu03bha7ukxF8otyPKTFdDz+rr9sE3YauS5PliDXK60=
|
||||
cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
|
||||
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8=
|
||||
@@ -36,6 +53,7 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e h1:NeAW1fUYUEWhft7pkxDf6WoUvEZJ/uOKsvtpjLnn8MU=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
|
||||
@@ -64,8 +82,14 @@ github.com/bill-rich/go-syslog v0.0.0-20220413021637-49edb52a574c h1:tSME5FDS02q
|
||||
github.com/bill-rich/go-syslog v0.0.0-20220413021637-49edb52a574c/go.mod h1:+sCc6hztur+oZCLOsNk6wCCy+GLrnSNHSRmTnnL+8iQ=
|
||||
github.com/bitfinexcom/bitfinex-api-go v0.0.0-20210608095005-9e0b26f200fb h1:9v7Bzlg+1EBYi2IYcUmOwHReBEfqBbYIj3ZCi9cIe1Q=
|
||||
github.com/bitfinexcom/bitfinex-api-go v0.0.0-20210608095005-9e0b26f200fb/go.mod h1:EkOqCuelvo7DY8vCOoZ09p7pHvAK9B1PHI9GeM4Rdxc=
|
||||
github.com/bradleyfalzon/ghinstallation/v2 v2.2.0 h1:AVvVU33rE8wdTS1aNnenwpigEBA9mvzI5OhjhZfH/LU=
|
||||
github.com/bradleyfalzon/ghinstallation/v2 v2.2.0/go.mod h1:xo3iIfK0lDKECe0s19nbxT0KKvk7LsrGc4NxR5ckKMA=
|
||||
github.com/bodgit/plumbing v1.2.0 h1:gg4haxoKphLjml+tgnecR4yLBV5zo4HAZGCtAh3xCzM=
|
||||
github.com/bodgit/plumbing v1.2.0/go.mod h1:b9TeRi7Hvc6Y05rjm8VML3+47n4XTZPtQ/5ghqic2n8=
|
||||
github.com/bodgit/sevenzip v1.3.0 h1:1ljgELgtHqvgIp8W8kgeEGHIWP4ch3xGI8uOBZgLVKY=
|
||||
github.com/bodgit/sevenzip v1.3.0/go.mod h1:omwNcgZTEooWM8gA/IJ2Nk/+ZQ94+GsytRzOJJ8FBlM=
|
||||
github.com/bodgit/windows v1.0.0 h1:rLQ/XjsleZvx4fR1tB/UxQrK+SJ2OFHzfPjLWWOhDIA=
|
||||
github.com/bodgit/windows v1.0.0/go.mod h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM=
|
||||
github.com/bradleyfalzon/ghinstallation/v2 v2.4.0 h1:zYSzkoIwekCQAr6GT6KxISLt4YRS6kd4/ixfzMN+7yc=
|
||||
github.com/bradleyfalzon/ghinstallation/v2 v2.4.0/go.mod h1:4MwZLSgBJJgg4i3nJwZJ95AMooSqN8fJDmegLVn9Q2U=
|
||||
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
@@ -75,6 +99,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY=
|
||||
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/connesc/cipherio v0.2.1 h1:FGtpTPMbKNNWByNrr9aEBtaJtXjqOzkIXNYJp6OEycw=
|
||||
github.com/connesc/cipherio v0.2.1/go.mod h1:ukY0MWJDFnJEbXMQtOcn2VmTpRfzcTz4OoVrWGGJZcA=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/crewjam/rfc5424 v0.1.0 h1:MSeXJm22oKovLzWj44AHwaItjIMUMugYGkEzfa831H8=
|
||||
github.com/crewjam/rfc5424 v0.1.0/go.mod h1:RCi9M3xHVOeerf6ULZzqv2xOGRO/zYaVUeRyPnBW3gQ=
|
||||
@@ -95,8 +121,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.0 h1:FPFO7LWZ2pfphahSUMX8L5p/6FqSzRYRxq6V74eG8ZI=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.0/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||
@@ -121,6 +147,8 @@ github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlK
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
|
||||
github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk=
|
||||
github.com/go-git/go-git/v5 v5.6.1/go.mod h1:mvyoL6Unz0PiTQrGQfSfiLFhBH1c1e84ylC2MDs4ee8=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-ldap/ldap/v3 v3.4.4 h1:qPjipEpt+qDa6SI/h1fzuGWoRUY+qqQ9sOZq67/PYUs=
|
||||
github.com/go-ldap/ldap/v3 v3.4.4/go.mod h1:fe1MsuN5eJJ1FeLT/LEBVdWfNWKh459R7aXgXtJC+aI=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
@@ -151,12 +179,20 @@ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2V
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
@@ -166,11 +202,14 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
@@ -179,24 +218,33 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github/v42 v42.0.0 h1:YNT0FwjPrEysRkLIiKuEfSvBPCGKphW5aS5PxwaoLec=
|
||||
github.com/google/go-github/v42 v42.0.0/go.mod h1:jgg/jvyI0YlDOM1/ps6XYh04HNQ3vKf0CVko62/EhRg=
|
||||
github.com/google/go-github/v50 v50.1.0 h1:hMUpkZjklC5GJ+c3GquSqOP/T4BNsB7XohaPhtMOzRk=
|
||||
github.com/google/go-github/v50 v50.1.0/go.mod h1:Ev4Tre8QoKiolvbpOSG3FIi4Mlon3S2Nt9W5JYqKiwA=
|
||||
github.com/google/go-github/v52 v52.0.0 h1:uyGWOY+jMQ8GVGSX8dkSwCzlehU3WfdxQ7GweO/JP7M=
|
||||
github.com/google/go-github/v52 v52.0.0/go.mod h1:WJV6VEEUPuMo5pXqqa2ZCZEdbQqua4zAk2MZTIo+m+4=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
|
||||
github.com/googleapis/gax-go/v2 v2.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc=
|
||||
github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A=
|
||||
github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
@@ -212,7 +260,10 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
@@ -229,8 +280,11 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/jpillora/s3 v1.1.4 h1:YCCKDWzb/Ye9EBNd83ATRF/8wPEy0xd43Rezb6u6fzc=
|
||||
github.com/jpillora/s3 v1.1.4/go.mod h1:yedE603V+crlFi1Kl/5vZJaBu9pUzE9wvKegU/lF2zs=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4=
|
||||
@@ -247,8 +301,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
@@ -258,8 +312,8 @@ github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPn
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.7 h1:xzByj8G8tj0Oq7ZYYU4+ixL/CVb5ruWCm0EZQ1PjOkE=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.7/go.mod h1:Fs8qUkO74HHaidabihzYephJH8qmGD/nCP6tE5xC9BM=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.8 h1:tRGQuDVPh66WCOelqe6LIGh0gwmfwxUrSSDunscGsRM=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.8/go.mod h1:5f7FUYGXdJWUjESffJaYR4R60VhnHxb2X3T1teMyv5A=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM=
|
||||
@@ -289,8 +343,8 @@ github.com/paulbellamy/ratecounter v0.2.0 h1:2L/RhJq+HA8gBQImDXtLPrDXK5qAj6ozWVK
|
||||
github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE=
|
||||
github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 h1:lL+y4Xv20pVlCGyLzNHRC0I0rIHhIL1lTvHizoS/dU8=
|
||||
github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9/go.mod h1:EHPiTAKtiFmrMldLUNswFwfZ2eJIYBHktdaUTZxYWRw=
|
||||
github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
|
||||
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||
@@ -305,6 +359,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rabbitmq/amqp091-go v1.8.0 h1:GBFy5PpLQ5jSVVSYv8ecHGqeX7UTLYR4ItQbDCss9MM=
|
||||
github.com/rabbitmq/amqp091-go v1.8.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
@@ -342,8 +398,8 @@ github.com/trufflesecurity/overseer v1.1.7-custom5/go.mod h1:nT9w37AiO1Nop2VhVhN
|
||||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
|
||||
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/xanzy/go-gitlab v0.81.0 h1:ofbhZ5ZY9AjHATWQie4qd2JfncdUmvcSA/zfQB767Dk=
|
||||
github.com/xanzy/go-gitlab v0.81.0/go.mod h1:VMbY3JIWdZ/ckvHbQqkyd3iYk2aViKrNIQ23IbFMQDo=
|
||||
github.com/xanzy/go-gitlab v0.83.0 h1:37p0MpTPNbsTMKX/JnmJtY8Ch1sFiJzVF342+RvZEGw=
|
||||
github.com/xanzy/go-gitlab v0.83.0/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
@@ -358,8 +414,12 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y=
|
||||
go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||
go.mongodb.org/mongo-driver v1.11.4 h1:4ayjakA013OdpGyL2K3ZqylTac/rMjrJOMZ1EHizXas=
|
||||
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
@@ -372,12 +432,15 @@ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9i
|
||||
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU=
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg=
|
||||
golang.org/x/arch v0.1.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
@@ -385,29 +448,58 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20221018205818-5c77f4b2bbd7 h1:lhh9BuEmjIBOdOhMIGSQzdW5LbTtFbUV1k9O/Rlq3SE=
|
||||
golang.org/x/exp v0.0.0-20221018205818-5c77f4b2bbd7/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
@@ -420,14 +512,22 @@ golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfS
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
|
||||
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
|
||||
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -436,12 +536,22 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -463,59 +573,112 @@ golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
|
||||
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE=
|
||||
google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20230320184635-7606e756e683 h1:khxVcsk/FhnzxMKOyD+TDGwjbEOpcPuIpmafPGFmhMA=
|
||||
google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
||||
@@ -530,6 +693,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
@@ -540,6 +704,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
||||
@@ -559,7 +724,13 @@ gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
set terminal png size 800,600
|
||||
set output "hack/bench/versions.png"
|
||||
|
||||
set title "User Time vs. Version"
|
||||
set xlabel "Version"
|
||||
set ylabel "Average User Time (s)"
|
||||
|
||||
set xtics rotate by -45
|
||||
|
||||
plot "hack/bench/plot.txt" using 2:xtic(1) with linespoints linestyle 1 notitle
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage: $0 <repository to clone> <number_of_versions_back_to_test>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the number of versions back to test from command line argument
|
||||
num_versions="$2"
|
||||
|
||||
test_repo="$1"
|
||||
|
||||
bash hack/bench/versions.sh $test_repo $num_versions | tee hack/bench/plot.txt
|
||||
|
||||
gnuplot hack/bench/plot.gp
|
||||
@@ -0,0 +1,24 @@
|
||||
v3.33.0: 1.402
|
||||
v3.32.2: 1.298
|
||||
v3.32.1: 1.332
|
||||
v3.32.0: 1.348
|
||||
v3.31.6: 2.470
|
||||
v3.31.5: 2.462
|
||||
v3.31.4: 2.460
|
||||
v3.31.3: 2.418
|
||||
v3.31.2: 1.384
|
||||
v3.31.1: 1.344
|
||||
v3.31.0: 1.354
|
||||
v3.30.0: 1.392
|
||||
v3.29.1: 1.382
|
||||
v3.29.0: 1.340
|
||||
v3.28.7: 1.380
|
||||
v3.28.6: 1.308
|
||||
v3.28.5: 2.596
|
||||
v3.28.4: 2.554
|
||||
v3.28.3: 2.582
|
||||
v3.28.1: 2.578
|
||||
v3.28.2: 2.566
|
||||
v3.28.0: 2.552
|
||||
v3.27.1: 2.574
|
||||
v3.26.0: 2.538
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
@@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage: $0 <repository to clone> <number_of_versions_back_to_test>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the number of versions back to test from command line argument
|
||||
num_versions="$2"
|
||||
|
||||
test_repo="$1"
|
||||
|
||||
num_iterations=5
|
||||
|
||||
# Create a temporary folder to clone the repository
|
||||
repo_tmp=$(mktemp -d)
|
||||
# Set up a trap to remove the temporary folder on exit or failure
|
||||
trap "rm -rf $repo_tmp" EXIT
|
||||
# Clone the test repository to a temporary folder
|
||||
git clone --quiet "$test_repo" $repo_tmp
|
||||
|
||||
|
||||
# Get list of git tags, sorted from newest to oldest
|
||||
tags=$(git tag --sort=-creatordate)
|
||||
|
||||
# Counter to keep track of number of tags checked out
|
||||
count=0
|
||||
|
||||
|
||||
# Loop over tags and checkout each one in turn, up to the specified number of versions
|
||||
for tag in $tags
|
||||
do
|
||||
if [[ $count -eq $num_versions ]]; then
|
||||
break
|
||||
fi
|
||||
|
||||
# Skip RC tags
|
||||
if [[ $tag == *"rc"* ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Skip alpha tags
|
||||
if [[ $tag == *"alpha"* ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Use git checkout with the quiet flag to suppress output
|
||||
git checkout $tag --quiet
|
||||
|
||||
# Run make install with suppressed output
|
||||
make install > /dev/null
|
||||
|
||||
# Initialize the variable to store the sum of user times
|
||||
user_time_sum=0
|
||||
|
||||
# Run each iteration 5 times and calculate the average user time
|
||||
for i in {1..$num_iterations}
|
||||
do
|
||||
# Run trufflehog with suppressed output and capture user time with /usr/bin/time
|
||||
tmpfile=$(mktemp)
|
||||
/usr/bin/time -o $tmpfile trufflehog git "file://$repo_tmp" --no-verification --no-update >/dev/null 2>&1
|
||||
time_output=$(cat $tmpfile)
|
||||
rm $tmpfile
|
||||
|
||||
# Extract the user time from the output
|
||||
user_time=$(echo $time_output | awk '{print $3}')
|
||||
|
||||
# Add the user time to the sum
|
||||
user_time_sum=$(echo "$user_time_sum + $user_time" | bc)
|
||||
done
|
||||
|
||||
# Calculate the average user time
|
||||
average_user_time=$(echo "scale=3; $user_time_sum / $num_iterations" | bc)
|
||||
|
||||
# Print the average user time output for this iteration in the specified format
|
||||
echo "$tag: $average_user_time"
|
||||
|
||||
# Increment the counter
|
||||
count=$((count+1))
|
||||
done
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/handlers"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/log"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/output"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/sources"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/sources/git"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/updater"
|
||||
@@ -99,12 +98,13 @@ var (
|
||||
filesystemScanIncludePaths = filesystemScan.Flag("include-paths", "Path to file with newline separated regexes for files to include in scan.").Short('i').String()
|
||||
filesystemScanExcludePaths = filesystemScan.Flag("exclude-paths", "Path to file with newline separated regexes for files to exclude in scan.").Short('x').String()
|
||||
|
||||
s3Scan = cli.Command("s3", "Find credentials in S3 buckets.")
|
||||
s3ScanKey = s3Scan.Flag("key", "S3 key used to authenticate. Can be provided with environment variable AWS_ACCESS_KEY_ID.").Envar("AWS_ACCESS_KEY_ID").String()
|
||||
s3ScanSecret = s3Scan.Flag("secret", "S3 secret used to authenticate. Can be provided with environment variable AWS_SECRET_ACCESS_KEY.").Envar("AWS_SECRET_ACCESS_KEY").String()
|
||||
s3ScanSessionToken = s3Scan.Flag("session-token", "S3 session token used to authenticate temporary credentials. Can be provided with environment variable AWS_SESSION_TOKEN.").Envar("AWS_SESSION_TOKEN").String()
|
||||
s3ScanCloudEnv = s3Scan.Flag("cloud-environment", "Use IAM credentials in cloud environment.").Bool()
|
||||
s3ScanBuckets = s3Scan.Flag("bucket", "Name of S3 bucket to scan. You can repeat this flag.").Strings()
|
||||
s3Scan = cli.Command("s3", "Find credentials in S3 buckets.")
|
||||
s3ScanKey = s3Scan.Flag("key", "S3 key used to authenticate. Can be provided with environment variable AWS_ACCESS_KEY_ID.").Envar("AWS_ACCESS_KEY_ID").String()
|
||||
s3ScanSecret = s3Scan.Flag("secret", "S3 secret used to authenticate. Can be provided with environment variable AWS_SECRET_ACCESS_KEY.").Envar("AWS_SECRET_ACCESS_KEY").String()
|
||||
s3ScanSessionToken = s3Scan.Flag("session-token", "S3 session token used to authenticate temporary credentials. Can be provided with environment variable AWS_SESSION_TOKEN.").Envar("AWS_SESSION_TOKEN").String()
|
||||
s3ScanCloudEnv = s3Scan.Flag("cloud-environment", "Use IAM credentials in cloud environment.").Bool()
|
||||
s3ScanBuckets = s3Scan.Flag("bucket", "Name of S3 bucket to scan. You can repeat this flag.").Strings()
|
||||
s3ScanMaxObjectSize = s3Scan.Flag("max-object-size", "Maximum size of objects to scan. Objects larger than this will be skipped. (Byte units eg. 512B, 2KB, 4MB)").Default("250MB").Bytes()
|
||||
|
||||
gcsScan = cli.Command("gcs", "Find credentials in GCS buckets.")
|
||||
gcsProjectID = gcsScan.Flag("project-id", "GCS project ID used to authenticate. Can NOT be used with unauth scan. Can be provided with environment variable GOOGLE_CLOUD_PROJECT.").Envar("GOOGLE_CLOUD_PROJECT").String()
|
||||
@@ -221,8 +221,6 @@ func run(state overseer.State) {
|
||||
}
|
||||
}
|
||||
|
||||
urls := splitVerifierURLs(*verifiers)
|
||||
|
||||
if *archiveMaxSize != 0 {
|
||||
handlers.SetArchiveMaxSize(int(*archiveMaxSize))
|
||||
}
|
||||
@@ -233,63 +231,95 @@ func run(state overseer.State) {
|
||||
handlers.SetArchiveMaxTimeout(*archiveTimeout)
|
||||
}
|
||||
|
||||
// Build include and exclude detector filter sets.
|
||||
var includeDetectorTypes, excludeDetectorTypes map[detectorspb.DetectorType]config.DetectorID
|
||||
// Build include and exclude detector sets for filtering on engine initialization.
|
||||
// Exit if there was an error to inform the user of the misconfiguration.
|
||||
var includeDetectorSet, excludeDetectorSet map[config.DetectorID]struct{}
|
||||
var detectorsWithCustomVerifierEndpoints map[config.DetectorID][]string
|
||||
{
|
||||
includeList, err := config.ParseDetectors(*includeDetectors)
|
||||
if err != nil {
|
||||
// Exit if there was an error to inform the user of the misconfiguration.
|
||||
logFatal(err, "invalid include list detector configuration")
|
||||
}
|
||||
excludeList, err := config.ParseDetectors(*excludeDetectors)
|
||||
if err != nil {
|
||||
// Exit if there was an error to inform the user of the misconfiguration.
|
||||
logFatal(err, "invalid exclude list detector configuration")
|
||||
}
|
||||
includeDetectorTypes = detectorTypeToMap(includeList)
|
||||
excludeDetectorTypes = detectorTypeToMap(excludeList)
|
||||
detectorsWithCustomVerifierEndpoints, err = config.ParseVerifierEndpoints(*verifiers)
|
||||
if err != nil {
|
||||
logFatal(err, "invalid verifier detector configuration")
|
||||
}
|
||||
includeDetectorSet = detectorTypeToSet(includeList)
|
||||
excludeDetectorSet = detectorTypeToSet(excludeList)
|
||||
}
|
||||
|
||||
// Verify that all the user-provided detectors support the optional
|
||||
// detector features.
|
||||
{
|
||||
if err, id := verifyDetectorsAreVersioner(includeDetectorSet); err != nil {
|
||||
logFatal(err, "invalid include list detector configuration", "detector", id)
|
||||
}
|
||||
if err, id := verifyDetectorsAreVersioner(excludeDetectorSet); err != nil {
|
||||
logFatal(err, "invalid exclude list detector configuration", "detector", id)
|
||||
}
|
||||
if err, id := verifyDetectorsAreVersioner(detectorsWithCustomVerifierEndpoints); err != nil {
|
||||
logFatal(err, "invalid verifier detector configuration", "detector", id)
|
||||
}
|
||||
// Extra check for endpoint customization.
|
||||
isEndpointCustomizer := engine.DefaultDetectorTypesImplementing[detectors.EndpointCustomizer]()
|
||||
for id := range detectorsWithCustomVerifierEndpoints {
|
||||
if _, ok := isEndpointCustomizer[id.ID]; !ok {
|
||||
logFatal(
|
||||
fmt.Errorf("endpoint provided but detector does not support endpoint customization"),
|
||||
"invalid custom verifier endpoint detector configuration",
|
||||
"detector", id,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
includeFilter := func(d detectors.Detector) bool {
|
||||
id, ok := includeDetectorTypes[d.Type()]
|
||||
if id.Version == 0 {
|
||||
return ok
|
||||
}
|
||||
versionD, ok := d.(detectors.Versioner)
|
||||
if !ok {
|
||||
// Error: version provided but not a detectors.Versioner
|
||||
logFatal(
|
||||
fmt.Errorf("version provided but detector does not have a version"),
|
||||
"invalid include list detector configuration",
|
||||
"detector", id,
|
||||
)
|
||||
}
|
||||
return versionD.Version() == id.Version
|
||||
_, ok := getWithDetectorID(d, includeDetectorSet)
|
||||
return ok
|
||||
}
|
||||
excludeFilter := func(d detectors.Detector) bool {
|
||||
id, ok := excludeDetectorTypes[d.Type()]
|
||||
if id.Version == 0 {
|
||||
return !ok
|
||||
}
|
||||
versionD, ok := d.(detectors.Versioner)
|
||||
_, ok := getWithDetectorID(d, excludeDetectorSet)
|
||||
return !ok
|
||||
}
|
||||
// Abuse filter to cause a side-effect.
|
||||
endpointCustomizer := func(d detectors.Detector) bool {
|
||||
urls, ok := getWithDetectorID(d, detectorsWithCustomVerifierEndpoints)
|
||||
if !ok {
|
||||
// Error: version provided but not a detectors.Versioner
|
||||
return true
|
||||
}
|
||||
id := config.GetDetectorID(d)
|
||||
customizer, ok := d.(detectors.EndpointCustomizer)
|
||||
if !ok {
|
||||
// NOTE: We should never reach here due to validation above.
|
||||
logFatal(
|
||||
fmt.Errorf("version provided but detector does not have a version"),
|
||||
"invalid exclude list detector configuration",
|
||||
fmt.Errorf("failed to configure a detector endpoint"),
|
||||
"the provided detector does not support endpoint configuration",
|
||||
"detector", id,
|
||||
)
|
||||
}
|
||||
return versionD.Version() != id.Version
|
||||
// TODO: Add flag to ignore the default endpoint.
|
||||
urls = append(urls, customizer.DefaultEndpoint())
|
||||
if err := customizer.SetEndpoints(urls...); err != nil {
|
||||
logFatal(err, "failed configuring custom endpoint for detector", "detector", id)
|
||||
}
|
||||
logger.Info("configured detector with verification urls",
|
||||
"detector", id, "urls", urls,
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
e := engine.Start(ctx,
|
||||
engine.WithConcurrency(*concurrency),
|
||||
engine.WithDecoders(decoders.DefaultDecoders()...),
|
||||
engine.WithDetectors(!*noVerification, engine.DefaultDetectors()...),
|
||||
engine.WithDetectors(!*noVerification, engine.CustomDetectors(ctx, urls)...),
|
||||
engine.WithDetectors(!*noVerification, conf.Detectors...),
|
||||
engine.WithFilterDetectors(includeFilter),
|
||||
engine.WithFilterDetectors(excludeFilter),
|
||||
engine.WithFilterDetectors(endpointCustomizer),
|
||||
engine.WithFilterUnverified(*filterUnverified),
|
||||
)
|
||||
|
||||
@@ -383,11 +413,12 @@ func run(state overseer.State) {
|
||||
}
|
||||
case s3Scan.FullCommand():
|
||||
cfg := sources.S3Config{
|
||||
Key: *s3ScanKey,
|
||||
Secret: *s3ScanSecret,
|
||||
SessionToken: *s3ScanSessionToken,
|
||||
Buckets: *s3ScanBuckets,
|
||||
CloudCred: *s3ScanCloudEnv,
|
||||
Key: *s3ScanKey,
|
||||
Secret: *s3ScanSecret,
|
||||
SessionToken: *s3ScanSessionToken,
|
||||
Buckets: *s3ScanBuckets,
|
||||
CloudCred: *s3ScanCloudEnv,
|
||||
MaxObjectSize: int64(*s3ScanMaxObjectSize),
|
||||
}
|
||||
if err := e.ScanS3(ctx, cfg); err != nil {
|
||||
logFatal(err, "Failed to scan S3.")
|
||||
@@ -498,19 +529,6 @@ func printAverageDetectorTime(e *engine.Engine) {
|
||||
}
|
||||
}
|
||||
|
||||
func splitVerifierURLs(verifierURLs map[string]string) map[string][]string {
|
||||
verifiers := make(map[string][]string, len(verifierURLs))
|
||||
for k, v := range verifierURLs {
|
||||
key := strings.ToLower(k)
|
||||
sliceOfValues := strings.Split(v, ",")
|
||||
for i, s := range sliceOfValues {
|
||||
sliceOfValues[i] = strings.TrimSpace(s)
|
||||
}
|
||||
verifiers[key] = sliceOfValues
|
||||
}
|
||||
return verifiers
|
||||
}
|
||||
|
||||
// logFatalFunc returns a log.Fatal style function. Calling the returned
|
||||
// function will terminate the program without cleanup.
|
||||
func logFatalFunc(logger logr.Logger) func(error, string, ...any) {
|
||||
@@ -524,10 +542,46 @@ func logFatalFunc(logger logr.Logger) func(error, string, ...any) {
|
||||
}
|
||||
}
|
||||
|
||||
func detectorTypeToMap(detectors []config.DetectorID) map[detectorspb.DetectorType]config.DetectorID {
|
||||
output := make(map[detectorspb.DetectorType]config.DetectorID, len(detectors))
|
||||
// detectorTypeToSet is a helper function to convert a slice of detector IDs into a set.
|
||||
func detectorTypeToSet(detectors []config.DetectorID) map[config.DetectorID]struct{} {
|
||||
output := make(map[config.DetectorID]struct{}, len(detectors))
|
||||
for _, d := range detectors {
|
||||
output[d.ID] = d
|
||||
output[d] = struct{}{}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
// getWithDetectorID is a helper function to get a value from a map using a
|
||||
// detector's ID. This function behaves like a normal map lookup, with an extra
|
||||
// step of checking for the non-specific version of a detector.
|
||||
func getWithDetectorID[T any](d detectors.Detector, data map[config.DetectorID]T) (T, bool) {
|
||||
key := config.GetDetectorID(d)
|
||||
// Check if the specific ID is provided.
|
||||
if t, ok := data[key]; ok || key.Version == 0 {
|
||||
return t, ok
|
||||
}
|
||||
// Check if the generic type is provided without a version.
|
||||
// This means "all" versions of a type.
|
||||
key.Version = 0
|
||||
t, ok := data[key]
|
||||
return t, ok
|
||||
}
|
||||
|
||||
// verifyDetectorsAreVersioner checks all keys in a provided map to verify the
|
||||
// provided type is actually a Versioner.
|
||||
func verifyDetectorsAreVersioner[T any](data map[config.DetectorID]T) (error, config.DetectorID) {
|
||||
isVersioner := engine.DefaultDetectorTypesImplementing[detectors.Versioner]()
|
||||
for id := range data {
|
||||
if id.Version == 0 {
|
||||
// Version not provided.
|
||||
continue
|
||||
}
|
||||
if _, ok := isVersioner[id.ID]; ok {
|
||||
// Version provided for a Versioner detector.
|
||||
continue
|
||||
}
|
||||
// Version provided on a non-Versioner detector.
|
||||
return fmt.Errorf("version provided but detector does not have a version"), id
|
||||
}
|
||||
return nil, config.DetectorID{}
|
||||
}
|
||||
|
||||
+50
-2
@@ -2,10 +2,12 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
dpb "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
@@ -31,11 +33,26 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// DetectorID identifies a detector type and version. This struct is used as a
|
||||
// way for users to identify detectors, whether unique or not. A DetectorID
|
||||
// with Version = 0 indicates all possible versions of a detector.
|
||||
type DetectorID struct {
|
||||
ID dpb.DetectorType
|
||||
Version int
|
||||
}
|
||||
|
||||
// GetDetectorID extracts the DetectorID from a Detector.
|
||||
func GetDetectorID(d detectors.Detector) DetectorID {
|
||||
var version int
|
||||
if v, ok := d.(detectors.Versioner); ok {
|
||||
version = v.Version()
|
||||
}
|
||||
return DetectorID{
|
||||
ID: d.Type(),
|
||||
Version: version,
|
||||
}
|
||||
}
|
||||
|
||||
// ParseDetectors parses user supplied string into a list of detectors types.
|
||||
// "all" will return the list of all available detectors. The input is comma
|
||||
// separated and may use the case-insensitive detector name defined in the
|
||||
@@ -68,6 +85,37 @@ func ParseDetectors(input string) ([]DetectorID, error) {
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// ParseDetector parses a user supplied string into a single DetectorID. Input
|
||||
// is case-insensitive and either the detector name or ID may be used.
|
||||
func ParseDetector(input string) (DetectorID, error) {
|
||||
return asDetectorID(strings.TrimSpace(input))
|
||||
}
|
||||
|
||||
// ParseVerifierEndpoints parses a map of user supplied verifier URLs. The
|
||||
// input keys are detector IDs and the values are a comma separated list of
|
||||
// URLs. The URLs are validated as HTTPS endpoints.
|
||||
func ParseVerifierEndpoints(verifierURLs map[string]string) (map[DetectorID][]string, error) {
|
||||
verifiers := make(map[DetectorID][]string, len(verifierURLs))
|
||||
for detectorID, urls := range verifierURLs {
|
||||
key, err := ParseDetector(detectorID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid detector ID for verifier: %w", err)
|
||||
}
|
||||
verifierURLs := strings.Split(urls, ",")
|
||||
for i, rawEndpoint := range verifierURLs {
|
||||
rawEndpoint := strings.TrimSpace(rawEndpoint)
|
||||
verifierURLs[i] = rawEndpoint
|
||||
if endpoint, err := url.Parse(rawEndpoint); err != nil {
|
||||
return nil, fmt.Errorf("invalid verifier url %q: %w", rawEndpoint, err)
|
||||
} else if endpoint.Scheme != "https" {
|
||||
return nil, fmt.Errorf("verifier url must be https: %q", rawEndpoint)
|
||||
}
|
||||
}
|
||||
verifiers[key] = append(verifiers[key], verifierURLs...)
|
||||
}
|
||||
return verifiers, nil
|
||||
}
|
||||
|
||||
func (id DetectorID) String() string {
|
||||
name := dpb.DetectorType_name[int32(id.ID)]
|
||||
if name == "" {
|
||||
@@ -139,8 +187,8 @@ func asRange(input string) ([]DetectorID, error) {
|
||||
return append(output, dtEnd), nil
|
||||
}
|
||||
|
||||
// asDetectorID converts the case-insensitive input into a DetectorID.
|
||||
// Name or ID may be used.
|
||||
// asDetectorID converts the case-insensitive input into a DetectorID. Name or
|
||||
// ID may be used. Input is expected to be already trimmed of whitespace.
|
||||
func asDetectorID(input string) (DetectorID, error) {
|
||||
if input == "" {
|
||||
return DetectorID{}, fmt.Errorf("empty detector")
|
||||
|
||||
+82
-43
@@ -3,7 +3,6 @@ package decoders
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"strings"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/sources"
|
||||
)
|
||||
@@ -13,52 +12,20 @@ type Base64 struct{}
|
||||
var (
|
||||
b64Charset = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=")
|
||||
b64EndChars = "+/="
|
||||
// Given characters are mostly ASCII, we can use a simple array to map.
|
||||
b64CharsetMapping [128]bool
|
||||
)
|
||||
|
||||
func getSubstringsOfCharacterSet(data []byte, charset []byte, threshold int) []string {
|
||||
count := 0
|
||||
substrings := []string{}
|
||||
letters := strings.Builder{}
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
func init() {
|
||||
// Build an array of all the characters in the base64 charset.
|
||||
for _, char := range b64Charset {
|
||||
b64CharsetMapping[char] = true
|
||||
}
|
||||
for _, char := range string(data) {
|
||||
if bytes.ContainsRune(charset, char) {
|
||||
letters.WriteRune(char)
|
||||
count++
|
||||
} else {
|
||||
if count > threshold {
|
||||
substrings = appendB64Substring(letters, substrings)
|
||||
}
|
||||
letters.Reset()
|
||||
count = 0
|
||||
}
|
||||
}
|
||||
|
||||
if count > threshold && len(letters.String()) > 0 {
|
||||
substrings = appendB64Substring(letters, substrings)
|
||||
}
|
||||
|
||||
return substrings
|
||||
}
|
||||
|
||||
func appendB64Substring(letters strings.Builder, substrings []string) []string {
|
||||
|
||||
substring := strings.TrimLeft(letters.String(), b64EndChars)
|
||||
// handle key=value
|
||||
if strings.Contains(strings.TrimRight(substring, b64EndChars), "=") {
|
||||
split := strings.SplitN(substring, "=", 2)
|
||||
substrings = append(substrings, split[len(split)-1])
|
||||
} else {
|
||||
substrings = append(substrings, substring)
|
||||
}
|
||||
return substrings
|
||||
}
|
||||
|
||||
func (d *Base64) FromChunk(chunk *sources.Chunk) *sources.Chunk {
|
||||
|
||||
encodedSubstrings := getSubstringsOfCharacterSet(chunk.Data, b64Charset, 20)
|
||||
decodedSubstrings := map[string][]byte{}
|
||||
encodedSubstrings := getSubstringsOfCharacterSet(chunk.Data, 20)
|
||||
decodedSubstrings := make(map[string][]byte)
|
||||
|
||||
for _, str := range encodedSubstrings {
|
||||
dec, err := base64.StdEncoding.DecodeString(str)
|
||||
@@ -68,11 +35,83 @@ func (d *Base64) FromChunk(chunk *sources.Chunk) *sources.Chunk {
|
||||
}
|
||||
|
||||
if len(decodedSubstrings) > 0 {
|
||||
for substring, dec := range decodedSubstrings {
|
||||
chunk.Data = bytes.Replace(chunk.Data, []byte(substring), dec, 1)
|
||||
var result bytes.Buffer
|
||||
result.Grow(len(chunk.Data))
|
||||
|
||||
start := 0
|
||||
for _, encoded := range encodedSubstrings {
|
||||
if decoded, ok := decodedSubstrings[encoded]; ok {
|
||||
end := bytes.Index(chunk.Data[start:], []byte(encoded))
|
||||
if end != -1 {
|
||||
result.Write(chunk.Data[start : start+end])
|
||||
result.Write(decoded)
|
||||
start += end + len(encoded)
|
||||
}
|
||||
}
|
||||
}
|
||||
result.Write(chunk.Data[start:])
|
||||
chunk.Data = result.Bytes()
|
||||
return chunk
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getSubstringsOfCharacterSet(data []byte, threshold int) []string {
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
count := 0
|
||||
substringsCount := 0
|
||||
|
||||
// Determine the number of substrings that will be returned.
|
||||
// Pre-allocate the slice to avoid reallocations.
|
||||
for _, char := range data {
|
||||
if char < 128 && b64CharsetMapping[char] {
|
||||
count++
|
||||
} else {
|
||||
if count > threshold {
|
||||
substringsCount++
|
||||
}
|
||||
count = 0
|
||||
}
|
||||
}
|
||||
if count > threshold {
|
||||
substringsCount++
|
||||
}
|
||||
|
||||
count = 0
|
||||
start := 0
|
||||
substrings := make([]string, 0, substringsCount)
|
||||
|
||||
for i, char := range data {
|
||||
if char < 128 && b64CharsetMapping[char] {
|
||||
if count == 0 {
|
||||
start = i
|
||||
}
|
||||
count++
|
||||
} else {
|
||||
if count > threshold {
|
||||
substrings = appendB64Substring(data, start, count, substrings)
|
||||
}
|
||||
count = 0
|
||||
}
|
||||
}
|
||||
|
||||
if count > threshold {
|
||||
substrings = appendB64Substring(data, start, count, substrings)
|
||||
}
|
||||
|
||||
return substrings
|
||||
}
|
||||
|
||||
func appendB64Substring(data []byte, start, count int, substrings []string) []string {
|
||||
substring := bytes.TrimLeft(data[start:start+count], b64EndChars)
|
||||
if idx := bytes.IndexByte(bytes.TrimRight(substring, b64EndChars), '='); idx != -1 {
|
||||
substrings = append(substrings, string(substring[idx+1:]))
|
||||
} else {
|
||||
substrings = append(substrings, string(substring))
|
||||
}
|
||||
return substrings
|
||||
}
|
||||
|
||||
@@ -90,13 +90,29 @@ func TestBase64_FromChunk(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFromChunk(benchmark *testing.B) {
|
||||
func BenchmarkFromChunkSmall(b *testing.B) {
|
||||
d := Base64{}
|
||||
for name, data := range detectors.MustGetBenchmarkData() {
|
||||
benchmark.Run(name, func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
d.FromChunk(&sources.Chunk{Data: data})
|
||||
}
|
||||
})
|
||||
data := detectors.MustGetBenchmarkData()["small"]
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
d.FromChunk(&sources.Chunk{Data: data})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFromChunkMedium(b *testing.B) {
|
||||
d := Base64{}
|
||||
data := detectors.MustGetBenchmarkData()["medium"]
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
d.FromChunk(&sources.Chunk{Data: data})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFromChunkLarge(b *testing.B) {
|
||||
d := Base64{}
|
||||
data := detectors.MustGetBenchmarkData()["big"]
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
d.FromChunk(&sources.Chunk{Data: data})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ func DefaultDecoders() []Decoder {
|
||||
return []Decoder{
|
||||
&UTF8{},
|
||||
&Base64{},
|
||||
&UTF16{},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package decoders
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/sources"
|
||||
)
|
||||
|
||||
type UTF16 struct{}
|
||||
|
||||
func (d *UTF16) FromChunk(chunk *sources.Chunk) *sources.Chunk {
|
||||
if chunk == nil || len(chunk.Data) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if utf16Data, err := utf16ToUTF8(chunk.Data); err == nil {
|
||||
chunk.Data = utf16Data
|
||||
return chunk
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// utf16ToUTF8 converts a byte slice containing UTF-16 encoded data to a UTF-8 encoded byte slice.
|
||||
func utf16ToUTF8(b []byte) ([]byte, error) {
|
||||
endianness, err := guessUTF16Endianness(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
for i := 0; i < len(b); i += 2 {
|
||||
r := rune(endianness.Uint16(b[i:]))
|
||||
if utf8.ValidRune(r) {
|
||||
buf.WriteRune(r)
|
||||
}
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func guessUTF16Endianness(b []byte) (binary.ByteOrder, error) {
|
||||
if len(b) < 2 || len(b)%2 != 0 {
|
||||
return nil, fmt.Errorf("input length must be even and at least 2 bytes long")
|
||||
}
|
||||
|
||||
var evenNullBytes, oddNullBytes int
|
||||
|
||||
for i := 0; i < len(b); i += 2 {
|
||||
if b[i] == 0 {
|
||||
oddNullBytes++
|
||||
}
|
||||
if b[i+1] == 0 {
|
||||
evenNullBytes++
|
||||
}
|
||||
}
|
||||
|
||||
if evenNullBytes > oddNullBytes {
|
||||
return binary.LittleEndian, nil
|
||||
}
|
||||
if oddNullBytes > evenNullBytes {
|
||||
return binary.BigEndian, nil
|
||||
}
|
||||
return nil, fmt.Errorf("could not determine endianness")
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package decoders
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/sources"
|
||||
)
|
||||
|
||||
func TestUTF16Decoder(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input []byte
|
||||
expected []byte
|
||||
expectNil bool
|
||||
}{
|
||||
{
|
||||
name: "Valid UTF-16LE input",
|
||||
input: []byte{72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 100, 0},
|
||||
expected: []byte("Hello World"),
|
||||
expectNil: false,
|
||||
},
|
||||
{
|
||||
name: "Valid UTF-16BE input",
|
||||
input: []byte{0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 100},
|
||||
expected: []byte("Hello World"),
|
||||
expectNil: false,
|
||||
},
|
||||
{
|
||||
name: "Invalid UTF-16 input (it's UTF-8)",
|
||||
input: []byte("Hello World!"),
|
||||
expected: nil,
|
||||
expectNil: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid UTF-16 input (odd length)",
|
||||
input: []byte{72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 0},
|
||||
expected: nil,
|
||||
expectNil: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
chunk := &sources.Chunk{Data: tc.input}
|
||||
decoder := &UTF16{}
|
||||
decodedChunk := decoder.FromChunk(chunk)
|
||||
|
||||
if tc.expectNil {
|
||||
if decodedChunk != nil {
|
||||
t.Errorf("Expected nil, got chunk with data: %v", decodedChunk.Data)
|
||||
}
|
||||
return
|
||||
}
|
||||
if decodedChunk == nil {
|
||||
t.Errorf("Expected chunk with data, got nil")
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(decodedChunk.Data, tc.expected) {
|
||||
t.Errorf("Expected decoded data: %v, got: %v", tc.expected, decodedChunk.Data)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUtf16ToUtf8(b *testing.B) {
|
||||
// Example UTF-16LE encoded data
|
||||
data := []byte{72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 100, 0}
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
_, _ = utf16ToUTF8(data)
|
||||
}
|
||||
}
|
||||
+20
-9
@@ -26,19 +26,30 @@ func (d *UTF8) FromChunk(chunk *sources.Chunk) *sources.Chunk {
|
||||
// extacting contigous portions of printable characters that we care
|
||||
// about from some bytes
|
||||
func extractSubstrings(b []byte) []byte {
|
||||
fields := bytes.FieldsFunc(b, func(r rune) bool {
|
||||
isValidByte := func(c byte) bool {
|
||||
// https://www.rapidtables.com/code/text/ascii-table.html
|
||||
// split on anything that is not ascii space through tilde
|
||||
return !(r > 31 && r < 127)
|
||||
})
|
||||
return c > 31 && c < 127
|
||||
}
|
||||
|
||||
keep := [][]byte{}
|
||||
for _, field := range fields {
|
||||
// Remove fields shorter than 6 characters.
|
||||
if bts := bytes.TrimSpace(field); len(bts) > 5 {
|
||||
keep = append(keep, bts)
|
||||
field := make([]byte, len(b))
|
||||
fieldLen := 0
|
||||
buf := &bytes.Buffer{}
|
||||
for i, c := range b {
|
||||
if isValidByte(c) {
|
||||
field[fieldLen] = c
|
||||
fieldLen++
|
||||
} else {
|
||||
if fieldLen > 5 {
|
||||
buf.Write(field[:fieldLen])
|
||||
}
|
||||
fieldLen = 0
|
||||
}
|
||||
|
||||
if i == len(b)-1 && fieldLen > 5 {
|
||||
buf.Write(field[:fieldLen])
|
||||
}
|
||||
}
|
||||
|
||||
return bytes.Join(keep, []byte("\n"))
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/kylelemons/godebug/pretty"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/sources"
|
||||
)
|
||||
|
||||
|
||||
@@ -56,11 +56,11 @@ func TestAWS_FromChunk(t *testing.T) {
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_AWS,
|
||||
Verified: true,
|
||||
Redacted: "AKIAWARWQKZNHMZBLY4I",
|
||||
Redacted: "AKIASP2TPHJSQH3FJRUX",
|
||||
ExtraData: map[string]string{
|
||||
"account": "413504919130",
|
||||
"arn": "arn:aws:iam::413504919130:root",
|
||||
"user_id": "413504919130",
|
||||
"account": "171436882533",
|
||||
"arn": "arn:aws:iam::171436882533:user/canarytokens.com@@4dxkh0pdeop3bzu9zx5wob793",
|
||||
"user_id": "AIDASP2TPHJSUFRSTTZX4",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -78,7 +78,7 @@ func TestAWS_FromChunk(t *testing.T) {
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_AWS,
|
||||
Verified: false,
|
||||
Redacted: "AKIAWARWQKZNHMZBLY4I",
|
||||
Redacted: "AKIASP2TPHJSQH3FJRUX",
|
||||
ExtraData: nil,
|
||||
},
|
||||
},
|
||||
@@ -106,18 +106,18 @@ func TestAWS_FromChunk(t *testing.T) {
|
||||
want: []detectors.Result{
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_AWS,
|
||||
Verified: true,
|
||||
Redacted: id,
|
||||
ExtraData: map[string]string{
|
||||
"account": "413504919130",
|
||||
"arn": "arn:aws:iam::413504919130:root",
|
||||
"user_id": "413504919130",
|
||||
},
|
||||
Verified: false,
|
||||
Redacted: "AKIASP2TPHJSQH3FJXYZ",
|
||||
},
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_AWS,
|
||||
Verified: false,
|
||||
Redacted: inactiveID,
|
||||
Verified: true,
|
||||
Redacted: "AKIASP2TPHJSQH3FJRUX",
|
||||
ExtraData: map[string]string{
|
||||
"account": "171436882533",
|
||||
"arn": "arn:aws:iam::171436882533:user/canarytokens.com@@4dxkh0pdeop3bzu9zx5wob793",
|
||||
"user_id": "AIDASP2TPHJSUFRSTTZX4",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -145,11 +145,11 @@ func TestAWS_FromChunk(t *testing.T) {
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_AWS,
|
||||
Verified: true,
|
||||
Redacted: id,
|
||||
Redacted: "AKIASP2TPHJSQH3FJRUX",
|
||||
ExtraData: map[string]string{
|
||||
"account": "413504919130",
|
||||
"arn": "arn:aws:iam::413504919130:root",
|
||||
"user_id": "413504919130",
|
||||
"account": "171436882533",
|
||||
"arn": "arn:aws:iam::171436882533:user/canarytokens.com@@4dxkh0pdeop3bzu9zx5wob793",
|
||||
"user_id": "AIDASP2TPHJSUFRSTTZX4",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -172,7 +172,7 @@ func TestAWS_FromChunk(t *testing.T) {
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_AWS,
|
||||
Verified: false,
|
||||
Redacted: "AKIAWARWQKZNHMZBLY4I",
|
||||
Redacted: "AKIASP2TPHJSQH3FJRUX",
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -181,7 +181,7 @@ func TestAWS_FromChunk(t *testing.T) {
|
||||
name: "skipped",
|
||||
s: scanner{
|
||||
skipIDs: map[string]struct{}{
|
||||
"AKIAWARWQKZNHMZBLY4I": {},
|
||||
"AKIASP2TPHJSQH3FJRUX": {},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
|
||||
@@ -54,6 +54,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
s := detectors.Result{
|
||||
DetectorType: detectorspb.DetectorType_Azure,
|
||||
Raw: []byte(clientSecret[2]),
|
||||
RawV2: []byte(clientID[2] + clientSecret[2] + tenantID[2]),
|
||||
Redacted: clientID[2],
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
}
|
||||
|
||||
if verify {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "https://api-cloud.browserstack.com/automate/plan.json", nil)
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "https://www.browserstack.com/automate/plan.json", nil)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ var _ detectors.Detector = (*Scanner)(nil)
|
||||
|
||||
var (
|
||||
client = common.SaneHttpClient()
|
||||
keyPat = regexp.MustCompile(`\b([CFPAT\-a-zA-Z-0-9]{49})\b`)
|
||||
keyPat = regexp.MustCompile(`\b(CFPAT-[a-zA-Z0-9_\-]{43})\b`)
|
||||
)
|
||||
|
||||
// Keywords are used for efficiently pre-filtering chunks.
|
||||
|
||||
@@ -51,6 +51,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
s1 := detectors.Result{
|
||||
DetectorType: detectorspb.DetectorType_DatadogToken,
|
||||
Raw: []byte(resMatch),
|
||||
RawV2: []byte(resMatch + resApiMatch),
|
||||
}
|
||||
|
||||
if verify {
|
||||
|
||||
@@ -31,6 +31,13 @@ type Versioner interface {
|
||||
Version() int
|
||||
}
|
||||
|
||||
// EndpointCustomizer is an optional interface that a detector can implement to
|
||||
// support verifying against user-supplied endpoints.
|
||||
type EndpointCustomizer interface {
|
||||
SetEndpoints(...string) error
|
||||
DefaultEndpoint() string
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
// DetectorType is the type of Detector.
|
||||
DetectorType detectorspb.DetectorType
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package detectors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
)
|
||||
|
||||
// EndpointSetter implements a sensible default for the SetEndpoints function
|
||||
// of the EndpointCustomizer interface. A detector can embed this struct to
|
||||
// gain the functionality.
|
||||
type EndpointSetter struct {
|
||||
endpoints []string
|
||||
}
|
||||
|
||||
func (e *EndpointSetter) SetEndpoints(endpoints ...string) error {
|
||||
if len(endpoints) == 0 {
|
||||
return fmt.Errorf("at least one endpoint required")
|
||||
}
|
||||
deduped := make([]string, 0, len(endpoints))
|
||||
for _, endpoint := range endpoints {
|
||||
common.AddStringSliceItem(endpoint, &deduped)
|
||||
}
|
||||
e.endpoints = deduped
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EndpointSetter) Endpoints(defaultEndpoint string) []string {
|
||||
// The only valid time len(e.endpoints) == 0 is when EndpointSetter is
|
||||
// initializetd to its default state. That means SetEndpoints was never
|
||||
// called and we should use the default.
|
||||
if len(e.endpoints) == 0 {
|
||||
return []string{defaultEndpoint}
|
||||
}
|
||||
return e.endpoints
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package detectors
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEmbeddedEndpointSetter(t *testing.T) {
|
||||
type Scanner struct{ EndpointSetter }
|
||||
var s Scanner
|
||||
assert.Equal(t, []string{"baz"}, s.Endpoints("baz"))
|
||||
assert.NoError(t, s.SetEndpoints("foo", "bar"))
|
||||
assert.Error(t, s.SetEndpoints())
|
||||
assert.Equal(t, []string{"foo", "bar"}, s.Endpoints("baz"))
|
||||
}
|
||||
@@ -79,14 +79,16 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
raw = []byte(key)
|
||||
}
|
||||
|
||||
credBytes, _ := json.Marshal(creds)
|
||||
|
||||
s := detectors.Result{
|
||||
DetectorType: detectorspb.DetectorType_GCP,
|
||||
Raw: raw,
|
||||
RawV2: credBytes,
|
||||
Redacted: creds.ClientEmail,
|
||||
}
|
||||
|
||||
if verify {
|
||||
credBytes, _ := json.Marshal(creds)
|
||||
credentials, err := google.CredentialsFromJSON(ctx, credBytes, "https://www.googleapis.com/auth/cloud-platform")
|
||||
if err != nil {
|
||||
continue
|
||||
|
||||
@@ -13,40 +13,15 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
)
|
||||
|
||||
const defaultURL = "https://api.github.com"
|
||||
|
||||
type Scanner struct {
|
||||
verifierURLs []string
|
||||
}
|
||||
|
||||
// New creates a new Scanner with the given options.
|
||||
func New(opts ...func(*Scanner)) *Scanner {
|
||||
scanner := &Scanner{
|
||||
verifierURLs: make([]string, 0),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(scanner)
|
||||
}
|
||||
|
||||
return scanner
|
||||
}
|
||||
|
||||
// WithVerifierURLs adds the given URLs to the list of URLs to check for
|
||||
// verification of secrets.
|
||||
func WithVerifierURLs(urls []string, includeDefault bool) func(*Scanner) {
|
||||
return func(s *Scanner) {
|
||||
if includeDefault {
|
||||
urls = append(urls, defaultURL)
|
||||
}
|
||||
s.verifierURLs = append(s.verifierURLs, urls...)
|
||||
}
|
||||
}
|
||||
type Scanner struct{ detectors.EndpointSetter }
|
||||
|
||||
// Ensure the Scanner satisfies the interfaces at compile time.
|
||||
var _ detectors.Detector = (*Scanner)(nil)
|
||||
var _ detectors.Versioner = (*Scanner)(nil)
|
||||
var _ detectors.EndpointCustomizer = (*Scanner)(nil)
|
||||
|
||||
func (s Scanner) Version() int { return 2 }
|
||||
func (Scanner) Version() int { return 2 }
|
||||
func (Scanner) DefaultEndpoint() string { return "https://api.github.com" }
|
||||
|
||||
var (
|
||||
// Oauth token
|
||||
@@ -82,10 +57,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
|
||||
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
|
||||
|
||||
if len(s.verifierURLs) == 0 {
|
||||
s.verifierURLs = append(s.verifierURLs, defaultURL)
|
||||
}
|
||||
|
||||
for _, match := range matches {
|
||||
// First match is entire regex, second is the first group.
|
||||
if len(match) != 2 {
|
||||
@@ -102,7 +73,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
if verify {
|
||||
client := common.SaneHttpClient()
|
||||
// https://developer.github.com/v3/users/#get-the-authenticated-user
|
||||
for _, url := range s.verifierURLs {
|
||||
for _, url := range s.Endpoints(s.DefaultEndpoint()) {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s/user", url), nil)
|
||||
if err != nil {
|
||||
continue
|
||||
|
||||
@@ -12,40 +12,15 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
const defaultURL = "https://api.github.com"
|
||||
|
||||
type Scanner struct {
|
||||
verifierURLs []string
|
||||
}
|
||||
|
||||
// New creates a new Scanner with the given options.
|
||||
func New(opts ...func(*Scanner)) *Scanner {
|
||||
scanner := &Scanner{
|
||||
verifierURLs: make([]string, 0),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(scanner)
|
||||
}
|
||||
|
||||
return scanner
|
||||
}
|
||||
|
||||
// WithVerifierURLs adds the given URLs to the list of URLs to check for
|
||||
// verification of secrets.
|
||||
func WithVerifierURLs(urls []string, includeDefault bool) func(*Scanner) {
|
||||
return func(s *Scanner) {
|
||||
if includeDefault {
|
||||
urls = append(urls, defaultURL)
|
||||
}
|
||||
s.verifierURLs = append(s.verifierURLs, urls...)
|
||||
}
|
||||
}
|
||||
type Scanner struct{ detectors.EndpointSetter }
|
||||
|
||||
// Ensure the Scanner satisfies the interfaces at compile time.
|
||||
var _ detectors.Detector = (*Scanner)(nil)
|
||||
var _ detectors.Versioner = (*Scanner)(nil)
|
||||
var _ detectors.EndpointCustomizer = (*Scanner)(nil)
|
||||
|
||||
func (s Scanner) Version() int { return 1 }
|
||||
func (Scanner) Version() int { return 1 }
|
||||
func (Scanner) DefaultEndpoint() string { return "https://api.github.com" }
|
||||
|
||||
var (
|
||||
// Oauth token
|
||||
@@ -98,7 +73,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
if verify {
|
||||
client := common.SaneHttpClient()
|
||||
// https://developer.github.com/v3/users/#get-the-authenticated-user
|
||||
for _, url := range s.verifierURLs {
|
||||
for _, url := range s.Endpoints(s.DefaultEndpoint()) {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s/user", url), nil)
|
||||
if err != nil {
|
||||
continue
|
||||
|
||||
@@ -12,40 +12,15 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
const defaultURL = "https://gitlab.com"
|
||||
|
||||
type Scanner struct {
|
||||
verifierURLs []string
|
||||
}
|
||||
|
||||
// New creates a new Scanner with the given options.
|
||||
func New(opts ...func(*Scanner)) *Scanner {
|
||||
scanner := &Scanner{
|
||||
verifierURLs: make([]string, 0),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(scanner)
|
||||
}
|
||||
|
||||
return scanner
|
||||
}
|
||||
|
||||
// WithVerifierURLs adds the given URLs to the list of URLs to check for
|
||||
// verification of secrets.
|
||||
func WithVerifierURLs(urls []string, includeDefault bool) func(*Scanner) {
|
||||
return func(s *Scanner) {
|
||||
if includeDefault {
|
||||
urls = append(urls, defaultURL)
|
||||
}
|
||||
s.verifierURLs = append(s.verifierURLs, urls...)
|
||||
}
|
||||
}
|
||||
type Scanner struct{ detectors.EndpointSetter }
|
||||
|
||||
// Ensure the Scanner satisfies the interfaces at compile time.
|
||||
var _ detectors.Detector = (*Scanner)(nil)
|
||||
var _ detectors.Versioner = (*Scanner)(nil)
|
||||
var _ detectors.EndpointCustomizer = (*Scanner)(nil)
|
||||
|
||||
func (s Scanner) Version() int { return 1 }
|
||||
func (Scanner) Version() int { return 1 }
|
||||
func (Scanner) DefaultEndpoint() string { return "https://gitlab.com" }
|
||||
|
||||
var (
|
||||
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"gitlab"}) + `\b((?:glpat|)[a-zA-Z0-9\-=_]{20,22})\b`)
|
||||
@@ -63,10 +38,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
|
||||
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
|
||||
|
||||
if len(s.verifierURLs) == 0 {
|
||||
s.verifierURLs = append(s.verifierURLs, defaultURL)
|
||||
}
|
||||
|
||||
for _, match := range matches {
|
||||
if len(match) != 2 {
|
||||
continue
|
||||
@@ -89,7 +60,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
// of them contain data, we know we have a valid key, but if they all fail, we don't
|
||||
|
||||
client := common.SaneHttpClient()
|
||||
for _, baseURL := range s.verifierURLs {
|
||||
for _, baseURL := range s.Endpoints(s.DefaultEndpoint()) {
|
||||
// test `read_user` scope
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", baseURL+"/api/v4/user", nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -11,40 +11,15 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
const defaultURL = "https://gitlab.com"
|
||||
|
||||
type Scanner struct {
|
||||
verifierURLs []string
|
||||
}
|
||||
|
||||
// New creates a new Scanner with the given options.
|
||||
func New(opts ...func(*Scanner)) *Scanner {
|
||||
scanner := &Scanner{
|
||||
verifierURLs: make([]string, 0),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(scanner)
|
||||
}
|
||||
|
||||
return scanner
|
||||
}
|
||||
|
||||
// WithVerifierURLs adds the given URLs to the list of URLs to check for
|
||||
// verification of secrets.
|
||||
func WithVerifierURLs(urls []string, includeDefault bool) func(*Scanner) {
|
||||
return func(s *Scanner) {
|
||||
if includeDefault {
|
||||
urls = append(urls, defaultURL)
|
||||
}
|
||||
s.verifierURLs = append(s.verifierURLs, urls...)
|
||||
}
|
||||
}
|
||||
type Scanner struct{ detectors.EndpointSetter }
|
||||
|
||||
// Ensure the Scanner satisfies the interfaces at compile time.
|
||||
var _ detectors.Detector = (*Scanner)(nil)
|
||||
var _ detectors.Versioner = (*Scanner)(nil)
|
||||
var _ detectors.EndpointCustomizer = (*Scanner)(nil)
|
||||
|
||||
func (*Scanner) Version() int { return 2 }
|
||||
func (Scanner) Version() int { return 2 }
|
||||
func (Scanner) DefaultEndpoint() string { return "https://gitlab.com" }
|
||||
|
||||
var (
|
||||
keyPat = regexp.MustCompile(`\b(glpat-[a-zA-Z0-9\-=_]{20,22})\b`)
|
||||
@@ -62,10 +37,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
|
||||
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
|
||||
|
||||
if len(s.verifierURLs) == 0 {
|
||||
s.verifierURLs = append(s.verifierURLs, defaultURL)
|
||||
}
|
||||
|
||||
for _, match := range matches {
|
||||
if len(match) != 2 {
|
||||
continue
|
||||
@@ -82,7 +53,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
// one of these scopes has access to, so we just check an example endpoint for each scope. If any
|
||||
// of them contain data, we know we have a valid key, but if they all fail, we don't
|
||||
client := common.SaneHttpClient()
|
||||
for _, baseURL := range s.verifierURLs {
|
||||
for _, baseURL := range s.Endpoints(s.DefaultEndpoint()) {
|
||||
// test `read_user` scope
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", baseURL+"/api/v4/user", nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -12,7 +13,35 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
type Scanner struct{}
|
||||
type Scanner struct {
|
||||
ignorePatterns []regexp.Regexp
|
||||
}
|
||||
|
||||
func New(opts ...func(*Scanner)) *Scanner {
|
||||
scanner := &Scanner{
|
||||
ignorePatterns: []regexp.Regexp{},
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(scanner)
|
||||
}
|
||||
|
||||
return scanner
|
||||
}
|
||||
|
||||
func WithIgnorePattern(ignoreStrings []string) func(*Scanner) {
|
||||
return func(s *Scanner) {
|
||||
ignorePatterns := []regexp.Regexp{}
|
||||
for _, ignoreString := range ignoreStrings {
|
||||
ignorePattern, err := regexp.Compile(ignoreString)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("%s is not a valid regex, error received: %v", ignoreString, err))
|
||||
}
|
||||
ignorePatterns = append(ignorePatterns, *ignorePattern)
|
||||
}
|
||||
|
||||
s.ignorePatterns = ignorePatterns
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the Scanner satisfies the interface at compile time.
|
||||
var _ detectors.Detector = (*Scanner)(nil)
|
||||
@@ -32,7 +61,15 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
dataStr := string(data)
|
||||
|
||||
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
|
||||
matchLoop:
|
||||
for _, match := range matches {
|
||||
if len(s.ignorePatterns) != 0 {
|
||||
for _, ignore := range s.ignorePatterns {
|
||||
if ignore.MatchString(match[0]) {
|
||||
continue matchLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
jdbcConn := match[0]
|
||||
|
||||
s := detectors.Result{
|
||||
|
||||
@@ -156,6 +156,57 @@ func TestJdbc_FromChunk(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestJdbc_FromDataWithIgnorePattern(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
data []byte
|
||||
verify bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []detectors.Result
|
||||
ignorePatterns []string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "not found",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
data: []byte("jdbc:sqlite::secretpattern:"),
|
||||
verify: false,
|
||||
},
|
||||
want: nil,
|
||||
ignorePatterns: []string{
|
||||
".*secretpattern.*",
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := New(WithIgnorePattern(tt.ignorePatterns))
|
||||
got, err := s.FromData(tt.args.ctx, tt.args.verify, tt.args.data)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("Jdbc.FromDataWithConfig() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if os.Getenv("FORCE_PASS_DIFF") == "true" {
|
||||
return
|
||||
}
|
||||
for i := range got {
|
||||
if len(got[i].Raw) == 0 {
|
||||
t.Fatal("no raw secret present")
|
||||
}
|
||||
got[i].Raw = nil
|
||||
}
|
||||
if diff := pretty.Compare(got, tt.want); diff != "" {
|
||||
t.Errorf("Jdbc.FromDataWithConfig() %s diff: (-got +want)\n%s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFromData(benchmark *testing.B) {
|
||||
ctx := context.Background()
|
||||
s := Scanner{}
|
||||
|
||||
@@ -24,7 +24,12 @@ var (
|
||||
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
|
||||
tokenPat = regexp.MustCompile(detectors.PrefixRegex([]string{"jira"}) + `\b([a-zA-Z-0-9]{24})\b`)
|
||||
domainPat = regexp.MustCompile(detectors.PrefixRegex([]string{"jira"}) + `\b([a-zA-Z-0-9]{5,24}\.[a-zA-Z-0-9]{3,16}\.[a-zA-Z-0-9]{3,16})\b`)
|
||||
emailPat = regexp.MustCompile(detectors.PrefixRegex([]string{"jira"}) + `\b([a-zA-Z-0-9]{5,24}\@[a-zA-Z-0-9]{3,16}\.com)\b`)
|
||||
emailPat = regexp.MustCompile(detectors.PrefixRegex([]string{"jira"}) + `\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b`)
|
||||
)
|
||||
|
||||
const (
|
||||
failedAuth = "AUTHENTICATED_FAILED"
|
||||
loginReasonHeaderKey = "X-Seraph-LoginReason"
|
||||
)
|
||||
|
||||
// Keywords are used for efficiently pre-filtering chunks.
|
||||
@@ -42,6 +47,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
emails := emailPat.FindAllStringSubmatch(dataStr, -1)
|
||||
|
||||
for _, email := range emails {
|
||||
email = strings.Split(email[0], " ")
|
||||
if len(email) != 2 {
|
||||
continue
|
||||
}
|
||||
@@ -60,10 +66,10 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
s1 := detectors.Result{
|
||||
DetectorType: detectorspb.DetectorType_JiraToken,
|
||||
Raw: []byte(resToken),
|
||||
RawV2: []byte(fmt.Sprintf("%s:%s:%s", resEmail, resToken, resDomain)),
|
||||
}
|
||||
|
||||
if verify {
|
||||
|
||||
data := fmt.Sprintf("%s:%s", resEmail, resToken)
|
||||
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "https://"+resDomain+"/rest/api/3/dashboard", nil)
|
||||
@@ -75,7 +81,11 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
res, err := client.Do(req)
|
||||
if err == nil {
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode >= 200 && res.StatusCode < 300 {
|
||||
|
||||
// If the request is successful and the login reason is not failed authentication, then the token is valid.
|
||||
// This is because Jira returns a 200 status code even if the token is invalid.
|
||||
// Jira returns a default dashboard page.
|
||||
if (res.StatusCode >= 200 && res.StatusCode < 300) && res.Header.Get(loginReasonHeaderKey) != failedAuth {
|
||||
s1.Verified = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ func TestJiraToken_FromChunk(t *testing.T) {
|
||||
t.Fatalf("no raw secret present: \n %+v", got[i])
|
||||
}
|
||||
got[i].Raw = nil
|
||||
got[i].RawV2 = nil
|
||||
}
|
||||
if diff := pretty.Compare(got, tt.want); diff != "" {
|
||||
t.Errorf("JiraToken.FromData() %s diff: (-got +want)\n%s", tt.name, diff)
|
||||
|
||||
@@ -41,6 +41,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
s := detectors.Result{
|
||||
DetectorType: detectorspb.DetectorType_Okta,
|
||||
Raw: []byte(token),
|
||||
RawV2: []byte(fmt.Sprintf("%s:%s", domain, token)),
|
||||
}
|
||||
|
||||
if verify {
|
||||
|
||||
@@ -50,6 +50,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
s := detectors.Result{
|
||||
DetectorType: detectorspb.DetectorType_OneLogin,
|
||||
Raw: []byte(clientID[1]),
|
||||
RawV2: []byte(fmt.Sprintf("%s:%s", clientID[1], clientSecret[1])),
|
||||
Redacted: clientID[1],
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package percy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
type Scanner struct{}
|
||||
|
||||
// Ensure the Scanner satisfies the interface at compile time.
|
||||
var _ detectors.Detector = (*Scanner)(nil)
|
||||
|
||||
var (
|
||||
client = common.SaneHttpClient()
|
||||
|
||||
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
|
||||
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"percy"}) + `\bPERCY_TOKEN=([0-9Aa-f]{64})\b`)
|
||||
)
|
||||
|
||||
// Keywords are used for efficiently pre-filtering chunks.
|
||||
// Use identifiers in the secret preferably, or the provider name.
|
||||
func (s Scanner) Keywords() []string {
|
||||
return []string{"percy"}
|
||||
}
|
||||
|
||||
// FromData will find and optionally verify Percy secrets in a given set of bytes.
|
||||
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
|
||||
dataStr := string(data)
|
||||
|
||||
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
|
||||
|
||||
for _, match := range matches {
|
||||
if len(match) != 2 {
|
||||
continue
|
||||
}
|
||||
resMatch := strings.TrimSpace(match[1])
|
||||
|
||||
s1 := detectors.Result{
|
||||
DetectorType: detectorspb.DetectorType_Percy,
|
||||
Raw: []byte(resMatch),
|
||||
}
|
||||
|
||||
if verify {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "https://percy.io/api/v1/projects", nil)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
req.Header.Add("Accept", "application/vnd.percy+json; version=3")
|
||||
req.Header.Add("Authorization", fmt.Sprintf("Token %s", resMatch))
|
||||
res, err := client.Do(req)
|
||||
if err == nil {
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode >= 200 && res.StatusCode < 300 {
|
||||
s1.Verified = true
|
||||
} else {
|
||||
// This function will check false positives for common test words, but also it will make sure the key appears 'random' enough to be a real key.
|
||||
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results = append(results, s1)
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (s Scanner) Type() detectorspb.DetectorType {
|
||||
return detectorspb.DetectorType_Percy
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
//go:build detectors
|
||||
// +build detectors
|
||||
|
||||
package percy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/kylelemons/godebug/pretty"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
func TestPercy_FromChunk(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
testSecrets, err := common.GetSecret(ctx, "trufflehog-testing", "detectors2")
|
||||
if err != nil {
|
||||
t.Fatalf("could not get test secrets from GCP: %s", err)
|
||||
}
|
||||
secret := testSecrets.MustGetField("PERCY_VERIFIED")
|
||||
inactiveSecret := testSecrets.MustGetField("PERCY_INACTIVE")
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
data []byte
|
||||
verify bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
s Scanner
|
||||
args args
|
||||
want []detectors.Result
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "found, verified",
|
||||
s: Scanner{},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
data: []byte(fmt.Sprintf("You can find a percy secret %s within", secret)),
|
||||
verify: true,
|
||||
},
|
||||
want: []detectors.Result{
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_Percy,
|
||||
Verified: true,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "found, unverified",
|
||||
s: Scanner{},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
data: []byte(fmt.Sprintf("You can find a percy secret %s within but not valid", inactiveSecret)), // the secret would satisfy the regex but not pass validation
|
||||
verify: true,
|
||||
},
|
||||
want: []detectors.Result{
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_Percy,
|
||||
Verified: false,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "not found",
|
||||
s: Scanner{},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
data: []byte("You cannot find the secret within"),
|
||||
verify: true,
|
||||
},
|
||||
want: nil,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := Scanner{}
|
||||
got, err := s.FromData(tt.args.ctx, tt.args.verify, tt.args.data)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("Percy.FromData() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
for i := range got {
|
||||
if len(got[i].Raw) == 0 {
|
||||
t.Fatalf("no raw secret present: \n %+v", got[i])
|
||||
}
|
||||
got[i].Raw = nil
|
||||
}
|
||||
if diff := pretty.Compare(got, tt.want); diff != "" {
|
||||
t.Errorf("Percy.FromData() %s diff: (-got +want)\n%s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFromData(benchmark *testing.B) {
|
||||
ctx := context.Background()
|
||||
s := Scanner{}
|
||||
for name, data := range detectors.MustGetBenchmarkData() {
|
||||
benchmark.Run(name, func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
_, err := s.FromData(ctx, false, data)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ var (
|
||||
// Keywords are used for efficiently pre-filtering chunks.
|
||||
// Use identifiers in the secret preferably, or the provider name.
|
||||
func (s Scanner) Keywords() []string {
|
||||
return []string{"sqlserver"}
|
||||
return []string{"sql", "database", "Data Source"}
|
||||
}
|
||||
|
||||
// FromData will find and optionally verify SpotifyKey secrets in a given set of bytes.
|
||||
|
||||
@@ -5,14 +5,15 @@ package sqlserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/denisenkom/go-mssqldb/msdsn"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"testing"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
@@ -75,6 +76,59 @@ func TestSQLServer_FromChunk(t *testing.T) {
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "not found, in XML, missing password param (pwd is not valid)",
|
||||
s: Scanner{},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
data: []byte(`<add name="Sample2" value="SERVER=server_name;DATABASE=database_name;user=user_name;pwd=plaintextpassword;encrypt=true;Timeout=120;MultipleActiveResultSets=True;" />`),
|
||||
verify: true,
|
||||
},
|
||||
want: nil,
|
||||
wantErr: false,
|
||||
mockFunc: func() {
|
||||
ping = func(config msdsn.Config) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "found, verified, in XML",
|
||||
s: Scanner{},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
data: []byte(`<add name="test db" value="SERVER=server_name;DATABASE=testdb;user=username;password=badpassword;encrypt=true;Timeout=120;MultipleActiveResultSets=True;" />`),
|
||||
verify: true,
|
||||
},
|
||||
want: []detectors.Result{
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_SQLServer,
|
||||
Verified: true,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
mockFunc: func() {
|
||||
ping = func(config msdsn.Config) (bool, error) {
|
||||
if config.Host != "server_name" {
|
||||
return false, errors.New("invalid host")
|
||||
}
|
||||
|
||||
if config.User != "username" {
|
||||
return false, errors.New("invalid database")
|
||||
}
|
||||
|
||||
if config.Password != "badpassword" {
|
||||
return false, errors.New("invalid password")
|
||||
}
|
||||
|
||||
if config.Database != "testdb" {
|
||||
return false, errors.New("invalid database")
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "not found",
|
||||
s: Scanner{},
|
||||
@@ -119,13 +173,16 @@ func TestSQLServer_FromChunk(t *testing.T) {
|
||||
|
||||
func TestSQLServer_pattern(t *testing.T) {
|
||||
if !pattern.Match([]byte(`builder.Services.AddDbContext<Database>(optionsBuilder => optionsBuilder.UseSqlServer("Server=localhost;Initial Catalog=master;User ID=sa;Password=P@ssw0rd!;Persist Security Info=true;MultipleActiveResultSets=true;"));`)) {
|
||||
t.Errorf("SQLServer.pattern: did not catched connection string from Program.cs")
|
||||
t.Errorf("SQLServer.pattern: did not find connection string from Program.cs")
|
||||
}
|
||||
if !pattern.Match([]byte(`{"ConnectionStrings": {"Demo": "Server=localhost;Initial Catalog=master;User ID=sa;Password=P@ssw0rd!;Persist Security Info=true;MultipleActiveResultSets=true;"}}`)) {
|
||||
t.Errorf("SQLServer.pattern: did not catched connection string from appsettings.json")
|
||||
t.Errorf("SQLServer.pattern: did not find connection string from appsettings.json")
|
||||
}
|
||||
if !pattern.Match([]byte(`CONNECTION_STRING: Server=localhost;Initial Catalog=master;User ID=sa;Password=P@ssw0rd!;Persist Security Info=true;MultipleActiveResultSets=true`)) {
|
||||
t.Errorf("SQLServer.pattern: did not catched connection string from .env")
|
||||
t.Errorf("SQLServer.pattern: did not find connection string from .env")
|
||||
}
|
||||
if !pattern.Match([]byte(`<add name="Sample2" value="SERVER=server_name;DATABASE=database_name;user=user_name;pwd=plaintextpassword;encrypt=true;Timeout=120;MultipleActiveResultSets=True;" />`)) {
|
||||
t.Errorf("SQLServer.pattern: did not find connection string in xml format")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package tineswebhook
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
type Scanner struct{}
|
||||
|
||||
// Ensure the Scanner satisfies the interface at compile time.
|
||||
var _ detectors.Detector = (*Scanner)(nil)
|
||||
|
||||
var (
|
||||
client = common.SaneHttpClient()
|
||||
|
||||
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
|
||||
keyPat = regexp.MustCompile(`(https://[\w-]+\.tines\.com/webhook/[a-z0-9]{32}/[a-z0-9]{32})`)
|
||||
)
|
||||
|
||||
// Keywords are used for efficiently pre-filtering chunks.
|
||||
// Use identifiers in the secret preferably, or the provider name.
|
||||
func (s Scanner) Keywords() []string {
|
||||
return []string{"tines.com"}
|
||||
}
|
||||
|
||||
// FromData will find and optionally verify TinesWebhook secrets in a given set of bytes.
|
||||
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
|
||||
dataStr := string(data)
|
||||
|
||||
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
|
||||
|
||||
for _, match := range matches {
|
||||
if len(match) != 2 {
|
||||
continue
|
||||
}
|
||||
resMatch := strings.TrimSpace(match[1])
|
||||
|
||||
s1 := detectors.Result{
|
||||
DetectorType: detectorspb.DetectorType_TinesWebhook,
|
||||
Raw: []byte(resMatch),
|
||||
}
|
||||
|
||||
if verify {
|
||||
payload := strings.NewReader(``)
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", resMatch, payload)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
res, err := client.Do(req)
|
||||
if err == nil {
|
||||
defer res.Body.Close()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if res.StatusCode >= 200 && res.StatusCode < 300 {
|
||||
s1.Verified = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results = append(results, s1)
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (s Scanner) Type() detectorspb.DetectorType {
|
||||
return detectorspb.DetectorType_TinesWebhook
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
//go:build detectors
|
||||
// +build detectors
|
||||
|
||||
package tineswebhook
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/kylelemons/godebug/pretty"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
func TestTinesWebhook_FromChunk(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
testSecrets, err := common.GetSecret(ctx, "trufflehog-testing", "detectors3")
|
||||
if err != nil {
|
||||
t.Fatalf("could not get test secrets from GCP: %s", err)
|
||||
}
|
||||
secret := testSecrets.MustGetField("TINESWEBHOOK_TOKEN")
|
||||
inactiveSecret := testSecrets.MustGetField("TINESWEBHOOK_INACTIVE")
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
data []byte
|
||||
verify bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
s Scanner
|
||||
args args
|
||||
want []detectors.Result
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "found, verified",
|
||||
s: Scanner{},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
data: []byte(fmt.Sprintf("You can find a tineswebhook secret %s within", secret)),
|
||||
verify: true,
|
||||
},
|
||||
want: []detectors.Result{
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_TinesWebhook,
|
||||
Verified: true,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "found, unverified",
|
||||
s: Scanner{},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
data: []byte(fmt.Sprintf("You can find a tineswebhook secret %s within but not valid", inactiveSecret)), // the secret would satisfy the regex but not pass validation
|
||||
verify: true,
|
||||
},
|
||||
want: []detectors.Result{
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_TinesWebhook,
|
||||
Verified: false,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "not found",
|
||||
s: Scanner{},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
data: []byte("You cannot find the secret within"),
|
||||
verify: true,
|
||||
},
|
||||
want: nil,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := Scanner{}
|
||||
got, err := s.FromData(tt.args.ctx, tt.args.verify, tt.args.data)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("TinesWebhook.FromData() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
for i := range got {
|
||||
if len(got[i].Raw) == 0 {
|
||||
t.Fatalf("no raw secret present: \n %+v", got[i])
|
||||
}
|
||||
got[i].Raw = nil
|
||||
}
|
||||
if diff := pretty.Compare(got, tt.want); diff != "" {
|
||||
t.Errorf("TinesWebhook.FromData() %s diff: (-got +want)\n%s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFromData(benchmark *testing.B) {
|
||||
ctx := context.Background()
|
||||
s := Scanner{}
|
||||
for name, data := range detectors.MustGetBenchmarkData() {
|
||||
benchmark.Run(name, func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
_, err := s.FromData(ctx, false, data)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -66,12 +66,15 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
}
|
||||
|
||||
rawURL, _ := url.Parse(urlMatch)
|
||||
rawURLStr := rawURL.String()
|
||||
// Removing the path causes possible deduplication issues if some paths have basic auth and some do not.
|
||||
rawURL.Path = ""
|
||||
redact := strings.TrimSpace(strings.Replace(rawURL.String(), password, "********", -1))
|
||||
|
||||
s := detectors.Result{
|
||||
DetectorType: detectorspb.DetectorType_URI,
|
||||
Raw: []byte(rawURL.String()),
|
||||
RawV2: []byte(rawURLStr),
|
||||
Redacted: redact,
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ func TestURI_FromChunk(t *testing.T) {
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_URI,
|
||||
Verified: false,
|
||||
Redacted: "https://user:****@www.httpwatch.com",
|
||||
Redacted: "https://user:********@www.httpwatch.com",
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -55,7 +55,7 @@ func TestURI_FromChunk(t *testing.T) {
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_URI,
|
||||
Verified: true,
|
||||
Redacted: "https://httpwatch:****@www.httpwatch.com",
|
||||
Redacted: "https://httpwatch:********@www.httpwatch.com",
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -72,7 +72,7 @@ func TestURI_FromChunk(t *testing.T) {
|
||||
{
|
||||
DetectorType: detectorspb.DetectorType_URI,
|
||||
Verified: true,
|
||||
Redacted: "https://httpwatch:****@www.httpwatch.com",
|
||||
Redacted: "https://httpwatch:********@www.httpwatch.com",
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
@@ -101,6 +101,7 @@ func TestURI_FromChunk(t *testing.T) {
|
||||
// }
|
||||
for i := range got {
|
||||
got[i].Raw = nil
|
||||
got[i].RawV2 = nil
|
||||
}
|
||||
if diff := pretty.Compare(got, tt.want); diff != "" {
|
||||
t.Errorf("URI.FromData() %s diff: (-got +want)\n%s", tt.name, diff)
|
||||
|
||||
+21
-67
@@ -1,7 +1,6 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/abbysale"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/abuseipdb"
|
||||
@@ -16,6 +15,7 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/airship"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/airtableapikey"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/airvisual"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/alchemy"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/alconost"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/alegra"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/aletheiaapi"
|
||||
@@ -75,6 +75,7 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/blablabus"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/blazemeter"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/blitapp"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/blocknative"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/blogger"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/bombbomb"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/boostnote"
|
||||
@@ -83,6 +84,7 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/brandfetch"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/browserstack"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/browshot"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/bscscan"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/buddyns"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/bugherd"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/bugsnag"
|
||||
@@ -142,6 +144,7 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/coinbase"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/coinlayer"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/coinlib"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/coinmarketcap"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/collect2"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/column"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/commercejs"
|
||||
@@ -213,6 +216,7 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/elasticemail"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/enablex"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/enigma"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/etherscan"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ethplorer"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/etsyapikey"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/everhour"
|
||||
@@ -319,6 +323,7 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/imagekit"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/imagga"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/impala"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/infura"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/insightly"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/instabot"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/integromat"
|
||||
@@ -408,6 +413,7 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/monkeylearn"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/moonclerk"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/moosend"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/moralis"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/mrticktock"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/mux"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/myfreshworks"
|
||||
@@ -471,6 +477,7 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/pdfshift"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/peopledatalabs"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/pepipost"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/percy"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/pinata"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/pipedream"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/pipedrive"
|
||||
@@ -651,6 +658,7 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/tiingo"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/timecamp"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/timezoneapi"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/tineswebhook"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/tmetric"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/todoist"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/tokeet"
|
||||
@@ -733,74 +741,8 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/zonkafeedback"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/zulipchat"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/etherscan"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/infura"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/alchemy"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/blocknative"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/moralis"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/bscscan"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/coinmarketcap"
|
||||
)
|
||||
|
||||
// CustomDetectors returns a list of detectors that are enabled by default, but
|
||||
// can be overridden by the user.
|
||||
func CustomDetectors(ctx context.Context, urls map[string][]string) []detectors.Detector {
|
||||
defaultDetectors := DefaultDetectors()
|
||||
if len(urls) == 0 {
|
||||
return defaultDetectors
|
||||
}
|
||||
|
||||
for i, detector := range defaultDetectors {
|
||||
|
||||
switch detector.Type() {
|
||||
case detectorspb.DetectorType_Github:
|
||||
githubUrls, ok := urls["github"]
|
||||
if !ok {
|
||||
ctx.Logger().V(2).Info("no GitHub urls to ignore")
|
||||
continue
|
||||
}
|
||||
ctx.Logger().V(2).Info("ignoring GitHub urls: %v", githubUrls)
|
||||
|
||||
versioner, ok := detector.(detectors.Versioner)
|
||||
if !ok {
|
||||
ctx.Logger().V(2).Info("Failed to get version for GitHub detector")
|
||||
}
|
||||
switch versioner.Version() {
|
||||
case 1:
|
||||
defaultDetectors[i] = github_old.New(github_old.WithVerifierURLs(githubUrls, true))
|
||||
default:
|
||||
defaultDetectors[i] = github.New(github.WithVerifierURLs(githubUrls, true))
|
||||
}
|
||||
|
||||
case detectorspb.DetectorType_Gitlab:
|
||||
gitlabUrls, ok := urls["gitlab"]
|
||||
if !ok {
|
||||
ctx.Logger().V(2).Info("no GitLab urls to ignore")
|
||||
continue
|
||||
}
|
||||
ctx.Logger().V(2).Info("ignoring GitLab urls: %v", gitlabUrls)
|
||||
|
||||
versioner, ok := detector.(detectors.Versioner)
|
||||
if !ok {
|
||||
ctx.Logger().V(2).Info("Failed to get version for Gitlab detector")
|
||||
}
|
||||
switch versioner.Version() {
|
||||
case 1:
|
||||
defaultDetectors[i] = gitlab.New(gitlab.WithVerifierURLs(gitlabUrls, true))
|
||||
default:
|
||||
defaultDetectors[i] = gitlabv2.New(gitlabv2.WithVerifierURLs(gitlabUrls, true))
|
||||
}
|
||||
|
||||
case detectorspb.DetectorType_JiraToken:
|
||||
// TODO(ahrav): Double check that we need to do this.
|
||||
default:
|
||||
ctx.Logger().V(5).Info("ignoring custom detector", "type", detector.Type())
|
||||
continue
|
||||
}
|
||||
}
|
||||
return defaultDetectors
|
||||
}
|
||||
|
||||
func DefaultDetectors() []detectors.Detector {
|
||||
return []detectors.Detector{
|
||||
&heroku.Scanner{},
|
||||
@@ -1565,6 +1507,18 @@ func DefaultDetectors() []detectors.Detector {
|
||||
moralis.Scanner{},
|
||||
bscscan.Scanner{},
|
||||
coinmarketcap.Scanner{},
|
||||
percy.Scanner{},
|
||||
tineswebhook.Scanner{},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func DefaultDetectorTypesImplementing[T any]() map[detectorspb.DetectorType]struct{} {
|
||||
out := make(map[detectorspb.DetectorType]struct{})
|
||||
for _, detector := range DefaultDetectors() {
|
||||
if _, ok := detector.(T); ok {
|
||||
out[detector.Type()] = struct{}{}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
|
||||
)
|
||||
|
||||
func TestDefaultDetectorsHaveUniqueVersions(t *testing.T) {
|
||||
detectorTypeToVersions := make(map[detectorspb.DetectorType]map[int]struct{})
|
||||
addVersion := func(versions map[int]struct{}, version int) map[int]struct{} {
|
||||
if versions == nil {
|
||||
versions = make(map[int]struct{})
|
||||
}
|
||||
versions[version] = struct{}{}
|
||||
return versions
|
||||
}
|
||||
// Loop through all our default detectors and find the ones that
|
||||
// implement Versioner. Of those, check each version number is unique.
|
||||
for _, detector := range DefaultDetectors() {
|
||||
v, ok := detector.(detectors.Versioner)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
version := v.Version()
|
||||
key := detector.Type()
|
||||
if set, ok := detectorTypeToVersions[key]; ok && set != nil {
|
||||
if _, ok := set[version]; ok {
|
||||
t.Errorf("detector %q has duplicate version: %d", detectorspb.DetectorType_name[int32(key)], version)
|
||||
}
|
||||
}
|
||||
detectorTypeToVersions[key] = addVersion(detectorTypeToVersions[key], version)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultDetectorTypesImplementing(t *testing.T) {
|
||||
isVersioner := DefaultDetectorTypesImplementing[detectors.Versioner]()
|
||||
for _, detector := range DefaultDetectors() {
|
||||
_, expectedOk := detector.(detectors.Versioner)
|
||||
_, gotOk := isVersioner[detector.Type()]
|
||||
if expectedOk == gotOk {
|
||||
continue
|
||||
}
|
||||
t.Errorf(
|
||||
"detector %q doesn't match expected",
|
||||
detectorspb.DetectorType_name[int32(detector.Type())],
|
||||
)
|
||||
}
|
||||
}
|
||||
+23
-7
@@ -13,6 +13,7 @@ import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/config"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/decoders"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
@@ -149,13 +150,28 @@ func Start(ctx context.Context, options ...EngineOption) *Engine {
|
||||
})
|
||||
e.prefilter = builder.Build(keywords)
|
||||
|
||||
ctx.Logger().V(2).Info("loaded decoders", "count", len(e.decoders))
|
||||
ctx.Logger().V(2).Info("loaded detectors",
|
||||
ctx.Logger().Info("loaded decoders", "count", len(e.decoders))
|
||||
ctx.Logger().Info("loaded detectors",
|
||||
"total", len(e.detectors[true])+len(e.detectors[false]),
|
||||
"verification_enabled", len(e.detectors[true]),
|
||||
"verification_disabled", len(e.detectors[false]),
|
||||
)
|
||||
|
||||
// Sanity check detectors for duplicate configuration. Only log in case
|
||||
// a detector has been configured in a way that isn't represented by
|
||||
// the DetectorID (type and version).
|
||||
{
|
||||
dets := append(e.detectors[true], e.detectors[false]...)
|
||||
seenDetectors := make(map[config.DetectorID]struct{}, len(dets))
|
||||
for _, det := range dets {
|
||||
id := config.GetDetectorID(det)
|
||||
if _, ok := seenDetectors[id]; ok {
|
||||
ctx.Logger().Info("possible duplicate detector configured", "detector", id)
|
||||
}
|
||||
seenDetectors[id] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// Start the workers.
|
||||
for i := 0; i < e.concurrency; i++ {
|
||||
e.workersWg.Add(1)
|
||||
@@ -238,6 +254,8 @@ func (e *Engine) detectorWorker(ctx context.Context) {
|
||||
decoderType = detectorspb.DecoderType_PLAIN
|
||||
case *decoders.Base64:
|
||||
decoderType = detectorspb.DecoderType_BASE64
|
||||
case *decoders.UTF16:
|
||||
decoderType = detectorspb.DecoderType_UTF16
|
||||
default:
|
||||
ctx.Logger().Info("unknown decoder type", "type", reflect.TypeOf(decoder).String())
|
||||
decoderType = detectorspb.DecoderType_UNKNOWN
|
||||
@@ -247,11 +265,9 @@ func (e *Engine) detectorWorker(ctx context.Context) {
|
||||
continue
|
||||
}
|
||||
|
||||
dataLower := strings.ToLower(string(decoded.Data))
|
||||
matches := e.prefilter.FindAll(dataLower)
|
||||
|
||||
for _, m := range matches {
|
||||
matchedKeywords[dataLower[m.Start():m.End()]] = struct{}{}
|
||||
// build a map of all keywords that were matched in the chunk
|
||||
for _, m := range e.prefilter.FindAll(string(decoded.Data)) {
|
||||
matchedKeywords[strings.ToLower(string(decoded.Data[m.Start():m.End()]))] = struct{}{}
|
||||
}
|
||||
|
||||
for verify, detectorsSet := range e.detectors {
|
||||
|
||||
@@ -193,6 +193,7 @@ func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, commitChan ch
|
||||
outReader := bufio.NewReader(stdOut)
|
||||
var currentCommit *Commit
|
||||
var currentDiff *Diff
|
||||
var recentlyPassedAuthor bool
|
||||
|
||||
defer common.RecoverWithExit(ctx)
|
||||
defer close(commitChan)
|
||||
@@ -225,6 +226,7 @@ func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, commitChan ch
|
||||
}
|
||||
case isAuthorLine(line):
|
||||
currentCommit.Author = strings.TrimRight(string(line[8:]), "\n")
|
||||
recentlyPassedAuthor = true
|
||||
case isDateLine(line):
|
||||
date, err := time.Parse(c.dateFormat, strings.TrimSpace(string(line[6:])))
|
||||
if err != nil {
|
||||
@@ -261,6 +263,7 @@ func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, commitChan ch
|
||||
case isModeLine(line):
|
||||
// NoOp
|
||||
case isIndexLine(line):
|
||||
recentlyPassedAuthor = false
|
||||
// NoOp
|
||||
case isPlusFileLine(line):
|
||||
currentDiff.PathB = strings.TrimRight(strings.TrimRight(string(line[6:]), "\n"), "\t") // Trim the newline and tab characters. https://github.com/trufflesecurity/trufflehog/issues/1060
|
||||
@@ -271,7 +274,9 @@ func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, commitChan ch
|
||||
case isMinusDiffLine(line):
|
||||
// NoOp. We only care about additions.
|
||||
case isMessageLine(line):
|
||||
currentCommit.Message.Write(line[4:])
|
||||
if recentlyPassedAuthor {
|
||||
currentCommit.Message.Write(line[4:])
|
||||
}
|
||||
case isContextDiffLine(line):
|
||||
currentDiff.Content.Write([]byte("\n"))
|
||||
case isBinaryLine(line):
|
||||
|
||||
@@ -2,6 +2,7 @@ package gitparse
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -228,6 +229,38 @@ func TestMaxCommitSize(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestMessageParsing(t *testing.T) {
|
||||
r := bytes.NewReader([]byte(fmt.Sprintf(singleCommitTabbedContent, ` `)))
|
||||
commitChan := make(chan Commit)
|
||||
parser := NewParser()
|
||||
expectedMessage := singleCommitSingleDiffMessage
|
||||
|
||||
go func() {
|
||||
parser.FromReader(context.TODO(), r, commitChan)
|
||||
}()
|
||||
for commit := range commitChan {
|
||||
if commit.Message.String() != expectedMessage {
|
||||
t.Errorf("Message does not match. Got:\n%s\nexpected:\n%s", commit.Message.String(), expectedMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const singleCommitTabbedContent = `commit 70001020fab32b1fcf2f1f0e5c66424eae649826 (HEAD -> master, origin/master, origin/HEAD)
|
||||
Author: Dustin Decker <humanatcomputer@gmail.com>
|
||||
Date: Mon Mar 15 23:27:16 2021 -0700
|
||||
|
||||
Update aws
|
||||
|
||||
diff --git a/aws b/aws
|
||||
index 2ee133b..12b4843 100644
|
||||
--- a/aws
|
||||
+++ b/aws
|
||||
@@ -1,7 +1,5 @@
|
||||
+[default]
|
||||
%saws_access_key_id = AKIAXYZDQCEN4B6JSJQI
|
||||
+aws_secret_access_key = Tg0pz8Jii8hkLx4+PnUisM8GmKs3a2DK+9qz/lie
|
||||
`
|
||||
|
||||
const singleCommitSingleDiff = `commit 70001020fab32b1fcf2f1f0e5c66424eae649826 (HEAD -> master, origin/master, origin/HEAD)
|
||||
Author: Dustin Decker <humanatcomputer@gmail.com>
|
||||
Date: Mon Mar 15 23:27:16 2021 -0700
|
||||
|
||||
@@ -29,6 +29,9 @@ func PrintJSON(r *detectors.ResultWithMetadata) error {
|
||||
Verified bool
|
||||
// Raw contains the raw secret data.
|
||||
Raw string
|
||||
// RawV2 contains the raw secret identifier that is a combination of both the ID and the secret.
|
||||
// This is used for secrets that are multi part and could have the same ID. Ex: AWS credentials
|
||||
RawV2 string
|
||||
// Redacted contains the redacted version of the raw secret identification data for display purposes.
|
||||
// A secret ID should be used if available.
|
||||
Redacted string
|
||||
@@ -44,6 +47,7 @@ func PrintJSON(r *detectors.ResultWithMetadata) error {
|
||||
DecoderName: r.DecoderType.String(),
|
||||
Verified: r.Verified,
|
||||
Raw: string(r.Raw),
|
||||
RawV2: string(r.RawV2),
|
||||
Redacted: r.Redacted,
|
||||
ExtraData: r.ExtraData,
|
||||
StructuredData: r.StructuredData,
|
||||
|
||||
+929
-918
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1267,117 +1267,6 @@ var _ interface {
|
||||
ErrorName() string
|
||||
} = GitlabValidationError{}
|
||||
|
||||
// Validate checks the field values on GoogleDrive with the rules defined in
|
||||
// the proto definition for this message. If any rules are violated, the first
|
||||
// error encountered is returned, or nil if there are no violations.
|
||||
func (m *GoogleDrive) Validate() error {
|
||||
return m.validate(false)
|
||||
}
|
||||
|
||||
// ValidateAll checks the field values on GoogleDrive with the rules defined in
|
||||
// the proto definition for this message. If any rules are violated, the
|
||||
// result is a list of violation errors wrapped in GoogleDriveMultiError, or
|
||||
// nil if none found.
|
||||
func (m *GoogleDrive) ValidateAll() error {
|
||||
return m.validate(true)
|
||||
}
|
||||
|
||||
func (m *GoogleDrive) validate(all bool) error {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errors []error
|
||||
|
||||
// no validation rules for File
|
||||
|
||||
// no validation rules for Link
|
||||
|
||||
// no validation rules for Email
|
||||
|
||||
// no validation rules for Timestamp
|
||||
|
||||
// no validation rules for Shared
|
||||
|
||||
// no validation rules for LastModifiedBy
|
||||
|
||||
if len(errors) > 0 {
|
||||
return GoogleDriveMultiError(errors)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GoogleDriveMultiError is an error wrapping multiple validation errors
|
||||
// returned by GoogleDrive.ValidateAll() if the designated constraints aren't met.
|
||||
type GoogleDriveMultiError []error
|
||||
|
||||
// Error returns a concatenation of all the error messages it wraps.
|
||||
func (m GoogleDriveMultiError) Error() string {
|
||||
var msgs []string
|
||||
for _, err := range m {
|
||||
msgs = append(msgs, err.Error())
|
||||
}
|
||||
return strings.Join(msgs, "; ")
|
||||
}
|
||||
|
||||
// AllErrors returns a list of validation violation errors.
|
||||
func (m GoogleDriveMultiError) AllErrors() []error { return m }
|
||||
|
||||
// GoogleDriveValidationError is the validation error returned by
|
||||
// GoogleDrive.Validate if the designated constraints aren't met.
|
||||
type GoogleDriveValidationError struct {
|
||||
field string
|
||||
reason string
|
||||
cause error
|
||||
key bool
|
||||
}
|
||||
|
||||
// Field function returns field value.
|
||||
func (e GoogleDriveValidationError) Field() string { return e.field }
|
||||
|
||||
// Reason function returns reason value.
|
||||
func (e GoogleDriveValidationError) Reason() string { return e.reason }
|
||||
|
||||
// Cause function returns cause value.
|
||||
func (e GoogleDriveValidationError) Cause() error { return e.cause }
|
||||
|
||||
// Key function returns key value.
|
||||
func (e GoogleDriveValidationError) Key() bool { return e.key }
|
||||
|
||||
// ErrorName returns error name.
|
||||
func (e GoogleDriveValidationError) ErrorName() string { return "GoogleDriveValidationError" }
|
||||
|
||||
// Error satisfies the builtin error interface
|
||||
func (e GoogleDriveValidationError) Error() string {
|
||||
cause := ""
|
||||
if e.cause != nil {
|
||||
cause = fmt.Sprintf(" | caused by: %v", e.cause)
|
||||
}
|
||||
|
||||
key := ""
|
||||
if e.key {
|
||||
key = "key for "
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"invalid %sGoogleDrive.%s: %s%s",
|
||||
key,
|
||||
e.field,
|
||||
e.reason,
|
||||
cause)
|
||||
}
|
||||
|
||||
var _ error = GoogleDriveValidationError{}
|
||||
|
||||
var _ interface {
|
||||
Field() string
|
||||
Reason() string
|
||||
Key() bool
|
||||
Cause() error
|
||||
ErrorName() string
|
||||
} = GoogleDriveValidationError{}
|
||||
|
||||
// Validate checks the field values on GCS with the rules defined in the proto
|
||||
// definition for this message. If any rules are violated, the first error
|
||||
// encountered is returned, or nil if there are no violations.
|
||||
@@ -2393,6 +2282,10 @@ func (m *Teams) validate(all bool) error {
|
||||
|
||||
// no validation rules for Location
|
||||
|
||||
// no validation rules for TeamName
|
||||
|
||||
// no validation rules for TeamId
|
||||
|
||||
if len(errors) > 0 {
|
||||
return TeamsMultiError(errors)
|
||||
}
|
||||
@@ -2828,6 +2721,230 @@ var _ interface {
|
||||
ErrorName() string
|
||||
} = PublicEventMonitoringValidationError{}
|
||||
|
||||
// Validate checks the field values on SharePoint with the rules defined in the
|
||||
// proto definition for this message. If any rules are violated, the first
|
||||
// error encountered is returned, or nil if there are no violations.
|
||||
func (m *SharePoint) Validate() error {
|
||||
return m.validate(false)
|
||||
}
|
||||
|
||||
// ValidateAll checks the field values on SharePoint with the rules defined in
|
||||
// the proto definition for this message. If any rules are violated, the
|
||||
// result is a list of violation errors wrapped in SharePointMultiError, or
|
||||
// nil if none found.
|
||||
func (m *SharePoint) ValidateAll() error {
|
||||
return m.validate(true)
|
||||
}
|
||||
|
||||
func (m *SharePoint) validate(all bool) error {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errors []error
|
||||
|
||||
// no validation rules for Link
|
||||
|
||||
// no validation rules for Timestamp
|
||||
|
||||
// no validation rules for Author
|
||||
|
||||
// no validation rules for Title
|
||||
|
||||
// no validation rules for Views
|
||||
|
||||
// no validation rules for Docid
|
||||
|
||||
// no validation rules for Email
|
||||
|
||||
if len(errors) > 0 {
|
||||
return SharePointMultiError(errors)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SharePointMultiError is an error wrapping multiple validation errors
|
||||
// returned by SharePoint.ValidateAll() if the designated constraints aren't met.
|
||||
type SharePointMultiError []error
|
||||
|
||||
// Error returns a concatenation of all the error messages it wraps.
|
||||
func (m SharePointMultiError) Error() string {
|
||||
var msgs []string
|
||||
for _, err := range m {
|
||||
msgs = append(msgs, err.Error())
|
||||
}
|
||||
return strings.Join(msgs, "; ")
|
||||
}
|
||||
|
||||
// AllErrors returns a list of validation violation errors.
|
||||
func (m SharePointMultiError) AllErrors() []error { return m }
|
||||
|
||||
// SharePointValidationError is the validation error returned by
|
||||
// SharePoint.Validate if the designated constraints aren't met.
|
||||
type SharePointValidationError struct {
|
||||
field string
|
||||
reason string
|
||||
cause error
|
||||
key bool
|
||||
}
|
||||
|
||||
// Field function returns field value.
|
||||
func (e SharePointValidationError) Field() string { return e.field }
|
||||
|
||||
// Reason function returns reason value.
|
||||
func (e SharePointValidationError) Reason() string { return e.reason }
|
||||
|
||||
// Cause function returns cause value.
|
||||
func (e SharePointValidationError) Cause() error { return e.cause }
|
||||
|
||||
// Key function returns key value.
|
||||
func (e SharePointValidationError) Key() bool { return e.key }
|
||||
|
||||
// ErrorName returns error name.
|
||||
func (e SharePointValidationError) ErrorName() string { return "SharePointValidationError" }
|
||||
|
||||
// Error satisfies the builtin error interface
|
||||
func (e SharePointValidationError) Error() string {
|
||||
cause := ""
|
||||
if e.cause != nil {
|
||||
cause = fmt.Sprintf(" | caused by: %v", e.cause)
|
||||
}
|
||||
|
||||
key := ""
|
||||
if e.key {
|
||||
key = "key for "
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"invalid %sSharePoint.%s: %s%s",
|
||||
key,
|
||||
e.field,
|
||||
e.reason,
|
||||
cause)
|
||||
}
|
||||
|
||||
var _ error = SharePointValidationError{}
|
||||
|
||||
var _ interface {
|
||||
Field() string
|
||||
Reason() string
|
||||
Key() bool
|
||||
Cause() error
|
||||
ErrorName() string
|
||||
} = SharePointValidationError{}
|
||||
|
||||
// Validate checks the field values on GoogleDrive with the rules defined in
|
||||
// the proto definition for this message. If any rules are violated, the first
|
||||
// error encountered is returned, or nil if there are no violations.
|
||||
func (m *GoogleDrive) Validate() error {
|
||||
return m.validate(false)
|
||||
}
|
||||
|
||||
// ValidateAll checks the field values on GoogleDrive with the rules defined in
|
||||
// the proto definition for this message. If any rules are violated, the
|
||||
// result is a list of violation errors wrapped in GoogleDriveMultiError, or
|
||||
// nil if none found.
|
||||
func (m *GoogleDrive) ValidateAll() error {
|
||||
return m.validate(true)
|
||||
}
|
||||
|
||||
func (m *GoogleDrive) validate(all bool) error {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errors []error
|
||||
|
||||
// no validation rules for File
|
||||
|
||||
// no validation rules for Link
|
||||
|
||||
// no validation rules for Email
|
||||
|
||||
// no validation rules for Timestamp
|
||||
|
||||
// no validation rules for Shared
|
||||
|
||||
// no validation rules for LastModifiedBy
|
||||
|
||||
if len(errors) > 0 {
|
||||
return GoogleDriveMultiError(errors)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GoogleDriveMultiError is an error wrapping multiple validation errors
|
||||
// returned by GoogleDrive.ValidateAll() if the designated constraints aren't met.
|
||||
type GoogleDriveMultiError []error
|
||||
|
||||
// Error returns a concatenation of all the error messages it wraps.
|
||||
func (m GoogleDriveMultiError) Error() string {
|
||||
var msgs []string
|
||||
for _, err := range m {
|
||||
msgs = append(msgs, err.Error())
|
||||
}
|
||||
return strings.Join(msgs, "; ")
|
||||
}
|
||||
|
||||
// AllErrors returns a list of validation violation errors.
|
||||
func (m GoogleDriveMultiError) AllErrors() []error { return m }
|
||||
|
||||
// GoogleDriveValidationError is the validation error returned by
|
||||
// GoogleDrive.Validate if the designated constraints aren't met.
|
||||
type GoogleDriveValidationError struct {
|
||||
field string
|
||||
reason string
|
||||
cause error
|
||||
key bool
|
||||
}
|
||||
|
||||
// Field function returns field value.
|
||||
func (e GoogleDriveValidationError) Field() string { return e.field }
|
||||
|
||||
// Reason function returns reason value.
|
||||
func (e GoogleDriveValidationError) Reason() string { return e.reason }
|
||||
|
||||
// Cause function returns cause value.
|
||||
func (e GoogleDriveValidationError) Cause() error { return e.cause }
|
||||
|
||||
// Key function returns key value.
|
||||
func (e GoogleDriveValidationError) Key() bool { return e.key }
|
||||
|
||||
// ErrorName returns error name.
|
||||
func (e GoogleDriveValidationError) ErrorName() string { return "GoogleDriveValidationError" }
|
||||
|
||||
// Error satisfies the builtin error interface
|
||||
func (e GoogleDriveValidationError) Error() string {
|
||||
cause := ""
|
||||
if e.cause != nil {
|
||||
cause = fmt.Sprintf(" | caused by: %v", e.cause)
|
||||
}
|
||||
|
||||
key := ""
|
||||
if e.key {
|
||||
key = "key for "
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"invalid %sGoogleDrive.%s: %s%s",
|
||||
key,
|
||||
e.field,
|
||||
e.reason,
|
||||
cause)
|
||||
}
|
||||
|
||||
var _ error = GoogleDriveValidationError{}
|
||||
|
||||
var _ interface {
|
||||
Field() string
|
||||
Reason() string
|
||||
Key() bool
|
||||
Cause() error
|
||||
ErrorName() string
|
||||
} = GoogleDriveValidationError{}
|
||||
|
||||
// Validate checks the field values on MetaData with the rules defined in the
|
||||
// proto definition for this message. If any rules are violated, the first
|
||||
// error encountered is returned, or nil if there are no violations.
|
||||
@@ -3596,6 +3713,68 @@ func (m *MetaData) validate(all bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
case *MetaData_Sharepoint:
|
||||
|
||||
if all {
|
||||
switch v := interface{}(m.GetSharepoint()).(type) {
|
||||
case interface{ ValidateAll() error }:
|
||||
if err := v.ValidateAll(); err != nil {
|
||||
errors = append(errors, MetaDataValidationError{
|
||||
field: "Sharepoint",
|
||||
reason: "embedded message failed validation",
|
||||
cause: err,
|
||||
})
|
||||
}
|
||||
case interface{ Validate() error }:
|
||||
if err := v.Validate(); err != nil {
|
||||
errors = append(errors, MetaDataValidationError{
|
||||
field: "Sharepoint",
|
||||
reason: "embedded message failed validation",
|
||||
cause: err,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if v, ok := interface{}(m.GetSharepoint()).(interface{ Validate() error }); ok {
|
||||
if err := v.Validate(); err != nil {
|
||||
return MetaDataValidationError{
|
||||
field: "Sharepoint",
|
||||
reason: "embedded message failed validation",
|
||||
cause: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case *MetaData_GoogleDrive:
|
||||
|
||||
if all {
|
||||
switch v := interface{}(m.GetGoogleDrive()).(type) {
|
||||
case interface{ ValidateAll() error }:
|
||||
if err := v.ValidateAll(); err != nil {
|
||||
errors = append(errors, MetaDataValidationError{
|
||||
field: "GoogleDrive",
|
||||
reason: "embedded message failed validation",
|
||||
cause: err,
|
||||
})
|
||||
}
|
||||
case interface{ Validate() error }:
|
||||
if err := v.Validate(); err != nil {
|
||||
errors = append(errors, MetaDataValidationError{
|
||||
field: "GoogleDrive",
|
||||
reason: "embedded message failed validation",
|
||||
cause: err,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if v, ok := interface{}(m.GetGoogleDrive()).(interface{ Validate() error }); ok {
|
||||
if err := v.Validate(); err != nil {
|
||||
return MetaDataValidationError{
|
||||
field: "GoogleDrive",
|
||||
reason: "embedded message failed validation",
|
||||
cause: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if len(errors) > 0 {
|
||||
|
||||
+382
-258
@@ -57,6 +57,7 @@ const (
|
||||
SourceType_SOURCE_TYPE_PUBLIC_EVENT_MONITORING SourceType = 26
|
||||
SourceType_SOURCE_TYPE_SLACK_REALTIME SourceType = 27
|
||||
SourceType_SOURCE_TYPE_GOOGLE_DRIVE SourceType = 28
|
||||
SourceType_SOURCE_TYPE_SHAREPOINT SourceType = 29
|
||||
SourceType_SOURCE_TYPE_GCS_UNAUTHED SourceType = 30
|
||||
)
|
||||
|
||||
@@ -92,6 +93,7 @@ var (
|
||||
26: "SOURCE_TYPE_PUBLIC_EVENT_MONITORING",
|
||||
27: "SOURCE_TYPE_SLACK_REALTIME",
|
||||
28: "SOURCE_TYPE_GOOGLE_DRIVE",
|
||||
29: "SOURCE_TYPE_SHAREPOINT",
|
||||
30: "SOURCE_TYPE_GCS_UNAUTHED",
|
||||
}
|
||||
SourceType_value = map[string]int32{
|
||||
@@ -124,6 +126,7 @@ var (
|
||||
"SOURCE_TYPE_PUBLIC_EVENT_MONITORING": 26,
|
||||
"SOURCE_TYPE_SLACK_REALTIME": 27,
|
||||
"SOURCE_TYPE_GOOGLE_DRIVE": 28,
|
||||
"SOURCE_TYPE_SHAREPOINT": 29,
|
||||
"SOURCE_TYPE_GCS_UNAUTHED": 30,
|
||||
}
|
||||
)
|
||||
@@ -1601,8 +1604,9 @@ type JIRA struct {
|
||||
// *JIRA_Unauthenticated
|
||||
// *JIRA_Oauth
|
||||
// *JIRA_Token
|
||||
Credential isJIRA_Credential `protobuf_oneof:"credential"`
|
||||
Projects []string `protobuf:"bytes,5,rep,name=projects,proto3" json:"projects,omitempty"`
|
||||
Credential isJIRA_Credential `protobuf_oneof:"credential"`
|
||||
Projects []string `protobuf:"bytes,5,rep,name=projects,proto3" json:"projects,omitempty"`
|
||||
IgnoreProjects []string `protobuf:"bytes,7,rep,name=ignore_projects,json=ignoreProjects,proto3" json:"ignore_projects,omitempty"`
|
||||
}
|
||||
|
||||
func (x *JIRA) Reset() {
|
||||
@@ -1686,6 +1690,13 @@ func (x *JIRA) GetProjects() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *JIRA) GetIgnoreProjects() []string {
|
||||
if x != nil {
|
||||
return x.IgnoreProjects
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isJIRA_Credential interface {
|
||||
isJIRA_Credential()
|
||||
}
|
||||
@@ -1856,8 +1867,9 @@ type S3 struct {
|
||||
// *S3_Unauthenticated
|
||||
// *S3_CloudEnvironment
|
||||
// *S3_SessionToken
|
||||
Credential isS3_Credential `protobuf_oneof:"credential"`
|
||||
Buckets []string `protobuf:"bytes,3,rep,name=buckets,proto3" json:"buckets,omitempty"`
|
||||
Credential isS3_Credential `protobuf_oneof:"credential"`
|
||||
Buckets []string `protobuf:"bytes,3,rep,name=buckets,proto3" json:"buckets,omitempty"`
|
||||
MaxObjectSize int64 `protobuf:"varint,6,opt,name=max_object_size,json=maxObjectSize,proto3" json:"max_object_size,omitempty"`
|
||||
}
|
||||
|
||||
func (x *S3) Reset() {
|
||||
@@ -1934,6 +1946,13 @@ func (x *S3) GetBuckets() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *S3) GetMaxObjectSize() int64 {
|
||||
if x != nil {
|
||||
return x.MaxObjectSize
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type isS3_Credential interface {
|
||||
isS3_Credential()
|
||||
}
|
||||
@@ -2367,7 +2386,7 @@ type Teams struct {
|
||||
Credential isTeams_Credential `protobuf_oneof:"credential"`
|
||||
Channels []string `protobuf:"bytes,4,rep,name=channels,proto3" json:"channels,omitempty"`
|
||||
IgnoreList []string `protobuf:"bytes,5,rep,name=ignoreList,proto3" json:"ignoreList,omitempty"`
|
||||
TeamId string `protobuf:"bytes,6,opt,name=team_id,json=teamId,proto3" json:"team_id,omitempty"`
|
||||
TeamIds []string `protobuf:"bytes,6,rep,name=team_ids,json=teamIds,proto3" json:"team_ids,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Teams) Reset() {
|
||||
@@ -2451,11 +2470,11 @@ func (x *Teams) GetIgnoreList() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Teams) GetTeamId() string {
|
||||
func (x *Teams) GetTeamIds() []string {
|
||||
if x != nil {
|
||||
return x.TeamId
|
||||
return x.TeamIds
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
type isTeams_Credential interface {
|
||||
@@ -2812,6 +2831,80 @@ type SlackRealtime_Tokens struct {
|
||||
|
||||
func (*SlackRealtime_Tokens) isSlackRealtime_Credential() {}
|
||||
|
||||
type Sharepoint struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Types that are assignable to Credential:
|
||||
// *Sharepoint_Oauth
|
||||
Credential isSharepoint_Credential `protobuf_oneof:"credential"`
|
||||
SiteUrl string `protobuf:"bytes,2,opt,name=site_url,json=siteUrl,proto3" json:"site_url,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Sharepoint) Reset() {
|
||||
*x = Sharepoint{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_sources_proto_msgTypes[27]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Sharepoint) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Sharepoint) ProtoMessage() {}
|
||||
|
||||
func (x *Sharepoint) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_sources_proto_msgTypes[27]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Sharepoint.ProtoReflect.Descriptor instead.
|
||||
func (*Sharepoint) Descriptor() ([]byte, []int) {
|
||||
return file_sources_proto_rawDescGZIP(), []int{27}
|
||||
}
|
||||
|
||||
func (m *Sharepoint) GetCredential() isSharepoint_Credential {
|
||||
if m != nil {
|
||||
return m.Credential
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Sharepoint) GetOauth() *credentialspb.Oauth2 {
|
||||
if x, ok := x.GetCredential().(*Sharepoint_Oauth); ok {
|
||||
return x.Oauth
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Sharepoint) GetSiteUrl() string {
|
||||
if x != nil {
|
||||
return x.SiteUrl
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type isSharepoint_Credential interface {
|
||||
isSharepoint_Credential()
|
||||
}
|
||||
|
||||
type Sharepoint_Oauth struct {
|
||||
Oauth *credentialspb.Oauth2 `protobuf:"bytes,1,opt,name=oauth,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Sharepoint_Oauth) isSharepoint_Credential() {}
|
||||
|
||||
var File_sources_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_sources_proto_rawDesc = []byte{
|
||||
@@ -3034,7 +3127,7 @@ var file_sources_proto_rawDesc = []byte{
|
||||
0x44, 0x72, 0x69, 0x76, 0x65, 0x12, 0x25, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
|
||||
0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c,
|
||||
0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x0c, 0x0a, 0x0a,
|
||||
0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x9e, 0x02, 0x0a, 0x04, 0x4a,
|
||||
0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0xc7, 0x02, 0x0a, 0x04, 0x4a,
|
||||
0x49, 0x52, 0x41, 0x12, 0x24, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x90, 0x01, 0x01, 0x52,
|
||||
0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0a, 0x62, 0x61, 0x73,
|
||||
@@ -3051,200 +3144,214 @@ var file_sources_proto_rawDesc = []byte{
|
||||
0x48, 0x00, 0x52, 0x05, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x05, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x0c, 0x0a,
|
||||
0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x73, 0x0a, 0x19, 0x4e,
|
||||
0x50, 0x4d, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65,
|
||||
0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x0f, 0x75, 0x6e, 0x61, 0x75,
|
||||
0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e,
|
||||
0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x48,
|
||||
0x00, 0x52, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x65, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,
|
||||
0x22, 0x74, 0x0a, 0x1a, 0x50, 0x79, 0x50, 0x49, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x48,
|
||||
0x0a, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x63, 0x61, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0xc8, 0x02, 0x0a, 0x02, 0x53, 0x33, 0x12, 0x37, 0x0a,
|
||||
0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e,
|
||||
0x4b, 0x65, 0x79, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x48, 0x00, 0x52, 0x09, 0x61, 0x63, 0x63,
|
||||
0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x48, 0x0a, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1c, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x55, 0x6e,
|
||||
0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52,
|
||||
0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x27, 0x0a,
|
||||
0x0f, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73,
|
||||
0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x50, 0x72,
|
||||
0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x61, 0x6c, 0x22, 0x73, 0x0a, 0x19, 0x4e, 0x50, 0x4d, 0x55, 0x6e, 0x61, 0x75, 0x74,
|
||||
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67,
|
||||
0x65, 0x12, 0x48, 0x0a, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63,
|
||||
0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x72, 0x65,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0f, 0x75, 0x6e, 0x61, 0x75,
|
||||
0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x63,
|
||||
0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x74, 0x0a, 0x1a, 0x50, 0x79, 0x50,
|
||||
0x49, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64,
|
||||
0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74,
|
||||
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1c, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x55,
|
||||
0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x48, 0x00,
|
||||
0x52, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65,
|
||||
0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22,
|
||||
0xf0, 0x02, 0x0a, 0x02, 0x53, 0x33, 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73,
|
||||
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x65,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x63, 0x72,
|
||||
0x65, 0x74, 0x48, 0x00, 0x52, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12,
|
||||
0x48, 0x0a, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x11, 0x63, 0x6c, 0x6f,
|
||||
0x75, 0x64, 0x5f, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
|
||||
0x6c, 0x73, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x45, 0x6e, 0x76, 0x69,
|
||||
0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x49, 0x0a, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22,
|
||||
0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x41, 0x57, 0x53,
|
||||
0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x63, 0x72,
|
||||
0x65, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f,
|
||||
0x6d, 0x61, 0x78, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x53, 0x69, 0x7a, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x61, 0x6c, 0x22, 0xc3, 0x01, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x24, 0x0a, 0x08,
|
||||
0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08,
|
||||
0xfa, 0x42, 0x05, 0x72, 0x03, 0x90, 0x01, 0x01, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69,
|
||||
0x6e, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x32, 0x0a, 0x06, 0x74, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x72, 0x65,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1a,
|
||||
0x0a, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09,
|
||||
0x52, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x67,
|
||||
0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72,
|
||||
0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x06, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74,
|
||||
0x22, 0x31, 0x0a, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x65, 0x12, 0x16, 0x0a,
|
||||
0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05,
|
||||
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x61, 0x6c, 0x22, 0xdb, 0x01, 0x0a, 0x06, 0x47, 0x65, 0x72, 0x72, 0x69, 0x74, 0x12, 0x24,
|
||||
0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x90, 0x01, 0x01, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70,
|
||||
0x6f, 0x69, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0a, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x61, 0x75,
|
||||
0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68,
|
||||
0x48, 0x00, 0x52, 0x09, 0x62, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x12, 0x48, 0x0a,
|
||||
0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64,
|
||||
0x12, 0x4c, 0x0a, 0x11, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f,
|
||||
0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x72,
|
||||
0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x45,
|
||||
0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x63, 0x6c,
|
||||
0x6f, 0x75, 0x64, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x49,
|
||||
0x0a, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x61, 0x6c, 0x73, 0x2e, 0x41, 0x57, 0x53, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x65, 0x73,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x63,
|
||||
0x6b, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x63, 0x6b,
|
||||
0x65, 0x74, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
|
||||
0x6c, 0x22, 0xc3, 0x01, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x24, 0x0a, 0x08, 0x65,
|
||||
0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa,
|
||||
0x42, 0x05, 0x72, 0x03, 0x90, 0x01, 0x01, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e,
|
||||
0x74, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x32, 0x0a, 0x06, 0x74, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x72, 0x65, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1a, 0x0a,
|
||||
0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x67, 0x6e,
|
||||
0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69,
|
||||
0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x06, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x22,
|
||||
0x31, 0x0a, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x05,
|
||||
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x74,
|
||||
0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x61, 0x6c, 0x22, 0xdb, 0x01, 0x0a, 0x06, 0x47, 0x65, 0x72, 0x72, 0x69, 0x74, 0x12, 0x24, 0x0a,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x61, 0x6c, 0x73, 0x2e, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63,
|
||||
0x61, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
|
||||
0x6c, 0x22, 0xa5, 0x01, 0x0a, 0x07, 0x4a, 0x65, 0x6e, 0x6b, 0x69, 0x6e, 0x73, 0x12, 0x24, 0x0a,
|
||||
0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42,
|
||||
0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x90, 0x01, 0x01, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f,
|
||||
0x69, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0a, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x61, 0x75, 0x74,
|
||||
0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x48,
|
||||
0x00, 0x52, 0x09, 0x62, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x12, 0x48, 0x0a, 0x0f,
|
||||
0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x61, 0x6c, 0x73, 0x2e, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61,
|
||||
0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,
|
||||
0x22, 0xa5, 0x01, 0x0a, 0x07, 0x4a, 0x65, 0x6e, 0x6b, 0x69, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x08,
|
||||
0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08,
|
||||
0xfa, 0x42, 0x05, 0x72, 0x03, 0x90, 0x01, 0x01, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69,
|
||||
0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0a, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x61, 0x75, 0x74, 0x68,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x61, 0x6c, 0x73, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x48, 0x00,
|
||||
0x52, 0x09, 0x62, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x12, 0x2d, 0x0a, 0x06, 0x68,
|
||||
0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x72,
|
||||
0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
|
||||
0x48, 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72,
|
||||
0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x9d, 0x02, 0x0a, 0x05, 0x54, 0x65, 0x61,
|
||||
0x6d, 0x73, 0x12, 0x24, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x90, 0x01, 0x01, 0x52, 0x08,
|
||||
0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
|
||||
0x12, 0x46, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65,
|
||||
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x6f, 0x61, 0x75, 0x74,
|
||||
0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x48, 0x00, 0x52, 0x05,
|
||||
0x6f, 0x61, 0x75, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
|
||||
0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
|
||||
0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x18,
|
||||
0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72,
|
||||
0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0xc3, 0x01, 0x0a, 0x0b, 0x41, 0x72, 0x74,
|
||||
0x69, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x24, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70,
|
||||
0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72,
|
||||
0x03, 0x90, 0x01, 0x01, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x37,
|
||||
0x0a, 0x0a, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
|
||||
0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x48, 0x00, 0x52, 0x09, 0x62, 0x61,
|
||||
0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73,
|
||||
0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,
|
||||
0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x0a, 0x0c,
|
||||
0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73,
|
||||
0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x94,
|
||||
0x01, 0x0a, 0x06, 0x53, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41,
|
||||
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x69,
|
||||
0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x74,
|
||||
0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x6c,
|
||||
0x73, 0x43, 0x65, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66,
|
||||
0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0xd6, 0x01, 0x0a, 0x15, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
|
||||
0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x12,
|
||||
0x48, 0x0a, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d,
|
||||
0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69,
|
||||
0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x44, 0x65, 0x70, 0x74, 0x68, 0x12, 0x30,
|
||||
0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65,
|
||||
0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x51,
|
||||
0x0a, 0x0d, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x12,
|
||||
0x32, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x18, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x53, 0x6c,
|
||||
0x61, 0x63, 0x6b, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x06, 0x74, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
|
||||
0x6c, 0x2a, 0xd5, 0x06, 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65,
|
||||
0x12, 0x1d, 0x0a, 0x19, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
|
||||
0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x10, 0x00, 0x12,
|
||||
0x19, 0x0a, 0x15, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42,
|
||||
0x49, 0x54, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x4f,
|
||||
0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x4c, 0x45,
|
||||
0x43, 0x49, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54,
|
||||
0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x4c, 0x55, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x03,
|
||||
0x12, 0x20, 0x0a, 0x1c, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
|
||||
0x44, 0x4f, 0x43, 0x4b, 0x45, 0x52, 0x48, 0x55, 0x42, 0x5f, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x53,
|
||||
0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50,
|
||||
0x45, 0x5f, 0x45, 0x43, 0x52, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43,
|
||||
0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x43, 0x53, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12,
|
||||
0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x49, 0x54, 0x48,
|
||||
0x55, 0x42, 0x10, 0x07, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54,
|
||||
0x59, 0x50, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x47, 0x49, 0x54, 0x10, 0x08,
|
||||
0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
|
||||
0x47, 0x49, 0x54, 0x4c, 0x41, 0x42, 0x10, 0x09, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x4f, 0x55, 0x52,
|
||||
0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a, 0x49, 0x52, 0x41, 0x10, 0x0a, 0x12, 0x24,
|
||||
0x0a, 0x20, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x50,
|
||||
0x4d, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x44, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47,
|
||||
0x45, 0x53, 0x10, 0x0b, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54,
|
||||
0x59, 0x50, 0x45, 0x5f, 0x50, 0x59, 0x50, 0x49, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x44,
|
||||
0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0c, 0x12, 0x12, 0x0a, 0x0e, 0x53,
|
||||
0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x33, 0x10, 0x0d, 0x12,
|
||||
0x15, 0x0a, 0x11, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53,
|
||||
0x4c, 0x41, 0x43, 0x4b, 0x10, 0x0e, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45,
|
||||
0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d,
|
||||
0x10, 0x0f, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50,
|
||||
0x45, 0x5f, 0x47, 0x49, 0x54, 0x10, 0x10, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x4f, 0x55, 0x52, 0x43,
|
||||
0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x10, 0x11, 0x12, 0x1b, 0x0a,
|
||||
0x17, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x33, 0x5f,
|
||||
0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x44, 0x10, 0x12, 0x12, 0x2a, 0x0a, 0x26, 0x53, 0x4f,
|
||||
0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42,
|
||||
0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e, 0x54, 0x49, 0x43, 0x41, 0x54, 0x45, 0x44,
|
||||
0x5f, 0x4f, 0x52, 0x47, 0x10, 0x13, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45,
|
||||
0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x4b, 0x49, 0x54, 0x45, 0x10,
|
||||
0x14, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45,
|
||||
0x5f, 0x47, 0x45, 0x52, 0x52, 0x49, 0x54, 0x10, 0x15, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x4f, 0x55,
|
||||
0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a, 0x45, 0x4e, 0x4b, 0x49, 0x4e, 0x53,
|
||||
0x10, 0x16, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50,
|
||||
0x45, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x53, 0x10, 0x17, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x4f, 0x55,
|
||||
0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a, 0x46, 0x52, 0x4f, 0x47, 0x5f, 0x41,
|
||||
0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x10, 0x18, 0x12, 0x16, 0x0a, 0x12,
|
||||
0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x59, 0x53, 0x4c,
|
||||
0x4f, 0x47, 0x10, 0x19, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54,
|
||||
0x59, 0x50, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54,
|
||||
0x5f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x1a, 0x12, 0x1e, 0x0a,
|
||||
0x1a, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4c, 0x41,
|
||||
0x43, 0x4b, 0x5f, 0x52, 0x45, 0x41, 0x4c, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x1b, 0x12, 0x1c, 0x0a,
|
||||
0x18, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x4f, 0x4f,
|
||||
0x47, 0x4c, 0x45, 0x5f, 0x44, 0x52, 0x49, 0x56, 0x45, 0x10, 0x1c, 0x12, 0x1c, 0x0a, 0x18, 0x53,
|
||||
0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x43, 0x53, 0x5f, 0x55,
|
||||
0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x44, 0x10, 0x1e, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66, 0x6c, 0x65, 0x73,
|
||||
0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66, 0x6c, 0x65, 0x68,
|
||||
0x6f, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x73, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x00, 0x52, 0x09, 0x62, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x12, 0x2d, 0x0a, 0x06,
|
||||
0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63,
|
||||
0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65,
|
||||
0x72, 0x48, 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x0c, 0x0a, 0x0a, 0x63,
|
||||
0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x9f, 0x02, 0x0a, 0x05, 0x54, 0x65,
|
||||
0x61, 0x6d, 0x73, 0x12, 0x24, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x90, 0x01, 0x01, 0x52,
|
||||
0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x12, 0x46, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x6f, 0x61, 0x75,
|
||||
0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x48, 0x00, 0x52,
|
||||
0x05, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
|
||||
0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
|
||||
0x6c, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x06,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x73, 0x42, 0x0c, 0x0a,
|
||||
0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0xc3, 0x01, 0x0a, 0x0b,
|
||||
0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x24, 0x0a, 0x08, 0x65,
|
||||
0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa,
|
||||
0x42, 0x05, 0x72, 0x03, 0x90, 0x01, 0x01, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e,
|
||||
0x74, 0x12, 0x37, 0x0a, 0x0a, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x61, 0x6c, 0x73, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x48, 0x00, 0x52,
|
||||
0x09, 0x62, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0c, 0x61, 0x63,
|
||||
0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x48, 0x00, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
|
||||
0x22, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18,
|
||||
0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72,
|
||||
0x69, 0x65, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
|
||||
0x6c, 0x22, 0x94, 0x01, 0x0a, 0x06, 0x53, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x69, 0x73, 0x74,
|
||||
0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0d, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6c, 0x73, 0x4b,
|
||||
0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6c, 0x73, 0x4b, 0x65, 0x79,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0xd6, 0x01, 0x0a, 0x15, 0x50, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x12, 0x48, 0x0a, 0x0f, 0x75, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x72,
|
||||
0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0f, 0x75, 0x6e, 0x61,
|
||||
0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f,
|
||||
0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x65, 0x70, 0x74,
|
||||
0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x44, 0x65, 0x70, 0x74,
|
||||
0x68, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69,
|
||||
0x6e, 0x63, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
|
||||
0x6c, 0x22, 0x51, 0x0a, 0x0d, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
|
||||
0x2e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x06,
|
||||
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x61, 0x6c, 0x22, 0x62, 0x0a, 0x0a, 0x53, 0x68, 0x61, 0x72, 0x65, 0x70, 0x6f, 0x69,
|
||||
0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x13, 0x2e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e,
|
||||
0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x48, 0x00, 0x52, 0x05, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x12,
|
||||
0x19, 0x0a, 0x08, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x73, 0x69, 0x74, 0x65, 0x55, 0x72, 0x6c, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72,
|
||||
0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2a, 0xf1, 0x06, 0x0a, 0x0a, 0x53, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x4f, 0x55, 0x52, 0x43,
|
||||
0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x4f,
|
||||
0x52, 0x41, 0x47, 0x45, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45,
|
||||
0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x49, 0x54, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x10,
|
||||
0x01, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45,
|
||||
0x5f, 0x43, 0x49, 0x52, 0x43, 0x4c, 0x45, 0x43, 0x49, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x53,
|
||||
0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x4c,
|
||||
0x55, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x03, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x4f, 0x55, 0x52, 0x43,
|
||||
0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x4b, 0x45, 0x52, 0x48, 0x55, 0x42,
|
||||
0x5f, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x53, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55,
|
||||
0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x43, 0x52, 0x10, 0x05, 0x12, 0x13,
|
||||
0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x43,
|
||||
0x53, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59,
|
||||
0x50, 0x45, 0x5f, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x10, 0x07, 0x12, 0x1a, 0x0a, 0x16, 0x53,
|
||||
0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49,
|
||||
0x43, 0x5f, 0x47, 0x49, 0x54, 0x10, 0x08, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43,
|
||||
0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x49, 0x54, 0x4c, 0x41, 0x42, 0x10, 0x09, 0x12,
|
||||
0x14, 0x0a, 0x10, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a,
|
||||
0x49, 0x52, 0x41, 0x10, 0x0a, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f,
|
||||
0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x50, 0x4d, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x44,
|
||||
0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0b, 0x12, 0x25, 0x0a, 0x21, 0x53,
|
||||
0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x59, 0x50, 0x49, 0x5f,
|
||||
0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x44, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53,
|
||||
0x10, 0x0c, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50,
|
||||
0x45, 0x5f, 0x53, 0x33, 0x10, 0x0d, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45,
|
||||
0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x43, 0x4b, 0x10, 0x0e, 0x12, 0x1a, 0x0a,
|
||||
0x16, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c,
|
||||
0x45, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x10, 0x0f, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55,
|
||||
0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x49, 0x54, 0x10, 0x10, 0x12, 0x14,
|
||||
0x0a, 0x10, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x45,
|
||||
0x53, 0x54, 0x10, 0x11, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54,
|
||||
0x59, 0x50, 0x45, 0x5f, 0x53, 0x33, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x44, 0x10,
|
||||
0x12, 0x12, 0x2a, 0x0a, 0x26, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45,
|
||||
0x5f, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e,
|
||||
0x54, 0x49, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4f, 0x52, 0x47, 0x10, 0x13, 0x12, 0x19, 0x0a,
|
||||
0x15, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x55, 0x49,
|
||||
0x4c, 0x44, 0x4b, 0x49, 0x54, 0x45, 0x10, 0x14, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52,
|
||||
0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x45, 0x52, 0x52, 0x49, 0x54, 0x10, 0x15,
|
||||
0x12, 0x17, 0x0a, 0x13, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
|
||||
0x4a, 0x45, 0x4e, 0x4b, 0x49, 0x4e, 0x53, 0x10, 0x16, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x4f, 0x55,
|
||||
0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x53, 0x10, 0x17,
|
||||
0x12, 0x21, 0x0a, 0x1d, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
|
||||
0x4a, 0x46, 0x52, 0x4f, 0x47, 0x5f, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x4f, 0x52,
|
||||
0x59, 0x10, 0x18, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59,
|
||||
0x50, 0x45, 0x5f, 0x53, 0x59, 0x53, 0x4c, 0x4f, 0x47, 0x10, 0x19, 0x12, 0x27, 0x0a, 0x23, 0x53,
|
||||
0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49,
|
||||
0x43, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x49,
|
||||
0x4e, 0x47, 0x10, 0x1a, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54,
|
||||
0x59, 0x50, 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x43, 0x4b, 0x5f, 0x52, 0x45, 0x41, 0x4c, 0x54, 0x49,
|
||||
0x4d, 0x45, 0x10, 0x1b, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54,
|
||||
0x59, 0x50, 0x45, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x44, 0x52, 0x49, 0x56, 0x45,
|
||||
0x10, 0x1c, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50,
|
||||
0x45, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x1d, 0x12, 0x1c,
|
||||
0x0a, 0x18, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x43,
|
||||
0x53, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x44, 0x10, 0x1e, 0x42, 0x3b, 0x5a, 0x39,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66,
|
||||
0x6c, 0x65, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66,
|
||||
0x6c, 0x65, 0x68, 0x6f, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -3260,7 +3367,7 @@ func file_sources_proto_rawDescGZIP() []byte {
|
||||
}
|
||||
|
||||
var file_sources_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||
var file_sources_proto_msgTypes = make([]protoimpl.MessageInfo, 27)
|
||||
var file_sources_proto_msgTypes = make([]protoimpl.MessageInfo, 28)
|
||||
var file_sources_proto_goTypes = []interface{}{
|
||||
(SourceType)(0), // 0: sources.SourceType
|
||||
(Confluence_GetAllSpacesScope)(0), // 1: sources.Confluence.GetAllSpacesScope
|
||||
@@ -3291,68 +3398,70 @@ var file_sources_proto_goTypes = []interface{}{
|
||||
(*Syslog)(nil), // 26: sources.Syslog
|
||||
(*PublicEventMonitoring)(nil), // 27: sources.PublicEventMonitoring
|
||||
(*SlackRealtime)(nil), // 28: sources.SlackRealtime
|
||||
(*durationpb.Duration)(nil), // 29: google.protobuf.Duration
|
||||
(*anypb.Any)(nil), // 30: google.protobuf.Any
|
||||
(*credentialspb.BasicAuth)(nil), // 31: credentials.BasicAuth
|
||||
(*credentialspb.Unauthenticated)(nil), // 32: credentials.Unauthenticated
|
||||
(*credentialspb.Oauth2)(nil), // 33: credentials.Oauth2
|
||||
(*credentialspb.KeySecret)(nil), // 34: credentials.KeySecret
|
||||
(*credentialspb.CloudEnvironment)(nil), // 35: credentials.CloudEnvironment
|
||||
(*credentialspb.SSHAuth)(nil), // 36: credentials.SSHAuth
|
||||
(*credentialspb.GitHubApp)(nil), // 37: credentials.GitHubApp
|
||||
(*credentialspb.AWSSessionTokenSecret)(nil), // 38: credentials.AWSSessionTokenSecret
|
||||
(*credentialspb.SlackTokens)(nil), // 39: credentials.SlackTokens
|
||||
(*credentialspb.Header)(nil), // 40: credentials.Header
|
||||
(*credentialspb.ClientCredentials)(nil), // 41: credentials.ClientCredentials
|
||||
(*timestamppb.Timestamp)(nil), // 42: google.protobuf.Timestamp
|
||||
(*Sharepoint)(nil), // 29: sources.Sharepoint
|
||||
(*durationpb.Duration)(nil), // 30: google.protobuf.Duration
|
||||
(*anypb.Any)(nil), // 31: google.protobuf.Any
|
||||
(*credentialspb.BasicAuth)(nil), // 32: credentials.BasicAuth
|
||||
(*credentialspb.Unauthenticated)(nil), // 33: credentials.Unauthenticated
|
||||
(*credentialspb.Oauth2)(nil), // 34: credentials.Oauth2
|
||||
(*credentialspb.KeySecret)(nil), // 35: credentials.KeySecret
|
||||
(*credentialspb.CloudEnvironment)(nil), // 36: credentials.CloudEnvironment
|
||||
(*credentialspb.SSHAuth)(nil), // 37: credentials.SSHAuth
|
||||
(*credentialspb.GitHubApp)(nil), // 38: credentials.GitHubApp
|
||||
(*credentialspb.AWSSessionTokenSecret)(nil), // 39: credentials.AWSSessionTokenSecret
|
||||
(*credentialspb.SlackTokens)(nil), // 40: credentials.SlackTokens
|
||||
(*credentialspb.Header)(nil), // 41: credentials.Header
|
||||
(*credentialspb.ClientCredentials)(nil), // 42: credentials.ClientCredentials
|
||||
(*timestamppb.Timestamp)(nil), // 43: google.protobuf.Timestamp
|
||||
}
|
||||
var file_sources_proto_depIdxs = []int32{
|
||||
29, // 0: sources.LocalSource.scan_interval:type_name -> google.protobuf.Duration
|
||||
30, // 1: sources.LocalSource.connection:type_name -> google.protobuf.Any
|
||||
31, // 2: sources.AzureStorage.basic_auth:type_name -> credentials.BasicAuth
|
||||
32, // 3: sources.AzureStorage.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
33, // 4: sources.Bitbucket.oauth:type_name -> credentials.Oauth2
|
||||
31, // 5: sources.Bitbucket.basic_auth:type_name -> credentials.BasicAuth
|
||||
32, // 6: sources.Confluence.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
31, // 7: sources.Confluence.basic_auth:type_name -> credentials.BasicAuth
|
||||
30, // 0: sources.LocalSource.scan_interval:type_name -> google.protobuf.Duration
|
||||
31, // 1: sources.LocalSource.connection:type_name -> google.protobuf.Any
|
||||
32, // 2: sources.AzureStorage.basic_auth:type_name -> credentials.BasicAuth
|
||||
33, // 3: sources.AzureStorage.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
34, // 4: sources.Bitbucket.oauth:type_name -> credentials.Oauth2
|
||||
32, // 5: sources.Bitbucket.basic_auth:type_name -> credentials.BasicAuth
|
||||
33, // 6: sources.Confluence.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
32, // 7: sources.Confluence.basic_auth:type_name -> credentials.BasicAuth
|
||||
1, // 8: sources.Confluence.spaces_scope:type_name -> sources.Confluence.GetAllSpacesScope
|
||||
32, // 9: sources.DockerHub.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
34, // 10: sources.ECR.access_key:type_name -> credentials.KeySecret
|
||||
32, // 11: sources.GCS.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
35, // 12: sources.GCS.adc:type_name -> credentials.CloudEnvironment
|
||||
33, // 13: sources.GCS.oauth:type_name -> credentials.Oauth2
|
||||
31, // 14: sources.Git.basic_auth:type_name -> credentials.BasicAuth
|
||||
32, // 15: sources.Git.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
36, // 16: sources.Git.ssh_auth:type_name -> credentials.SSHAuth
|
||||
33, // 17: sources.GitLab.oauth:type_name -> credentials.Oauth2
|
||||
31, // 18: sources.GitLab.basic_auth:type_name -> credentials.BasicAuth
|
||||
37, // 19: sources.GitHub.github_app:type_name -> credentials.GitHubApp
|
||||
32, // 20: sources.GitHub.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
31, // 21: sources.JIRA.basic_auth:type_name -> credentials.BasicAuth
|
||||
32, // 22: sources.JIRA.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
33, // 23: sources.JIRA.oauth:type_name -> credentials.Oauth2
|
||||
32, // 24: sources.NPMUnauthenticatedPackage.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
32, // 25: sources.PyPIUnauthenticatedPackage.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
34, // 26: sources.S3.access_key:type_name -> credentials.KeySecret
|
||||
32, // 27: sources.S3.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
35, // 28: sources.S3.cloud_environment:type_name -> credentials.CloudEnvironment
|
||||
38, // 29: sources.S3.session_token:type_name -> credentials.AWSSessionTokenSecret
|
||||
39, // 30: sources.Slack.tokens:type_name -> credentials.SlackTokens
|
||||
31, // 31: sources.Gerrit.basic_auth:type_name -> credentials.BasicAuth
|
||||
32, // 32: sources.Gerrit.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
31, // 33: sources.Jenkins.basic_auth:type_name -> credentials.BasicAuth
|
||||
40, // 34: sources.Jenkins.header:type_name -> credentials.Header
|
||||
41, // 35: sources.Teams.authenticated:type_name -> credentials.ClientCredentials
|
||||
33, // 36: sources.Teams.oauth:type_name -> credentials.Oauth2
|
||||
31, // 37: sources.Artifactory.basic_auth:type_name -> credentials.BasicAuth
|
||||
32, // 38: sources.PublicEventMonitoring.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
42, // 39: sources.PublicEventMonitoring.since:type_name -> google.protobuf.Timestamp
|
||||
39, // 40: sources.SlackRealtime.tokens:type_name -> credentials.SlackTokens
|
||||
41, // [41:41] is the sub-list for method output_type
|
||||
41, // [41:41] is the sub-list for method input_type
|
||||
41, // [41:41] is the sub-list for extension type_name
|
||||
41, // [41:41] is the sub-list for extension extendee
|
||||
0, // [0:41] is the sub-list for field type_name
|
||||
33, // 9: sources.DockerHub.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
35, // 10: sources.ECR.access_key:type_name -> credentials.KeySecret
|
||||
33, // 11: sources.GCS.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
36, // 12: sources.GCS.adc:type_name -> credentials.CloudEnvironment
|
||||
34, // 13: sources.GCS.oauth:type_name -> credentials.Oauth2
|
||||
32, // 14: sources.Git.basic_auth:type_name -> credentials.BasicAuth
|
||||
33, // 15: sources.Git.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
37, // 16: sources.Git.ssh_auth:type_name -> credentials.SSHAuth
|
||||
34, // 17: sources.GitLab.oauth:type_name -> credentials.Oauth2
|
||||
32, // 18: sources.GitLab.basic_auth:type_name -> credentials.BasicAuth
|
||||
38, // 19: sources.GitHub.github_app:type_name -> credentials.GitHubApp
|
||||
33, // 20: sources.GitHub.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
32, // 21: sources.JIRA.basic_auth:type_name -> credentials.BasicAuth
|
||||
33, // 22: sources.JIRA.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
34, // 23: sources.JIRA.oauth:type_name -> credentials.Oauth2
|
||||
33, // 24: sources.NPMUnauthenticatedPackage.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
33, // 25: sources.PyPIUnauthenticatedPackage.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
35, // 26: sources.S3.access_key:type_name -> credentials.KeySecret
|
||||
33, // 27: sources.S3.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
36, // 28: sources.S3.cloud_environment:type_name -> credentials.CloudEnvironment
|
||||
39, // 29: sources.S3.session_token:type_name -> credentials.AWSSessionTokenSecret
|
||||
40, // 30: sources.Slack.tokens:type_name -> credentials.SlackTokens
|
||||
32, // 31: sources.Gerrit.basic_auth:type_name -> credentials.BasicAuth
|
||||
33, // 32: sources.Gerrit.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
32, // 33: sources.Jenkins.basic_auth:type_name -> credentials.BasicAuth
|
||||
41, // 34: sources.Jenkins.header:type_name -> credentials.Header
|
||||
42, // 35: sources.Teams.authenticated:type_name -> credentials.ClientCredentials
|
||||
34, // 36: sources.Teams.oauth:type_name -> credentials.Oauth2
|
||||
32, // 37: sources.Artifactory.basic_auth:type_name -> credentials.BasicAuth
|
||||
33, // 38: sources.PublicEventMonitoring.unauthenticated:type_name -> credentials.Unauthenticated
|
||||
43, // 39: sources.PublicEventMonitoring.since:type_name -> google.protobuf.Timestamp
|
||||
40, // 40: sources.SlackRealtime.tokens:type_name -> credentials.SlackTokens
|
||||
34, // 41: sources.Sharepoint.oauth:type_name -> credentials.Oauth2
|
||||
42, // [42:42] is the sub-list for method output_type
|
||||
42, // [42:42] is the sub-list for method input_type
|
||||
42, // [42:42] is the sub-list for extension type_name
|
||||
42, // [42:42] is the sub-list for extension extendee
|
||||
0, // [0:42] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_sources_proto_init() }
|
||||
@@ -3685,6 +3794,18 @@ func file_sources_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_sources_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Sharepoint); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_sources_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
(*AzureStorage_ConnectionString)(nil),
|
||||
@@ -3785,13 +3906,16 @@ func file_sources_proto_init() {
|
||||
file_sources_proto_msgTypes[26].OneofWrappers = []interface{}{
|
||||
(*SlackRealtime_Tokens)(nil),
|
||||
}
|
||||
file_sources_proto_msgTypes[27].OneofWrappers = []interface{}{
|
||||
(*Sharepoint_Oauth)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_sources_proto_rawDesc,
|
||||
NumEnums: 2,
|
||||
NumMessages: 27,
|
||||
NumMessages: 28,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -2601,6 +2601,8 @@ func (m *S3) validate(all bool) error {
|
||||
|
||||
var errors []error
|
||||
|
||||
// no validation rules for MaxObjectSize
|
||||
|
||||
switch m.Credential.(type) {
|
||||
|
||||
case *S3_AccessKey:
|
||||
@@ -3543,8 +3545,6 @@ func (m *Teams) validate(all bool) error {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
||||
// no validation rules for TeamId
|
||||
|
||||
switch m.Credential.(type) {
|
||||
|
||||
case *Teams_Token:
|
||||
@@ -4252,3 +4252,139 @@ var _ interface {
|
||||
Cause() error
|
||||
ErrorName() string
|
||||
} = SlackRealtimeValidationError{}
|
||||
|
||||
// Validate checks the field values on Sharepoint with the rules defined in the
|
||||
// proto definition for this message. If any rules are violated, the first
|
||||
// error encountered is returned, or nil if there are no violations.
|
||||
func (m *Sharepoint) Validate() error {
|
||||
return m.validate(false)
|
||||
}
|
||||
|
||||
// ValidateAll checks the field values on Sharepoint with the rules defined in
|
||||
// the proto definition for this message. If any rules are violated, the
|
||||
// result is a list of violation errors wrapped in SharepointMultiError, or
|
||||
// nil if none found.
|
||||
func (m *Sharepoint) ValidateAll() error {
|
||||
return m.validate(true)
|
||||
}
|
||||
|
||||
func (m *Sharepoint) validate(all bool) error {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errors []error
|
||||
|
||||
// no validation rules for SiteUrl
|
||||
|
||||
switch m.Credential.(type) {
|
||||
|
||||
case *Sharepoint_Oauth:
|
||||
|
||||
if all {
|
||||
switch v := interface{}(m.GetOauth()).(type) {
|
||||
case interface{ ValidateAll() error }:
|
||||
if err := v.ValidateAll(); err != nil {
|
||||
errors = append(errors, SharepointValidationError{
|
||||
field: "Oauth",
|
||||
reason: "embedded message failed validation",
|
||||
cause: err,
|
||||
})
|
||||
}
|
||||
case interface{ Validate() error }:
|
||||
if err := v.Validate(); err != nil {
|
||||
errors = append(errors, SharepointValidationError{
|
||||
field: "Oauth",
|
||||
reason: "embedded message failed validation",
|
||||
cause: err,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if v, ok := interface{}(m.GetOauth()).(interface{ Validate() error }); ok {
|
||||
if err := v.Validate(); err != nil {
|
||||
return SharepointValidationError{
|
||||
field: "Oauth",
|
||||
reason: "embedded message failed validation",
|
||||
cause: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if len(errors) > 0 {
|
||||
return SharepointMultiError(errors)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SharepointMultiError is an error wrapping multiple validation errors
|
||||
// returned by Sharepoint.ValidateAll() if the designated constraints aren't met.
|
||||
type SharepointMultiError []error
|
||||
|
||||
// Error returns a concatenation of all the error messages it wraps.
|
||||
func (m SharepointMultiError) Error() string {
|
||||
var msgs []string
|
||||
for _, err := range m {
|
||||
msgs = append(msgs, err.Error())
|
||||
}
|
||||
return strings.Join(msgs, "; ")
|
||||
}
|
||||
|
||||
// AllErrors returns a list of validation violation errors.
|
||||
func (m SharepointMultiError) AllErrors() []error { return m }
|
||||
|
||||
// SharepointValidationError is the validation error returned by
|
||||
// Sharepoint.Validate if the designated constraints aren't met.
|
||||
type SharepointValidationError struct {
|
||||
field string
|
||||
reason string
|
||||
cause error
|
||||
key bool
|
||||
}
|
||||
|
||||
// Field function returns field value.
|
||||
func (e SharepointValidationError) Field() string { return e.field }
|
||||
|
||||
// Reason function returns reason value.
|
||||
func (e SharepointValidationError) Reason() string { return e.reason }
|
||||
|
||||
// Cause function returns cause value.
|
||||
func (e SharepointValidationError) Cause() error { return e.cause }
|
||||
|
||||
// Key function returns key value.
|
||||
func (e SharepointValidationError) Key() bool { return e.key }
|
||||
|
||||
// ErrorName returns error name.
|
||||
func (e SharepointValidationError) ErrorName() string { return "SharepointValidationError" }
|
||||
|
||||
// Error satisfies the builtin error interface
|
||||
func (e SharepointValidationError) Error() string {
|
||||
cause := ""
|
||||
if e.cause != nil {
|
||||
cause = fmt.Sprintf(" | caused by: %v", e.cause)
|
||||
}
|
||||
|
||||
key := ""
|
||||
if e.key {
|
||||
key = "key for "
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"invalid %sSharepoint.%s: %s%s",
|
||||
key,
|
||||
e.field,
|
||||
e.reason,
|
||||
cause)
|
||||
}
|
||||
|
||||
var _ error = SharepointValidationError{}
|
||||
|
||||
var _ interface {
|
||||
Field() string
|
||||
Reason() string
|
||||
Key() bool
|
||||
Cause() error
|
||||
ErrorName() string
|
||||
} = SharepointValidationError{}
|
||||
|
||||
@@ -50,12 +50,10 @@ func TestSource_Scan(t *testing.T) {
|
||||
wantSourceMetadata: &source_metadatapb.MetaData{
|
||||
Data: &source_metadatapb.MetaData_Circleci{
|
||||
Circleci: &source_metadatapb.CircleCI{
|
||||
VcsType: "github",
|
||||
Username: "dustin-decker",
|
||||
Repository: "circle-ci",
|
||||
BuildNumber: 2,
|
||||
BuildStep: "Spin up environment",
|
||||
Link: "https://app.circleci.com/pipelines/github/dustin-decker/circle-ci/2",
|
||||
VcsType: "github",
|
||||
Username: "dustin-decker",
|
||||
Repository: "circle-ci",
|
||||
BuildStep: "Spin up environment",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -85,6 +83,8 @@ func TestSource_Scan(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
gotChunk := <-chunksCh
|
||||
gotChunk.SourceMetadata.Data.(*source_metadatapb.MetaData_Circleci).Circleci.BuildNumber = 0 // override this because we need to periodically re-run the builds
|
||||
gotChunk.SourceMetadata.Data.(*source_metadatapb.MetaData_Circleci).Circleci.Link = "" // override this because we need to periodically re-run the builds
|
||||
if diff := pretty.Compare(gotChunk.SourceMetadata, tt.wantSourceMetadata); diff != "" {
|
||||
t.Errorf("Source.Chunks() %s diff: (-got +want)\n%s", tt.name, diff)
|
||||
}
|
||||
|
||||
+82
-1
@@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"cloud.google.com/go/storage"
|
||||
@@ -17,6 +18,8 @@ import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/cache"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/cache/memory"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/handlers"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/credentialspb"
|
||||
@@ -25,6 +28,8 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/sources"
|
||||
)
|
||||
|
||||
const defaultCachePersistIncrement = 2500
|
||||
|
||||
// Ensure the Source satisfies the interface at compile time.
|
||||
var _ sources.Source = (*Source)(nil)
|
||||
|
||||
@@ -57,7 +62,41 @@ type Source struct {
|
||||
log logr.Logger
|
||||
chunksCh chan *sources.Chunk
|
||||
|
||||
sources.Progress
|
||||
mu sync.Mutex
|
||||
sources.Progress // progress is not thread safe
|
||||
}
|
||||
|
||||
// persistableCache is a wrapper around cache.Cache that allows
|
||||
// for the persistence of the cache contents in the Progress of the source
|
||||
// at given increments.
|
||||
type persistableCache struct {
|
||||
persistIncrement int
|
||||
cache.Cache
|
||||
*sources.Progress
|
||||
}
|
||||
|
||||
func newPersistableCache(increment int, cache cache.Cache, p *sources.Progress) *persistableCache {
|
||||
return &persistableCache{
|
||||
persistIncrement: increment,
|
||||
Cache: cache,
|
||||
Progress: p,
|
||||
}
|
||||
}
|
||||
|
||||
// Set overrides the cache Set method of the cache to enable the persistence
|
||||
// of the cache contents the Progress of the source at given increments.
|
||||
func (c *persistableCache) Set(key, val string) {
|
||||
c.Cache.Set(key, val)
|
||||
if ok, contents := c.shouldPersist(); ok {
|
||||
c.Progress.EncodedResumeInfo = contents
|
||||
}
|
||||
}
|
||||
|
||||
func (c *persistableCache) shouldPersist() (bool, string) {
|
||||
if c.Count()%c.persistIncrement != 0 {
|
||||
return false, ""
|
||||
}
|
||||
return true, c.Contents()
|
||||
}
|
||||
|
||||
// Init returns an initialized GCS source.
|
||||
@@ -190,6 +229,7 @@ func setGCSManagerOptions(include, exclude []string, includeFn, excludeFn func([
|
||||
}
|
||||
|
||||
// enumerate all the objects and buckets in the source.
|
||||
// This will be used to calculate progress.
|
||||
func (s *Source) enumerate(ctx context.Context) error {
|
||||
stats, err := s.gcsManager.attributes(ctx)
|
||||
if err != nil {
|
||||
@@ -202,11 +242,14 @@ func (s *Source) enumerate(ctx context.Context) error {
|
||||
|
||||
// Chunks emits chunks of bytes over a channel.
|
||||
func (s *Source) Chunks(ctx context.Context, chunksChan chan *sources.Chunk) error {
|
||||
persistableCache := s.setupCache(ctx)
|
||||
|
||||
objectCh, err := s.gcsManager.listObjects(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error listing objects: %w", err)
|
||||
}
|
||||
s.chunksCh = chunksChan
|
||||
s.Progress.Message = "starting to process objects..."
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for obj := range objectCh {
|
||||
@@ -217,6 +260,11 @@ func (s *Source) Chunks(ctx context.Context, chunksChan chan *sources.Chunk) err
|
||||
continue
|
||||
}
|
||||
|
||||
if persistableCache.Exists(o.name) {
|
||||
ctx.Logger().V(5).Info("skipping object, object already processed", "name", o.name)
|
||||
continue
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go func(obj object) {
|
||||
defer wg.Done()
|
||||
@@ -225,13 +273,46 @@ func (s *Source) Chunks(ctx context.Context, chunksChan chan *sources.Chunk) err
|
||||
ctx.Logger().V(1).Info("error setting start progress progress", "name", o.name, "error", err)
|
||||
return
|
||||
}
|
||||
s.setProgress(ctx, o.md5, o.name, persistableCache)
|
||||
}(o)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
s.completeProgress(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Source) setupCache(ctx context.Context) *persistableCache {
|
||||
var c cache.Cache
|
||||
if s.Progress.EncodedResumeInfo != "" {
|
||||
c = memory.NewWithData(ctx, strings.Split(s.Progress.EncodedResumeInfo, ","))
|
||||
} else {
|
||||
c = memory.New()
|
||||
}
|
||||
|
||||
// TODO (ahrav): Make this configurable via conn.
|
||||
persistCache := newPersistableCache(defaultCachePersistIncrement, c, &s.Progress)
|
||||
return persistCache
|
||||
}
|
||||
|
||||
func (s *Source) setProgress(ctx context.Context, md5, objName string, cache cache.Cache) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
ctx.Logger().V(5).Info("setting progress for object", "object-name", objName)
|
||||
s.SectionsCompleted++
|
||||
|
||||
cache.Set(md5, md5)
|
||||
s.Progress.SectionsRemaining = int32(s.stats.numObjects)
|
||||
s.Progress.PercentComplete = int64(float64(s.SectionsCompleted) / float64(s.stats.numObjects) * 100)
|
||||
}
|
||||
|
||||
func (s *Source) completeProgress(ctx context.Context) {
|
||||
msg := fmt.Sprintf("GCS source finished processing %d objects", s.stats.numObjects)
|
||||
ctx.Logger().Info(msg)
|
||||
s.Progress.Message = msg
|
||||
}
|
||||
|
||||
func (s *Source) processObject(ctx context.Context, o object) error {
|
||||
chunkSkel := &sources.Chunk{
|
||||
SourceName: s.name,
|
||||
|
||||
@@ -2,6 +2,7 @@ package gcs
|
||||
|
||||
import (
|
||||
aCtx "context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -28,9 +29,7 @@ const (
|
||||
maxObjectSizeLimit = 50 * 1024 * 1024 // 50MB
|
||||
)
|
||||
|
||||
var (
|
||||
defaultConcurrency = runtime.NumCPU()
|
||||
)
|
||||
var defaultConcurrency = runtime.NumCPU()
|
||||
|
||||
type objectManager interface {
|
||||
listObjects(context.Context) (chan io.Reader, error)
|
||||
@@ -295,7 +294,7 @@ func withConcurrency(concurrency int) gcsManagerOption {
|
||||
|
||||
// withMaxObjectSize sets the maximum size of objects that will be scanned.
|
||||
// If not set, set to a negative number, or set larger than 1GB,
|
||||
// the default value of 500MB will be used.
|
||||
// the default value of 50MB will be used.
|
||||
func withMaxObjectSize(maxObjectSize int64) gcsManagerOption {
|
||||
return func(m *gcsManager) error {
|
||||
if maxObjectSize <= 0 || maxObjectSize > maxObjectSizeLimit {
|
||||
@@ -371,6 +370,7 @@ type object struct {
|
||||
contentType string
|
||||
owner string
|
||||
link string
|
||||
md5 string
|
||||
// acl represents an ACLEntities.
|
||||
// https://pkg.go.dev/cloud.google.com/go/storage#ACLEntity
|
||||
acl []string
|
||||
@@ -648,6 +648,7 @@ func (g *gcsManager) constructObject(ctx context.Context, obj *storage.ObjectHan
|
||||
o.contentType = attrs.ContentType
|
||||
o.owner = attrs.Owner
|
||||
o.link = attrs.MediaLink
|
||||
o.md5 = hex.EncodeToString(attrs.MD5)
|
||||
o.createdAt = attrs.Created
|
||||
o.updatedAt = attrs.Updated
|
||||
o.acl = objectACLs(attrs.ACL)
|
||||
|
||||
@@ -480,6 +480,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 150,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th/o/aws1.txt?generation=1677870994890594&alt=media",
|
||||
acl: []string{},
|
||||
md5: "7a4df45f839cd594ac236b19524cec92",
|
||||
},
|
||||
{
|
||||
name: "moar2.txt",
|
||||
@@ -488,6 +489,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 12,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th/o/moar2.txt?generation=1677871000378542&alt=media",
|
||||
acl: []string{},
|
||||
md5: "e59ff97941044f85df5297e1c302d260",
|
||||
},
|
||||
{
|
||||
name: "aws3.txt",
|
||||
@@ -496,6 +498,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 150,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th2/o/aws3.txt?generation=1677871022489611&alt=media",
|
||||
acl: []string{},
|
||||
md5: "26eb03378a0c8e99ee0cecf9155ace81",
|
||||
},
|
||||
{
|
||||
name: "moar.txt",
|
||||
@@ -504,6 +507,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 6,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th3/o/moar.txt?generation=1677871042896804&alt=media",
|
||||
acl: []string{},
|
||||
md5: "09f7e02f1290be211da707a266f153b3",
|
||||
},
|
||||
{
|
||||
name: "AMAZON_FASHION_5.json",
|
||||
@@ -512,6 +516,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 1413469,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th4/o/AMAZON_FASHION_5.json?generation=1677871063457469&alt=media",
|
||||
acl: []string{},
|
||||
md5: "5a1d8f483aa34695256379050d42a2b7",
|
||||
},
|
||||
},
|
||||
wantNumBkt: 4,
|
||||
@@ -529,6 +534,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 150,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th/o/aws1.txt?generation=1677870994890594&alt=media",
|
||||
acl: []string{},
|
||||
md5: "7a4df45f839cd594ac236b19524cec92",
|
||||
},
|
||||
{
|
||||
name: "moar2.txt",
|
||||
@@ -537,6 +543,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 12,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th/o/moar2.txt?generation=1677871000378542&alt=media",
|
||||
acl: []string{},
|
||||
md5: "e59ff97941044f85df5297e1c302d260",
|
||||
},
|
||||
},
|
||||
wantNumBkt: 1,
|
||||
@@ -554,6 +561,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 6,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th3/o/moar.txt?generation=1677871042896804&alt=media",
|
||||
acl: []string{},
|
||||
md5: "09f7e02f1290be211da707a266f153b3",
|
||||
},
|
||||
{
|
||||
name: "AMAZON_FASHION_5.json",
|
||||
@@ -562,6 +570,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 1413469,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th4/o/AMAZON_FASHION_5.json?generation=1677871063457469&alt=media",
|
||||
acl: []string{},
|
||||
md5: "5a1d8f483aa34695256379050d42a2b7",
|
||||
},
|
||||
},
|
||||
wantNumBkt: 2,
|
||||
@@ -583,6 +592,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 150,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th2/o/aws3.txt?generation=1677871022489611&alt=media",
|
||||
acl: []string{},
|
||||
md5: "26eb03378a0c8e99ee0cecf9155ace81",
|
||||
},
|
||||
{
|
||||
name: "moar.txt",
|
||||
@@ -591,6 +601,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 6,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th3/o/moar.txt?generation=1677871042896804&alt=media",
|
||||
acl: []string{},
|
||||
md5: "09f7e02f1290be211da707a266f153b3",
|
||||
},
|
||||
{
|
||||
name: "AMAZON_FASHION_5.json",
|
||||
@@ -599,6 +610,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 1413469,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th4/o/AMAZON_FASHION_5.json?generation=1677871063457469&alt=media",
|
||||
acl: []string{},
|
||||
md5: "5a1d8f483aa34695256379050d42a2b7",
|
||||
},
|
||||
},
|
||||
wantNumBkt: 4, // We still list objects in all buckets.
|
||||
@@ -620,6 +632,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 150,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th/o/aws1.txt?generation=1677870994890594&alt=media",
|
||||
acl: []string{},
|
||||
md5: "7a4df45f839cd594ac236b19524cec92",
|
||||
},
|
||||
},
|
||||
wantNumBkt: 1,
|
||||
@@ -641,6 +654,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 150,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th/o/aws1.txt?generation=1677870994890594&alt=media",
|
||||
acl: []string{},
|
||||
md5: "7a4df45f839cd594ac236b19524cec92",
|
||||
},
|
||||
},
|
||||
wantNumBkt: 4,
|
||||
@@ -663,6 +677,7 @@ func TestGCSManagerListObjects(t *testing.T) {
|
||||
size: 12,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th/o/moar2.txt?generation=1677871000378542&alt=media",
|
||||
acl: []string{},
|
||||
md5: "e59ff97941044f85df5297e1c302d260",
|
||||
},
|
||||
},
|
||||
wantNumBkt: 1,
|
||||
@@ -750,6 +765,7 @@ func TestGCSManagerListObjects_Resuming(t *testing.T) {
|
||||
size: 12,
|
||||
link: "https://storage.googleapis.com/download/storage/v1/b/test-bkt-th/o/moar2.txt?generation=1677871000378542&alt=media",
|
||||
acl: []string{},
|
||||
md5: "e59ff97941044f85df5297e1c302d260",
|
||||
},
|
||||
},
|
||||
wantNumBkt: 1,
|
||||
|
||||
+108
-5
@@ -5,6 +5,8 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -203,7 +205,9 @@ func TestSourceOauth2Client(t *testing.T) {
|
||||
}
|
||||
|
||||
type mockObjectManager struct {
|
||||
wantErr bool
|
||||
// numObjects is the number of objects to return in the listObjects call.
|
||||
numObjects int
|
||||
wantErr bool
|
||||
}
|
||||
|
||||
func (m *mockObjectManager) attributes(_ context.Context) (*attributes, error) {
|
||||
@@ -212,7 +216,7 @@ func (m *mockObjectManager) attributes(_ context.Context) (*attributes, error) {
|
||||
}
|
||||
|
||||
return &attributes{
|
||||
numObjects: 5,
|
||||
numObjects: uint64(m.numObjects),
|
||||
numBuckets: 1,
|
||||
bucketObjects: map[string]uint64{testBucket: 5},
|
||||
}, nil
|
||||
@@ -242,7 +246,7 @@ func (m *mockObjectManager) listObjects(context.Context) (chan io.Reader, error)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
// Add 5 objects to the channel.
|
||||
for i := 0; i < 5; i++ {
|
||||
for i := 0; i < m.numObjects; i++ {
|
||||
ch <- createTestObject(i)
|
||||
}
|
||||
}()
|
||||
@@ -259,6 +263,7 @@ func createTestObject(id int) object {
|
||||
link: fmt.Sprintf("https://storage.googleapis.com/%s/%s", testBucket, fmt.Sprintf("object%d", id)),
|
||||
acl: []string{"authenticatedUsers"},
|
||||
size: 42,
|
||||
md5: fmt.Sprintf("md5hash%d", id),
|
||||
Reader: &mockReader{data: []byte(fmt.Sprintf("hello world %d", id))},
|
||||
createdAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
}
|
||||
@@ -292,8 +297,9 @@ func TestSourceChunks_ListObjects(t *testing.T) {
|
||||
chunksCh := make(chan *sources.Chunk, 1)
|
||||
|
||||
source := &Source{
|
||||
gcsManager: &mockObjectManager{},
|
||||
gcsManager: &mockObjectManager{numObjects: 5},
|
||||
chunksCh: chunksCh,
|
||||
Progress: sources.Progress{},
|
||||
}
|
||||
|
||||
err := source.enumerate(ctx)
|
||||
@@ -338,7 +344,7 @@ func TestSourceChunks_ListObjects(t *testing.T) {
|
||||
|
||||
func TestSourceInit_Enumerate(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
source := &Source{gcsManager: &mockObjectManager{}}
|
||||
source := &Source{gcsManager: &mockObjectManager{numObjects: 5}}
|
||||
|
||||
err := source.enumerate(ctx)
|
||||
assert.Nil(t, err)
|
||||
@@ -359,3 +365,100 @@ func TestSourceChunks_ListObjects_Error(t *testing.T) {
|
||||
err := source.Chunks(ctx, chunksCh)
|
||||
assert.True(t, err != nil)
|
||||
}
|
||||
|
||||
func TestSourceChunks_ProgressSet(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
chunksCh := make(chan *sources.Chunk, 1)
|
||||
source := &Source{
|
||||
gcsManager: &mockObjectManager{numObjects: defaultCachePersistIncrement},
|
||||
chunksCh: chunksCh,
|
||||
Progress: sources.Progress{},
|
||||
}
|
||||
|
||||
err := source.enumerate(ctx)
|
||||
assert.Nil(t, err)
|
||||
|
||||
go func() {
|
||||
defer close(chunksCh)
|
||||
err := source.Chunks(ctx, chunksCh)
|
||||
assert.Nil(t, err)
|
||||
}()
|
||||
|
||||
want := make([]*sources.Chunk, 0, defaultCachePersistIncrement)
|
||||
for i := 0; i < defaultCachePersistIncrement; i++ {
|
||||
want = append(want, createTestSourceChunk(i))
|
||||
}
|
||||
|
||||
got := make([]*sources.Chunk, 0, defaultCachePersistIncrement)
|
||||
for ch := range chunksCh {
|
||||
got = append(got, ch)
|
||||
}
|
||||
|
||||
// Ensure we get 2500 objects back.
|
||||
assert.Equal(t, len(want), len(got))
|
||||
|
||||
// Test that the resume progress is set.
|
||||
var progress strings.Builder
|
||||
for i := range got {
|
||||
progress.WriteString(fmt.Sprintf("md5hash%d", i))
|
||||
// Add a comma if not the last element.
|
||||
if i != len(got)-1 {
|
||||
progress.WriteString(",")
|
||||
}
|
||||
}
|
||||
|
||||
encodeResume := strings.Split(source.Progress.EncodedResumeInfo, ",")
|
||||
sort.Slice(encodeResume, func(i, j int) bool {
|
||||
numI, _ := strconv.Atoi(strings.TrimPrefix(encodeResume[i], "md5hash"))
|
||||
numJ, _ := strconv.Atoi(strings.TrimPrefix(encodeResume[j], "md5hash"))
|
||||
return numI < numJ
|
||||
})
|
||||
|
||||
assert.Equal(t, progress.String(), strings.Join(encodeResume, ","))
|
||||
assert.Equal(t, int32(defaultCachePersistIncrement), source.Progress.SectionsCompleted)
|
||||
assert.Equal(t, int64(100), source.Progress.PercentComplete)
|
||||
assert.Equal(t, fmt.Sprintf("GCS source finished processing %d objects", defaultCachePersistIncrement), source.Progress.Message)
|
||||
}
|
||||
|
||||
func TestSource_CachePersistence(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
wantObjCnt := 4 // ensure we have less objects than the cache increment
|
||||
mockObjManager := &mockObjectManager{numObjects: wantObjCnt}
|
||||
|
||||
chunksCh := make(chan *sources.Chunk, 1)
|
||||
source := &Source{
|
||||
gcsManager: mockObjManager,
|
||||
chunksCh: chunksCh,
|
||||
Progress: sources.Progress{},
|
||||
}
|
||||
|
||||
err := source.enumerate(ctx)
|
||||
assert.Nil(t, err)
|
||||
|
||||
go func() {
|
||||
defer close(chunksCh)
|
||||
err := source.Chunks(ctx, chunksCh)
|
||||
assert.Nil(t, err)
|
||||
}()
|
||||
|
||||
want := make([]*sources.Chunk, 0, wantObjCnt)
|
||||
for i := 0; i < wantObjCnt; i++ {
|
||||
want = append(want, createTestSourceChunk(i))
|
||||
}
|
||||
|
||||
got := make([]*sources.Chunk, 0, wantObjCnt)
|
||||
for ch := range chunksCh {
|
||||
got = append(got, ch)
|
||||
}
|
||||
|
||||
// Ensure we get 4 objects back.
|
||||
assert.Equal(t, len(want), len(got))
|
||||
|
||||
// Test that the resume progress is empty.
|
||||
// The cache should not have been persisted.
|
||||
assert.Equal(t, "", source.Progress.EncodedResumeInfo)
|
||||
assert.Equal(t, int32(wantObjCnt), source.Progress.SectionsCompleted)
|
||||
assert.Equal(t, int64(100), source.Progress.PercentComplete)
|
||||
assert.Equal(t, fmt.Sprintf("GCS source finished processing %d objects", wantObjCnt), source.Progress.Message)
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ func CloneRepo(ctx context.Context, userInfo *url.Userinfo, gitUrl string, args
|
||||
return "", nil, errors.New("clone command exited with no output")
|
||||
}
|
||||
if cloneCmd.ProcessState != nil && cloneCmd.ProcessState.ExitCode() != 0 {
|
||||
logger.V(1).Info("git clone failed", "output", output, "error", err)
|
||||
logger.V(1).Info("git clone failed", "output", string(output), "error", err)
|
||||
return "", nil, fmt.Errorf("could not clone repo: %s, %w", safeUrl, err)
|
||||
}
|
||||
|
||||
@@ -560,7 +560,8 @@ func (s *Git) ScanRepo(ctx context.Context, repo *git.Repository, repoPath strin
|
||||
if err := normalizeConfig(scanOptions, repo); err != nil {
|
||||
return err
|
||||
}
|
||||
start := time.Now().UnixNano()
|
||||
start := time.Now().Unix()
|
||||
|
||||
if err := s.ScanCommits(ctx, repo, repoPath, scanOptions, chunksChan); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -576,8 +577,8 @@ func (s *Git) ScanRepo(ctx context.Context, repo *git.Repository, repoPath strin
|
||||
repoUrl = getSafeRemoteURL(repo, remotes[0].Config().Name)
|
||||
}
|
||||
|
||||
scanTime := time.Now().UnixNano() - start
|
||||
ctx.Logger().V(1).Info("scanning git repo complete", "Repo", repoUrl, "path", repoPath, "time", scanTime)
|
||||
scanTime := time.Now().Unix() - start
|
||||
ctx.Logger().V(1).Info("scanning git repo complete", "repo", repoUrl, "path", repoPath, "time_seconds", scanTime)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -320,6 +320,8 @@ func (s *Source) enumerateWithToken(ctx context.Context, apiEndpoint, token stri
|
||||
ghUser *github.User
|
||||
resp *github.Response
|
||||
)
|
||||
|
||||
ctx.Logger().V(1).Info("Enumerating with token", "endpoint", apiEndpoint)
|
||||
for {
|
||||
ghUser, resp, err = s.apiClient.Users.Get(context.TODO(), "")
|
||||
if handled := s.handleRateLimit(err, resp); handled {
|
||||
@@ -373,16 +375,10 @@ func (s *Source) enumerateWithToken(ctx context.Context, apiEndpoint, token stri
|
||||
logger.Error(err, "error fetching repos for user", "user", ghUser.GetLogin())
|
||||
}
|
||||
|
||||
// TODO: Test it actually works to list org gists like this.
|
||||
if err := s.addGistsByUser(ctx, org); err != nil {
|
||||
logger.Error(err, "error fetching gists by org")
|
||||
}
|
||||
|
||||
if s.conn.ScanUsers {
|
||||
err := s.addMembersByOrg(ctx, org)
|
||||
if err != nil {
|
||||
logger.Error(err, "Unable to add members by org for org")
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -392,6 +388,9 @@ func (s *Source) enumerateWithToken(ctx context.Context, apiEndpoint, token stri
|
||||
if err := s.addGistsByUser(ctx, ghUser.GetLogin()); err != nil {
|
||||
s.log.Error(err, "error fetching gists", "user", ghUser.GetLogin())
|
||||
}
|
||||
|
||||
s.log.Info("Completed enumeration", "num_repos", len(s.repos), "num_orgs", len(s.orgs), "num_members", len(s.members))
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.conn.ScanUsers {
|
||||
@@ -503,14 +502,10 @@ func (s *Source) Chunks(ctx context.Context, chunksChan chan *sources.Chunk) err
|
||||
// We must sort the repos so we can resume later if necessary.
|
||||
sort.Strings(s.repos)
|
||||
|
||||
for _, err := range s.scan(ctx, installationClient, chunksChan) {
|
||||
s.log.Error(err, "error scanning repository")
|
||||
}
|
||||
|
||||
return nil
|
||||
return s.scan(ctx, installationClient, chunksChan)
|
||||
}
|
||||
|
||||
func (s *Source) scan(ctx context.Context, installationClient *github.Client, chunksChan chan *sources.Chunk) []error {
|
||||
func (s *Source) scan(ctx context.Context, installationClient *github.Client, chunksChan chan *sources.Chunk) error {
|
||||
var scanned uint64
|
||||
|
||||
s.log.V(2).Info("Found repos to scan", "count", len(s.repos))
|
||||
@@ -524,7 +519,7 @@ func (s *Source) scan(ctx context.Context, installationClient *github.Client, ch
|
||||
s.scanOptions = &git.ScanOptions{}
|
||||
}
|
||||
|
||||
var scanErrs []error
|
||||
scanErrs := sources.NewScanErrors()
|
||||
for i, repoURL := range s.repos {
|
||||
i, repoURL := i, repoURL
|
||||
s.jobPool.Go(func() error {
|
||||
@@ -542,7 +537,7 @@ func (s *Source) scan(ctx context.Context, installationClient *github.Client, ch
|
||||
}(s, repoURL)
|
||||
|
||||
if !strings.HasSuffix(repoURL, ".git") {
|
||||
scanErrs = append(scanErrs, fmt.Errorf("repo %s does not end in .git", repoURL))
|
||||
scanErrs.Add(fmt.Errorf("repo %s does not end in .git", repoURL))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -553,20 +548,18 @@ func (s *Source) scan(ctx context.Context, installationClient *github.Client, ch
|
||||
var err error
|
||||
|
||||
path, repo, err = s.cloneRepo(ctx, repoURL, installationClient)
|
||||
if err != nil {
|
||||
scanErrs = append(scanErrs, err)
|
||||
}
|
||||
|
||||
defer os.RemoveAll(path)
|
||||
if err != nil {
|
||||
scanErrs.Add(fmt.Errorf("error cloning repo %s: %w", repoURL, err))
|
||||
return nil
|
||||
}
|
||||
|
||||
s.scanOptions.BaseHash = s.conn.Base
|
||||
s.scanOptions.HeadHash = s.conn.Head
|
||||
|
||||
logger.V(2).Info(fmt.Sprintf("scanning repo %d/%d", i, len(s.repos)))
|
||||
if err = s.git.ScanRepo(ctx, repo, path, s.scanOptions, chunksChan); err != nil {
|
||||
logger.Error(err, "unable to scan repo, continuing")
|
||||
scanErrs.Add(fmt.Errorf("error scanning repo %s: %w", repoURL, err))
|
||||
return nil
|
||||
}
|
||||
atomic.AddUint64(&scanned, 1)
|
||||
@@ -577,11 +570,12 @@ func (s *Source) scan(ctx context.Context, installationClient *github.Client, ch
|
||||
}
|
||||
|
||||
_ = s.jobPool.Wait()
|
||||
if len(scanErrs) == 0 {
|
||||
s.SetProgressComplete(len(s.repos), len(s.repos), "Completed Github scan", "")
|
||||
if scanErrs.Count() > 0 {
|
||||
s.log.V(2).Info("Errors encountered while scanning", "error-count", scanErrs.Count(), "errors", scanErrs)
|
||||
}
|
||||
s.SetProgressComplete(len(s.repos), len(s.repos), "Completed Github scan", "")
|
||||
|
||||
return scanErrs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Source) cloneRepo(ctx context.Context, repoURL string, installationClient *github.Client) (string, *gogit.Repository, error) {
|
||||
|
||||
@@ -498,9 +498,10 @@ func Test_scan_SetProgressComplete(t *testing.T) {
|
||||
wantComplete: true,
|
||||
},
|
||||
{
|
||||
name: "one valid repo",
|
||||
repos: []string{"a"},
|
||||
wantErr: true,
|
||||
name: "one valid repo",
|
||||
repos: []string{"a"},
|
||||
wantComplete: true,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
+24
-5
@@ -29,6 +29,11 @@ import (
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/sources"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultMaxObjectSize = 250 * 1024 * 1024 // 250 MiB
|
||||
maxObjectSizeLimit = 250 * 1024 * 1024 // 250 MiB
|
||||
)
|
||||
|
||||
type Source struct {
|
||||
name string
|
||||
sourceId int64
|
||||
@@ -37,9 +42,10 @@ type Source struct {
|
||||
concurrency int
|
||||
log logr.Logger
|
||||
sources.Progress
|
||||
errorCount *sync.Map
|
||||
conn *sourcespb.S3
|
||||
jobPool *errgroup.Group
|
||||
errorCount *sync.Map
|
||||
conn *sourcespb.S3
|
||||
jobPool *errgroup.Group
|
||||
maxObjectSize int64
|
||||
}
|
||||
|
||||
// Ensure the Source satisfies the interface at compile time
|
||||
@@ -79,9 +85,22 @@ func (s *Source) Init(aCtx context.Context, name string, jobId, sourceId int64,
|
||||
}
|
||||
s.conn = &conn
|
||||
|
||||
s.setMaxObjectSize(conn.GetMaxObjectSize())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// setMaxObjectSize sets the maximum size of objects that will be scanned. If
|
||||
// not set, set to a negative number, or set larger than the
|
||||
// maxObjectSizeLimit, the defaultMaxObjectSizeLimit will be used.
|
||||
func (s *Source) setMaxObjectSize(maxObjectSize int64) {
|
||||
if maxObjectSize <= 0 || maxObjectSize > maxObjectSizeLimit {
|
||||
s.maxObjectSize = defaultMaxObjectSize
|
||||
} else {
|
||||
s.maxObjectSize = maxObjectSize
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Source) newClient(region string) (*s3.S3, error) {
|
||||
cfg := aws.NewConfig()
|
||||
cfg.CredentialsChainVerboseErrors = aws.Bool(true)
|
||||
@@ -203,8 +222,8 @@ func (s *Source) pageChunker(ctx context.Context, client *s3.S3, chunksChan chan
|
||||
}
|
||||
|
||||
// ignore large files
|
||||
if *obj.Size > int64(250*common.MB) {
|
||||
s.log.V(3).Info("Skipping %d byte file (over 250MB limit)", "object", *obj.Key)
|
||||
if *obj.Size > s.maxObjectSize {
|
||||
s.log.V(3).Info("Skipping %d byte file (over maxObjectSize limit)", "object", *obj.Key)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,8 @@ type S3Config struct {
|
||||
SessionToken string
|
||||
// Buckets is the list of buckets to scan.
|
||||
Buckets []string
|
||||
// MaxObjectSize is the maximum object size to scan.
|
||||
MaxObjectSize int64
|
||||
}
|
||||
|
||||
// SyslogConfig defines the optional configuration for a syslog source.
|
||||
|
||||
@@ -10,7 +10,7 @@ type ChunkFunc func(chunk *Chunk) error
|
||||
|
||||
var MatchError = errors.New("chunk doesn't match")
|
||||
|
||||
func HandleTestChannel(chunksCh chan *Chunk, cf ChunkFunc) error {
|
||||
func HandleTestChannel(chunksCh chan *Chunk, cf ChunkFunc, timeout int) error {
|
||||
for {
|
||||
select {
|
||||
case gotChunk := <-chunksCh:
|
||||
@@ -22,8 +22,8 @@ func HandleTestChannel(chunksCh chan *Chunk, cf ChunkFunc) error {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case <-time.After(10 * time.Second):
|
||||
return fmt.Errorf("no new chunks received after 10 seconds")
|
||||
case <-time.After(time.Duration(timeout) * time.Second):
|
||||
return fmt.Errorf("no new chunks received after %d seconds", timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ enum DecoderType {
|
||||
UNKNOWN = 0;
|
||||
PLAIN = 1;
|
||||
BASE64 = 2;
|
||||
UTF16 = 3;
|
||||
}
|
||||
|
||||
enum DetectorType {
|
||||
@@ -919,6 +920,8 @@ enum DetectorType {
|
||||
Moralis = 909;
|
||||
BscScan = 910;
|
||||
CoinMarketCap = 911;
|
||||
Percy = 912;
|
||||
TinesWebhook = 913;
|
||||
}
|
||||
|
||||
message Result {
|
||||
|
||||
@@ -111,15 +111,6 @@ message Gitlab {
|
||||
int64 line = 7;
|
||||
}
|
||||
|
||||
message GoogleDrive {
|
||||
string file = 1;
|
||||
string link = 2;
|
||||
string email = 3;
|
||||
string timestamp = 4;
|
||||
bool shared = 5;
|
||||
string last_modified_by = 6;
|
||||
}
|
||||
|
||||
message GCS {
|
||||
string bucket = 1;
|
||||
string filename = 2;
|
||||
@@ -212,6 +203,8 @@ message Teams {
|
||||
string file = 6;
|
||||
string email = 7;
|
||||
string location = 8;
|
||||
string team_name = 9;
|
||||
string team_id = 10;
|
||||
}
|
||||
|
||||
// https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-FileInfo
|
||||
@@ -239,6 +232,25 @@ message PublicEventMonitoring {
|
||||
}
|
||||
}
|
||||
|
||||
message SharePoint {
|
||||
string link = 1;
|
||||
string timestamp = 2;
|
||||
string author = 3;
|
||||
string title = 4;
|
||||
int64 views = 5;
|
||||
string docid = 6;
|
||||
string email = 7;
|
||||
}
|
||||
|
||||
message GoogleDrive {
|
||||
string file = 1;
|
||||
string link = 2;
|
||||
string email = 3;
|
||||
string timestamp = 4;
|
||||
bool shared = 5;
|
||||
string last_modified_by = 6;
|
||||
}
|
||||
|
||||
message MetaData {
|
||||
oneof data {
|
||||
Azure azure = 1;
|
||||
@@ -265,5 +277,7 @@ message MetaData {
|
||||
Artifactory artifactory = 22;
|
||||
Syslog syslog = 23;
|
||||
PublicEventMonitoring publicEventMonitoring = 24;
|
||||
SharePoint sharepoint = 25;
|
||||
GoogleDrive googleDrive = 26;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-1
@@ -41,6 +41,7 @@ enum SourceType {
|
||||
SOURCE_TYPE_PUBLIC_EVENT_MONITORING = 26;
|
||||
SOURCE_TYPE_SLACK_REALTIME = 27;
|
||||
SOURCE_TYPE_GOOGLE_DRIVE = 28;
|
||||
SOURCE_TYPE_SHAREPOINT = 29;
|
||||
SOURCE_TYPE_GCS_UNAUTHED = 30;
|
||||
}
|
||||
|
||||
@@ -194,6 +195,7 @@ message JIRA {
|
||||
string token = 6;
|
||||
}
|
||||
repeated string projects = 5;
|
||||
repeated string ignore_projects = 7;
|
||||
}
|
||||
|
||||
message NPMUnauthenticatedPackage {
|
||||
@@ -216,6 +218,7 @@ message S3 {
|
||||
credentials.AWSSessionTokenSecret session_token = 5;
|
||||
}
|
||||
repeated string buckets = 3;
|
||||
int64 max_object_size = 6;
|
||||
}
|
||||
|
||||
message Slack {
|
||||
@@ -262,7 +265,7 @@ message Teams {
|
||||
}
|
||||
repeated string channels = 4;
|
||||
repeated string ignoreList = 5;
|
||||
string team_id = 6;
|
||||
repeated string team_ids = 6;
|
||||
}
|
||||
|
||||
// https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-RetrieveFolderorRepositoryArchive
|
||||
@@ -297,3 +300,10 @@ message SlackRealtime {
|
||||
credentials.SlackTokens tokens = 1;
|
||||
}
|
||||
}
|
||||
|
||||
message Sharepoint {
|
||||
oneof credential {
|
||||
credentials.Oauth2 oauth = 1;
|
||||
}
|
||||
string site_url = 2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user