Compare commits

..

41 Commits

Author SHA1 Message Date
Shabbir B d1cbc54fc6 Updated BrowserStack detector endpoint (#1290)
Updated endpoint
2023-04-26 08:59:24 -07:00
Miccah 5a86c18302 Fix include and exclude detector logic (#1267)
* Fix include and exclude detector logic

* Fix test

* Add more clarifying comments
2023-04-26 10:49:54 -05:00
ahrav 622700b6ec update proto to allow for ignoring projects. (#1289) 2023-04-26 07:30:43 -07:00
ahrav 15ed428e28 update jira detector. (#1288) 2023-04-25 17:26:51 -07:00
Shabbir B 6f801f64c7 Added a new detector for percy.io (#1284)
* Feature: Added a new detector for percy.io

* Updated variable name

---------

Co-authored-by: ahrav <ahravdutta02@gmail.com>
2023-04-25 13:18:34 -07:00
Dustin Decker 3485a6dab1 improve sqlserver detection and testing (#1285)
* improve sqlserver detection and testing

* add data source keyword
2023-04-25 11:00:37 -07:00
ahrav 34f5db64ae Small optimizations for the base64 decoder (#1278)
* Small optimizations.

* remove unnecessary timer reset.

* remove blank lines.

* remove test file.

* Move b64 character mapping creation to init.
2023-04-24 11:27:07 -07:00
dependabot[bot] 91bd843ba7 Bump cloud.google.com/go/storage from 1.29.0 to 1.30.1 (#1282)
Bumps [cloud.google.com/go/storage](https://github.com/googleapis/google-cloud-go) from 1.29.0 to 1.30.1.
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/pubsub/v1.29.0...spanner/v1.30.1)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/storage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-24 10:37:48 -07:00
dependabot[bot] 584ab043a2 Bump github.com/envoyproxy/protoc-gen-validate from 0.10.1 to 1.0.0 (#1280)
Bumps [github.com/envoyproxy/protoc-gen-validate](https://github.com/envoyproxy/protoc-gen-validate) from 0.10.1 to 1.0.0.
- [Release notes](https://github.com/envoyproxy/protoc-gen-validate/releases)
- [Changelog](https://github.com/bufbuild/protoc-gen-validate/blob/main/.goreleaser.yaml)
- [Commits](https://github.com/envoyproxy/protoc-gen-validate/compare/v0.10.1...v1.0.0)

---
updated-dependencies:
- dependency-name: github.com/envoyproxy/protoc-gen-validate
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-24 10:27:10 -07:00
dependabot[bot] 7578a3a56e Bump google.golang.org/api from 0.118.0 to 0.119.0 (#1279)
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.118.0 to 0.119.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.118.0...v0.119.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-24 10:12:12 -07:00
ahrav 800ac30ea0 optimize base64 decoder. (#1277) 2023-04-20 20:36:46 -07:00
ahrav abdff53d5d optimize utf-8 decoder (#1275)
* optimize utf-8 decoder.

* remove string conversion.
2023-04-20 16:52:34 -07:00
Yassine Ilmi a002ba9a75 Add RawV2 Results to the JSON Output (#1273)
* Add RawV2 to JSON Output

* Adding RawV2 results to Azure, Datadog and GCP Detectors
2023-04-20 16:31:53 -07:00
ahrav cec1543894 Add utf16 decoder proto. (#1276) 2023-04-20 15:25:36 -07:00
Dustin Decker e217e2fbfd Ensure multipart credentials are deduplicated correctly (#1271)
* Ensure multipart credentials are deduplicated correctly

* update tests
2023-04-20 15:07:59 -07:00
ahrav 4116a24b1c Add utf16 decoder (#1274)
* Add utf16 decoder.

* Add test for utf-8.

* Remove else if.

* optimize to use a single loop.
2023-04-20 15:07:49 -07:00
Bill Rich a6902ae9cb Add configurable detectors (#1139)
* JDBC detector ignore patterns

* Remove newline

---------

Co-authored-by: Bill Rich <bill.rich@trufflesec.com>
2023-04-20 11:44:28 -07:00
Zubair Khan 6dd24d17d4 Switch Endpoint Field to Client ID (#1270)
* no longer using endpoint, but do need client id

* use oauth2 credential type
2023-04-19 16:54:37 -04:00
ahrav 5b2b434a8a Allow multipel team IDs. (#1259) 2023-04-19 11:47:25 -07:00
ah̳̕mͭͭͨͩ̐e̘ͬ́͋ͬ̊̓͂d 1c1f034468 Adding Google drive to MetaData proto (#1264) 2023-04-19 10:49:40 -04:00
dependabot[bot] 661e62f006 Bump github.com/xanzy/go-gitlab from 0.81.0 to 0.83.0 (#1268)
Bumps [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) from 0.81.0 to 0.83.0.
- [Release notes](https://github.com/xanzy/go-gitlab/releases)
- [Changelog](https://github.com/xanzy/go-gitlab/blob/master/releases_test.go)
- [Commits](https://github.com/xanzy/go-gitlab/compare/v0.81.0...v0.83.0)

---
updated-dependencies:
- dependency-name: github.com/xanzy/go-gitlab
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-18 08:48:26 -07:00
dependabot[bot] 92244019a9 Bump github.com/lib/pq from 1.10.7 to 1.10.8 (#1260)
Bumps [github.com/lib/pq](https://github.com/lib/pq) from 1.10.7 to 1.10.8.
- [Release notes](https://github.com/lib/pq/releases)
- [Commits](https://github.com/lib/pq/compare/v1.10.7...v1.10.8)

---
updated-dependencies:
- dependency-name: github.com/lib/pq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-18 08:36:17 -07:00
Miccah dfc5a9f5db [chore] Log possible duplicate detectors (#1266)
* [chore] Log possible duplicate detectors

* Fix typos
2023-04-18 10:36:00 -05:00
dependabot[bot] f5ecbc857b Bump github.com/xanzy/go-gitlab from 0.81.0 to 0.82.0 (#1262)
Bumps [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) from 0.81.0 to 0.82.0.
- [Release notes](https://github.com/xanzy/go-gitlab/releases)
- [Changelog](https://github.com/xanzy/go-gitlab/blob/master/releases_test.go)
- [Commits](https://github.com/xanzy/go-gitlab/compare/v0.81.0...v0.82.0)

---
updated-dependencies:
- dependency-name: github.com/xanzy/go-gitlab
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-18 08:34:01 -07:00
dependabot[bot] 42975c6d1e Bump google.golang.org/api from 0.114.0 to 0.118.0 (#1261)
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.114.0 to 0.118.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.114.0...v0.118.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-18 08:33:14 -07:00
Bill Rich 0507f0eb87 Only add detectors once (#1265) 2023-04-17 14:10:13 -07:00
ahrav 531e3ef6c3 Add team name to proto. (#1258) 2023-04-14 09:07:23 -07:00
Dustin Decker 97ce27153a []bytes were being logged as b64ed string (#1255) 2023-04-14 06:43:26 -07:00
Zachary Rice 1c89e79c2d Remove toLower call on decoded chunk (#1254)
* remove to lower on decoded data

* clean up
2023-04-14 07:29:32 -05:00
ahrav 461f1a631e [chore] - use hex encode vs base64 (#1256)
* use hex encode vs base64.

* fix tests.
2023-04-13 19:16:06 -07:00
ahrav 2fbf86a6ab Use md5 hash for resuming key (#1203)
* Add in-memory caching lib, used by the GCS source.

* Use cache for tracking progress for the GCS source.

* fix merge issue.

* fix merge issue.

* fix test.

* Fix static check.

* Add test for NewWithData.

* Use cache for tracking progress for the GCS source.

* fix merge issue.

* fix merge issue.

* fix test.

* update comment.

* update comments.

* Use cache for tracking progress for the GCS source.

* fix merge issue.

* fix merge issue.

* fix test.

* Include md5 hash to the object struct.

* remove unused dep.

* address comments.

* Add exists method.

* Use cache for tracking progress for the GCS source.

* fix merge issue.

* fix merge issue.

* fix test.

* rebase.

* fix test.

* Use cache for tracking progress for the GCS source.

* fix merge issue.

* fix merge issue.

* fix test.

* rebase.

* rebase.

* split encode resume by comma.

* update comment.

add comment for shouldCache.

remove redundant return.

* use md5 instead of name.

* update tests.

* Include md5 hash to the object struct.

* use md5 instead of name.

* update tests.

* Use a persistable cache.

* fix merge.

* fix merge.

* Include md5 hash to the object struct.

* use md5 instead of name.

* update tests.

* use md5 instead of name.

* update progress tests.

* use name for log message.

* remove slice operation.
2023-04-13 18:26:45 -07:00
Zachary Rice 458c79165a fix extra log messages (#1253)
* fix extra log messages

* add small test, move flag to isindex
2023-04-13 09:53:21 -05:00
Dustin Decker 1db22599af update circle test because workflows expire and need re-running (#1251) 2023-04-10 16:21:19 -07:00
Miccah 562f3aaa2a Generate protos (#1250) 2023-04-10 17:15:53 -05:00
Zubair Khan 2c1d8fbba4 THOG-920/add oss proto (#1240)
* add sharepoint source proto

* create sharepoint oss protos

* add email field, remove oauth2 type, update token to refresh_token

* rename path to link

* restore clientcredentials

* restore s3 and confluence proto changes from make command
2023-04-10 10:30:47 -07:00
dependabot[bot] f1cb933a5a Bump go.mongodb.org/mongo-driver from 1.11.3 to 1.11.4 (#1247)
Bumps [go.mongodb.org/mongo-driver](https://github.com/mongodb/mongo-go-driver) from 1.11.3 to 1.11.4.
- [Release notes](https://github.com/mongodb/mongo-go-driver/releases)
- [Commits](https://github.com/mongodb/mongo-go-driver/compare/v1.11.3...v1.11.4)

---
updated-dependencies:
- dependency-name: go.mongodb.org/mongo-driver
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 10:29:48 -07:00
dependabot[bot] 256ae20079 Bump github.com/bradleyfalzon/ghinstallation/v2 from 2.2.0 to 2.3.0 (#1245)
Bumps [github.com/bradleyfalzon/ghinstallation/v2](https://github.com/bradleyfalzon/ghinstallation) from 2.2.0 to 2.3.0.
- [Release notes](https://github.com/bradleyfalzon/ghinstallation/releases)
- [Commits](https://github.com/bradleyfalzon/ghinstallation/compare/v2.2.0...v2.3.0)

---
updated-dependencies:
- dependency-name: github.com/bradleyfalzon/ghinstallation/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 10:11:46 -07:00
dependabot[bot] 5fce8f9f18 Bump golang.org/x/crypto from 0.7.0 to 0.8.0 (#1244)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.7.0 to 0.8.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/compare/v0.7.0...v0.8.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 10:09:40 -07:00
dependabot[bot] 304abb9ca9 Bump golang.org/x/oauth2 from 0.6.0 to 0.7.0 (#1243)
Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/golang/oauth2/releases)
- [Commits](https://github.com/golang/oauth2/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/oauth2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 10:01:46 -07:00
dependabot[bot] a8c27b9510 Bump golang.org/x/text from 0.8.0 to 0.9.0 (#1246)
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.8.0 to 0.9.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.8.0...v0.9.0)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 10:00:15 -07:00
ahrav c451f9daf8 Use persistable cache for GCS progress tracking (#1204)
* Add in-memory caching lib, used by the GCS source.

* Use cache for tracking progress for the GCS source.

* fix merge issue.

* fix merge issue.

* fix test.

* Fix static check.

* Add test for NewWithData.

* Use cache for tracking progress for the GCS source.

* fix merge issue.

* fix merge issue.

* fix test.

* update comment.

* update comments.

* Use cache for tracking progress for the GCS source.

* fix merge issue.

* fix merge issue.

* fix test.

* remove unused dep.

* address comments.

* Add exists method.

* Use cache for tracking progress for the GCS source.

* fix merge issue.

* fix merge issue.

* fix test.

* rebase.

* fix test.

* Use cache for tracking progress for the GCS source.

* fix merge issue.

* fix merge issue.

* fix test.

* rebase.

* rebase.

* split encode resume by comma.

* Use a persistable cache.

* fix merge.

* fix merge.

* Add progress as part of the cache given it will be the persistence layer.

* Add test for making sure the cache doesn't persist when the increment value is not met.

* fix tests.
2023-04-10 07:55:00 -07:00
48 changed files with 3490 additions and 1901 deletions
+14 -14
View File
@@ -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.3.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,14 +35,14 @@ 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.8
github.com/mattn/go-sqlite3 v1.14.16
github.com/mholt/archiver/v4 v4.0.0-alpha.7
github.com/patrickmn/go-cache v2.1.0+incompatible
@@ -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
@@ -103,7 +103,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/v50 v50.2.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
@@ -142,11 +142,11 @@ 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
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
+36 -25
View File
@@ -3,6 +3,7 @@ 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/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/iam v0.12.0 h1:DRtTY29b75ciH6Ov1PHb4/iat2CLCvrOm40Q0a6DFpE=
@@ -64,8 +65,8 @@ 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/bradleyfalzon/ghinstallation/v2 v2.3.0 h1:RRGTqFWOe++1YmvYmO0PvMGzYTaZ6f8X3Su8WKmM+Ds=
github.com/bradleyfalzon/ghinstallation/v2 v2.3.0/go.mod h1:8rdGt82ERhM7sjY5FLx2gV4aPhxn6YUE8XlDMKG1z/Y=
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=
@@ -95,8 +96,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=
@@ -166,6 +167,7 @@ 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=
@@ -179,12 +181,13 @@ 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/v50 v50.2.0 h1:j2FyongEHlO9nxXLc+LP3wuBSVU9mVxfpdYUexMpIfk=
github.com/google/go-github/v50 v50.2.0/go.mod h1:VBY8FB6yPIjrtKhozXv4FQupxKLS6H4m6xFZlT43q8Q=
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/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
@@ -195,8 +198,8 @@ 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.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=
@@ -247,8 +250,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.8 h1:3fdt97i/cwSU83+E0hZTC/Xpc9mTZxc6UWSCRcSbxiE=
github.com/lib/pq v1.10.8/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=
@@ -342,8 +345,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 +361,8 @@ 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.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=
@@ -377,7 +380,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
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,8 +387,9 @@ 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-20221018205818-5c77f4b2bbd7 h1:lhh9BuEmjIBOdOhMIGSQzdW5LbTtFbUV1k9O/Rlq3SE=
golang.org/x/exp v0.0.0-20221018205818-5c77f4b2bbd7/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
@@ -398,8 +401,9 @@ 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=
@@ -420,11 +424,13 @@ 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.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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -463,14 +469,16 @@ 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/text v0.3.0/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=
@@ -478,8 +486,9 @@ 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.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=
@@ -493,8 +502,9 @@ golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4f
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=
@@ -530,6 +540,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=
+58 -28
View File
@@ -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"
@@ -233,8 +232,8 @@ 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.
var includeDetectorSet, excludeDetectorSet map[config.DetectorID]struct{}
{
includeList, err := config.ParseDetectors(*includeDetectors)
if err != nil {
@@ -246,46 +245,60 @@ func run(state overseer.State) {
// 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)
includeDetectorSet = detectorTypeToSet(includeList)
excludeDetectorSet = detectorTypeToSet(excludeList)
}
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
// Verify that all the user-provided detectors support the optional
// detector features.
{
isVersioner := engine.DefaultDetectorTypesImplementing[detectors.Versioner]()
for id := range includeDetectorSet {
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.
logFatal(
fmt.Errorf("version provided but detector does not have a version"),
"invalid include list detector configuration",
"detector", id,
)
}
return versionD.Version() == id.Version
}
excludeFilter := func(d detectors.Detector) bool {
id, ok := excludeDetectorTypes[d.Type()]
if id.Version == 0 {
return !ok
}
versionD, ok := d.(detectors.Versioner)
if !ok {
// Error: version provided but not a detectors.Versioner
for id := range excludeDetectorSet {
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.
logFatal(
fmt.Errorf("version provided but detector does not have a version"),
"invalid exclude list detector configuration",
"detector", id,
)
}
return versionD.Version() != id.Version
}
includeFilter := func(d detectors.Detector) bool {
_, ok := getWithDetectorID(d, includeDetectorSet)
return ok
}
excludeFilter := func(d detectors.Detector) bool {
_, ok := getWithDetectorID(d, excludeDetectorSet)
return !ok
}
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),
@@ -524,10 +537,27 @@ 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
}
+16
View File
@@ -6,6 +6,7 @@ import (
"strconv"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
dpb "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
)
@@ -31,11 +32,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
+82 -43
View File
@@ -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
}
+23 -7
View File
@@ -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})
}
}
+1
View File
@@ -8,6 +8,7 @@ func DefaultDecoders() []Decoder {
return []Decoder{
&UTF8{},
&Base64{},
&UTF16{},
}
}
+68
View File
@@ -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")
}
+73
View File
@@ -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
View File
@@ -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()
}
+1
View File
@@ -4,6 +4,7 @@ import (
"testing"
"github.com/kylelemons/godebug/pretty"
"github.com/trufflesecurity/trufflehog/v3/pkg/sources"
)
+20 -20
View File
@@ -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{
+1
View File
@@ -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],
}
+1 -1
View File
@@ -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
}
@@ -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 {
+3 -1
View File
@@ -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
+38 -1
View File
@@ -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{
+51
View File
@@ -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{}
+13 -3
View File
@@ -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)
+1
View File
@@ -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 {
+1
View File
@@ -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],
}
+79
View File
@@ -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
}
+119
View File
@@ -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)
}
}
})
}
}
+1 -1
View File
@@ -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.
+62 -5
View File
@@ -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")
}
}
+3
View File
@@ -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,
}
+4 -3
View File
@@ -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)
+19 -7
View File
@@ -16,6 +16,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 +76,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 +85,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 +145,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 +217,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 +324,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 +414,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 +478,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"
@@ -733,13 +741,6 @@ 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
@@ -1565,6 +1566,17 @@ func DefaultDetectors() []detectors.Detector {
moralis.Scanner{},
bscscan.Scanner{},
coinmarketcap.Scanner{},
percy.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
}
+50
View File
@@ -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
View File
@@ -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 {
+6 -1
View File
@@ -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):
+33
View File
@@ -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 = 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
`
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
+4
View File
@@ -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,
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 {
+371 -258
View File
@@ -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()
}
@@ -2367,7 +2378,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 +2462,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 +2823,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 +3119,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 +3136,211 @@ 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,
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,
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,
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, 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, 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, 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, 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, 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,
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, 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,
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 +3356,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 +3387,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 +3783,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 +3895,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,
},
+136 -2
View File
@@ -3543,8 +3543,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 +4250,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{}
+6 -6
View File
@@ -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
View File
@@ -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,
+3
View File
@@ -2,6 +2,7 @@ package gcs
import (
aCtx "context"
"encoding/hex"
"fmt"
"io"
"net/http"
@@ -371,6 +372,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 +650,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)
+16
View File
@@ -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
View File
@@ -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)
}
+1 -1
View File
@@ -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)
}
+2
View File
@@ -8,6 +8,7 @@ enum DecoderType {
UNKNOWN = 0;
PLAIN = 1;
BASE64 = 2;
UTF16 = 3;
}
enum DetectorType {
@@ -919,6 +920,7 @@ enum DetectorType {
Moralis = 909;
BscScan = 910;
CoinMarketCap = 911;
Percy = 912;
}
message Result {
+23 -9
View File
@@ -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;
}
}
+10 -1
View File
@@ -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 {
@@ -262,7 +264,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 +299,10 @@ message SlackRealtime {
credentials.SlackTokens tokens = 1;
}
}
message Sharepoint {
oneof credential {
credentials.Oauth2 oauth = 1;
}
string site_url = 2;
}