Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d78333e1b5 | |||
| af77a4aad0 |
@@ -4,6 +4,10 @@ go 1.20
|
||||
|
||||
replace github.com/jpillora/overseer => github.com/trufflesecurity/overseer v1.1.7-custom5
|
||||
|
||||
replace github.com/zricethezav/gitleaks/v8 => github.com/trufflesecurity/gitleaks/v8 v8.6.1-custom10
|
||||
|
||||
replace github.com/gitleaks/go-gitdiff => github.com/trufflesecurity/go-gitdiff v0.7.6-zombies2
|
||||
|
||||
require (
|
||||
cloud.google.com/go/secretmanager v1.10.0
|
||||
cloud.google.com/go/storage v1.30.1
|
||||
|
||||
Vendored
-4
@@ -15,10 +15,6 @@ type Cache interface {
|
||||
Clear()
|
||||
// Count the number of key/value pairs in the cache.
|
||||
Count() int
|
||||
// Keys returns all keys in the cache.
|
||||
Keys() []string
|
||||
// Values returns all values in the cache.
|
||||
Values() []string
|
||||
// Contents returns all keys in the cache encoded as a string.
|
||||
Contents() string
|
||||
}
|
||||
|
||||
Vendored
-20
@@ -74,26 +74,6 @@ func (c *Cache) Count() int {
|
||||
return c.c.ItemCount()
|
||||
}
|
||||
|
||||
// Keys returns all keys in the cache.
|
||||
func (c *Cache) Keys() []string {
|
||||
items := c.c.Items()
|
||||
res := make([]string, 0, len(items))
|
||||
for k := range items {
|
||||
res = append(res, k)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Values returns all values in the cache.
|
||||
func (c *Cache) Values() []string {
|
||||
items := c.c.Items()
|
||||
res := make([]string, 0, len(items))
|
||||
for _, v := range items {
|
||||
res = append(res, v.Object.(string))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Contents returns all key-value pairs in the cache encodes as a string.
|
||||
func (c *Cache) Contents() string {
|
||||
items := c.c.Items()
|
||||
|
||||
Vendored
+5
-21
@@ -46,28 +46,12 @@ func TestCache(t *testing.T) {
|
||||
t.Fatalf("Unexpected value for key10 after clear: %v, %v", v, ok)
|
||||
}
|
||||
|
||||
// Test getting only the keys.
|
||||
keys := []string{"key1", "key2", "key3"}
|
||||
values := []string{"value1", "value2", "value3"}
|
||||
for i, k := range keys {
|
||||
c.Set(k, values[i])
|
||||
}
|
||||
k := c.Keys()
|
||||
sort.Strings(keys)
|
||||
sort.Strings(k)
|
||||
if !cmp.Equal(keys, k) {
|
||||
t.Fatalf("Unexpected keys: %v", k)
|
||||
}
|
||||
|
||||
// Test getting only the values.
|
||||
vals := c.Values()
|
||||
sort.Strings(vals)
|
||||
sort.Strings(values)
|
||||
if !cmp.Equal(values, vals) {
|
||||
t.Fatalf("Unexpected values: %v", vals)
|
||||
}
|
||||
|
||||
// Test contents.
|
||||
keys := []string{"key1", "key2", "key3"}
|
||||
for _, k := range keys {
|
||||
c.Set(k, k)
|
||||
}
|
||||
|
||||
items := c.Contents()
|
||||
sort.Strings(keys)
|
||||
res := strings.Split(items, ",")
|
||||
|
||||
@@ -21,7 +21,7 @@ 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{"ipstack"}) + `\b([a-fA-F0-9]{32})\b`)
|
||||
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"ipstack"}) + `\b([a-fA-f0-9]{32})\b`)
|
||||
)
|
||||
|
||||
// Keywords are used for efficiently pre-filtering chunks.
|
||||
|
||||
@@ -20,7 +20,7 @@ type Scanner struct{}
|
||||
var _ detectors.Detector = (*Scanner)(nil)
|
||||
|
||||
var (
|
||||
// possibly always `sq0csp` for secret
|
||||
//possibly always `sq0csp` for secret
|
||||
// and `sq0idb` for app
|
||||
keyPat = regexp.MustCompile(`[\w\-]*sq0i[a-z]{2}-[0-9A-Za-z\-_]{22,43}`)
|
||||
secPat = regexp.MustCompile(`[\w\-]*sq0c[a-z]{2}-[0-9A-Za-z\-_]{40,50}`)
|
||||
@@ -39,6 +39,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
matches := keyPat.FindAllString(dataStr, -1)
|
||||
secMatches := secPat.FindAllString(dataStr, -1)
|
||||
for _, match := range matches {
|
||||
|
||||
for _, secMatch := range secMatches {
|
||||
|
||||
if detectors.IsKnownFalsePositive(strings.ToLower(secMatch), detectors.DefaultFalsePositives, true) {
|
||||
@@ -46,7 +47,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
}
|
||||
|
||||
s := detectors.Result{
|
||||
DetectorType: detectorspb.DetectorType_SquareApp,
|
||||
DetectorType: detectorspb.DetectorType_Square,
|
||||
Raw: []byte(match),
|
||||
Redacted: match,
|
||||
}
|
||||
@@ -71,7 +72,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
// unclear if this version needs to be set or matters, seems to work without, but docs want it
|
||||
// req.Header.Add("Square-Version", "2020-08-12")
|
||||
//req.Header.Add("Square-Version", "2020-08-12")
|
||||
res, err := client.Do(req)
|
||||
if err == nil {
|
||||
res.Body.Close() // The request body is unused.
|
||||
@@ -94,5 +95,5 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
||||
}
|
||||
|
||||
func (s Scanner) Type() detectorspb.DetectorType {
|
||||
return detectorspb.DetectorType_SquareApp
|
||||
return detectorspb.DetectorType_Square
|
||||
}
|
||||
|
||||
@@ -341,9 +341,9 @@ func (e *Engine) detectorWorker(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// lineNumberSupportedSources is a list of sources that support line numbers.
|
||||
// It is stored this way because slice consts are not supported.
|
||||
func lineNumberSupportedSources() []sourcespb.SourceType {
|
||||
// gitSources is a list of sources that utilize the Git source. It is stored this way because slice consts are not
|
||||
// supported.
|
||||
func gitSources() []sourcespb.SourceType {
|
||||
return []sourcespb.SourceType{
|
||||
sourcespb.SourceType_SOURCE_TYPE_GIT,
|
||||
sourcespb.SourceType_SOURCE_TYPE_GITHUB,
|
||||
@@ -352,13 +352,12 @@ func lineNumberSupportedSources() []sourcespb.SourceType {
|
||||
sourcespb.SourceType_SOURCE_TYPE_GERRIT,
|
||||
sourcespb.SourceType_SOURCE_TYPE_GITHUB_UNAUTHENTICATED_ORG,
|
||||
sourcespb.SourceType_SOURCE_TYPE_PUBLIC_GIT,
|
||||
sourcespb.SourceType_SOURCE_TYPE_FILESYSTEM,
|
||||
}
|
||||
}
|
||||
|
||||
// SupportsLineNumbers determines if a line number can be found for a source type.
|
||||
func SupportsLineNumbers(sourceType sourcespb.SourceType) bool {
|
||||
for _, i := range lineNumberSupportedSources() {
|
||||
for _, i := range gitSources() {
|
||||
if i == sourceType {
|
||||
return true
|
||||
}
|
||||
@@ -392,8 +391,6 @@ func FragmentFirstLine(chunk *sources.Chunk) (int64, *int64) {
|
||||
fragmentStart = &metadata.Bitbucket.Line
|
||||
case *source_metadatapb.MetaData_Gerrit:
|
||||
fragmentStart = &metadata.Gerrit.Line
|
||||
case *source_metadatapb.MetaData_Filesystem:
|
||||
fragmentStart = &metadata.Filesystem.Line
|
||||
default:
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
+1
-6
@@ -22,12 +22,7 @@ func (e *Engine) ScanGit(ctx context.Context, c sources.GitConfig) error {
|
||||
git.ScanOptionLogOptions(logOptions),
|
||||
}
|
||||
|
||||
options := &gogit.PlainOpenOptions{
|
||||
DetectDotGit: true,
|
||||
EnableDotGitCommonDir: true,
|
||||
}
|
||||
|
||||
repo, err := gogit.PlainOpenWithOptions(c.RepoPath, options)
|
||||
repo, err := gogit.PlainOpenWithOptions(c.RepoPath, &gogit.PlainOpenOptions{DetectDotGit: true})
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not open repo: %s: %w", c.RepoPath, err)
|
||||
}
|
||||
|
||||
+11
-21
@@ -33,7 +33,6 @@ type Commit struct {
|
||||
Date time.Time
|
||||
Message strings.Builder
|
||||
Diffs []Diff
|
||||
Size int // in bytes
|
||||
}
|
||||
|
||||
// Diff contains the info about a file diff in a commit.
|
||||
@@ -118,7 +117,7 @@ func (c1 *Commit) Equal(c2 *Commit) bool {
|
||||
|
||||
// RepoPath parses the output of the `git log` command for the `source` path.
|
||||
func (c *Parser) RepoPath(ctx context.Context, source string, head string, abbreviatedLog bool, excludedGlobs []string) (chan Commit, error) {
|
||||
args := []string{"-C", source, "log", "-p", "--full-history", "--date=format:%a %b %d %H:%M:%S %Y %z"}
|
||||
args := []string{"-C", source, "log", "-p", "-U5", "--full-history", "--date=format:%a %b %d %H:%M:%S %Y %z"}
|
||||
if abbreviatedLog {
|
||||
args = append(args, "--diff-filter=AM")
|
||||
}
|
||||
@@ -143,7 +142,7 @@ func (c *Parser) RepoPath(ctx context.Context, source string, head string, abbre
|
||||
// Unstaged parses the output of the `git diff` command for the `source` path.
|
||||
func (c *Parser) Unstaged(ctx context.Context, source string) (chan Commit, error) {
|
||||
// Provide the --cached flag to diff to get the diff of the staged changes.
|
||||
args := []string{"-C", source, "diff", "-p", "--cached", "--full-history", "--diff-filter=AM", "--date=format:%a %b %d %H:%M:%S %Y %z", "HEAD"}
|
||||
args := []string{"-C", source, "diff", "-p", "-U5", "--cached", "--full-history", "--diff-filter=AM", "--date=format:%a %b %d %H:%M:%S %Y %z", "HEAD"}
|
||||
|
||||
cmd := exec.Command("git", args...)
|
||||
|
||||
@@ -192,12 +191,9 @@ func (c *Parser) executeCommand(ctx context.Context, cmd *exec.Cmd) (chan Commit
|
||||
|
||||
func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, commitChan chan Commit) {
|
||||
outReader := bufio.NewReader(stdOut)
|
||||
var (
|
||||
currentCommit *Commit
|
||||
currentDiff *Diff
|
||||
recentlyPassedAuthor bool
|
||||
totalLogSize int
|
||||
)
|
||||
var currentCommit *Commit
|
||||
var currentDiff *Diff
|
||||
var recentlyPassedAuthor bool
|
||||
|
||||
defer common.RecoverWithExit(ctx)
|
||||
defer close(commitChan)
|
||||
@@ -214,12 +210,10 @@ func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, commitChan ch
|
||||
// If there is a currentDiff, add it to currentCommit.
|
||||
if currentDiff != nil && currentDiff.Content.Len() > 0 {
|
||||
currentCommit.Diffs = append(currentCommit.Diffs, *currentDiff)
|
||||
currentCommit.Size += currentDiff.Content.Len()
|
||||
}
|
||||
// If there is a currentCommit, send it to the channel.
|
||||
if currentCommit != nil {
|
||||
commitChan <- *currentCommit
|
||||
totalLogSize += currentCommit.Size
|
||||
}
|
||||
// Create a new currentDiff and currentCommit
|
||||
currentDiff = &Diff{}
|
||||
@@ -254,7 +248,6 @@ func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, commitChan ch
|
||||
if totalSize > c.maxCommitSize {
|
||||
oldCommit := currentCommit
|
||||
commitChan <- *currentCommit
|
||||
totalLogSize += currentCommit.Size
|
||||
currentCommit = &Commit{
|
||||
Hash: currentCommit.Hash,
|
||||
Author: currentCommit.Author,
|
||||
@@ -280,8 +273,10 @@ func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, commitChan ch
|
||||
currentDiff.Content.Write(line[1:])
|
||||
case isMinusDiffLine(line):
|
||||
// NoOp. We only care about additions.
|
||||
case (isMessageLine(line) && recentlyPassedAuthor):
|
||||
currentCommit.Message.Write(line[4:])
|
||||
case isMessageLine(line):
|
||||
if recentlyPassedAuthor {
|
||||
currentCommit.Message.Write(line[4:])
|
||||
}
|
||||
case isContextDiffLine(line):
|
||||
currentDiff.Content.Write([]byte("\n"))
|
||||
case isBinaryLine(line):
|
||||
@@ -313,20 +308,15 @@ func (c *Parser) FromReader(ctx context.Context, stdOut io.Reader, commitChan ch
|
||||
break
|
||||
}
|
||||
}
|
||||
cleanupParse(currentCommit, currentDiff, commitChan, &totalLogSize)
|
||||
|
||||
ctx.Logger().V(2).Info("finished parsing git log.", "total_log_size", totalLogSize)
|
||||
cleanupParse(currentCommit, currentDiff, commitChan)
|
||||
}
|
||||
|
||||
func cleanupParse(currentCommit *Commit, currentDiff *Diff, commitChan chan Commit, totalLogSize *int) {
|
||||
func cleanupParse(currentCommit *Commit, currentDiff *Diff, commitChan chan Commit) {
|
||||
if currentDiff != nil && currentDiff.Content.Len() > 0 {
|
||||
currentCommit.Diffs = append(currentCommit.Diffs, *currentDiff)
|
||||
}
|
||||
if currentCommit != nil {
|
||||
commitChan <- *currentCommit
|
||||
if totalLogSize != nil {
|
||||
*totalLogSize += currentCommit.Size
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/mholt/archiver/v4"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||
)
|
||||
@@ -92,6 +91,12 @@ func (d *Archive) openArchive(ctx context.Context, depth int, reader io.Reader,
|
||||
return err
|
||||
}
|
||||
switch archive := format.(type) {
|
||||
case archiver.Extractor:
|
||||
err := archive.Extract(context.WithValue(ctx, depthKey, depth+1), reader, nil, d.extractorHandler(archiveChan))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case archiver.Decompressor:
|
||||
compReader, err := archive.OpenReader(reader)
|
||||
if err != nil {
|
||||
@@ -103,12 +108,6 @@ func (d *Archive) openArchive(ctx context.Context, depth int, reader io.Reader,
|
||||
}
|
||||
newReader := bytes.NewReader(fileBytes)
|
||||
return d.openArchive(ctx, depth+1, newReader, archiveChan)
|
||||
case archiver.Extractor:
|
||||
err := archive.Extract(context.WithValue(ctx, depthKey, depth+1), reader, nil, d.extractorHandler(archiveChan))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Unknown archive type: %s", format.Name())
|
||||
}
|
||||
|
||||
@@ -66,14 +66,9 @@ func ConvertToLegacyJSON(r *detectors.ResultWithMetadata, repoPath string) (*Leg
|
||||
return nil, fmt.Errorf("legacy JSON output can not be used with this source: %s", r.SourceName)
|
||||
}
|
||||
|
||||
options := &gogit.PlainOpenOptions{
|
||||
DetectDotGit: true,
|
||||
EnableDotGitCommonDir: true,
|
||||
}
|
||||
|
||||
// The repo will be needed to gather info needed for the legacy output that
|
||||
// isn't included in the new output format.
|
||||
repo, err := gogit.PlainOpenWithOptions(repoPath, options)
|
||||
// The repo will be needed to gather info needed for the legacy output that isn't included in the new
|
||||
// output format.
|
||||
repo, err := gogit.PlainOpenWithOptions(repoPath, &gogit.PlainOpenOptions{DetectDotGit: true})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not open repo %q: %w", repoPath, err)
|
||||
}
|
||||
|
||||
@@ -984,7 +984,7 @@ const (
|
||||
DetectorType_BscScan DetectorType = 910
|
||||
DetectorType_CoinMarketCap DetectorType = 911
|
||||
DetectorType_Percy DetectorType = 912
|
||||
DetectorType_TinesWebhook DetectorType = 913
|
||||
DetectorType_TinesWebhook DetectorType = 913
|
||||
)
|
||||
|
||||
// Enum value maps for DetectorType.
|
||||
@@ -2811,7 +2811,7 @@ var (
|
||||
"BscScan": 910,
|
||||
"CoinMarketCap": 911,
|
||||
"Percy": 912,
|
||||
"TinesWebhook": 913,
|
||||
"TinesWebhook": 913,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -3176,7 +3176,7 @@ var file_detectors_proto_rawDesc = []byte{
|
||||
0x0a, 0x0b, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a,
|
||||
0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x4c,
|
||||
0x41, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x42, 0x41, 0x53, 0x45, 0x36, 0x34, 0x10,
|
||||
0x02, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x54, 0x46, 0x31, 0x36, 0x10, 0x03, 0x2a, 0x9d, 0x72, 0x0a,
|
||||
0x02, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x54, 0x46, 0x31, 0x36, 0x10, 0x03, 0x2a, 0x96, 0x72, 0x0a,
|
||||
0x0c, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a,
|
||||
0x07, 0x41, 0x6c, 0x69, 0x62, 0x61, 0x62, 0x61, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x4d,
|
||||
0x51, 0x50, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x57, 0x53, 0x10, 0x02, 0x12, 0x09, 0x0a,
|
||||
@@ -4089,13 +4089,12 @@ var file_detectors_proto_rawDesc = []byte{
|
||||
0x07, 0x4d, 0x6f, 0x72, 0x61, 0x6c, 0x69, 0x73, 0x10, 0x8d, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x42,
|
||||
0x73, 0x63, 0x53, 0x63, 0x61, 0x6e, 0x10, 0x8e, 0x07, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x6f, 0x69,
|
||||
0x6e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x43, 0x61, 0x70, 0x10, 0x8f, 0x07, 0x12, 0x0a, 0x0a,
|
||||
0x05, 0x50, 0x65, 0x72, 0x63, 0x79, 0x10, 0x90, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x69, 0x6e,
|
||||
0x65, 0x73, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x10, 0x91, 0x07, 0x42, 0x3d, 0x5a, 0x3b,
|
||||
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,
|
||||
0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x05, 0x50, 0x65, 0x72, 0x63, 0x79, 0x10, 0x90, 0x07, 0x12, 0x0a, 0x0a, 0x05, 0x54, 0x69, 0x6e,
|
||||
0x65, 0x73, 0x10, 0x91, 0x07, 0x42, 0x3d, 0x5a, 0x3b, 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, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f,
|
||||
0x72, 0x73, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -745,7 +745,6 @@ type Filesystem struct {
|
||||
File string `protobuf:"bytes,1,opt,name=file,proto3" json:"file,omitempty"`
|
||||
Link string `protobuf:"bytes,2,opt,name=link,proto3" json:"link,omitempty"`
|
||||
Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
|
||||
Line int64 `protobuf:"varint,4,opt,name=line,proto3" json:"line,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Filesystem) Reset() {
|
||||
@@ -801,13 +800,6 @@ func (x *Filesystem) GetEmail() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Filesystem) GetLine() int64 {
|
||||
if x != nil {
|
||||
return x.Line
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Git struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -2887,296 +2879,295 @@ var file_source_metadata_proto_rawDesc = []byte{
|
||||
0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69,
|
||||
0x6e, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65,
|
||||
0x6d, 0x61, 0x69, 0x6c, 0x22, 0x5e, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74,
|
||||
0x6d, 0x61, 0x69, 0x6c, 0x22, 0x4a, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74,
|
||||
0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d,
|
||||
0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04,
|
||||
0x6c, 0x69, 0x6e, 0x65, 0x22, 0x99, 0x01, 0x0a, 0x03, 0x47, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f,
|
||||
0x6d, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69,
|
||||
0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1e,
|
||||
0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x6c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65,
|
||||
0x22, 0x89, 0x02, 0x0a, 0x06, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x6c,
|
||||
0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72,
|
||||
0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d,
|
||||
0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c,
|
||||
0x69, 0x6e, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12,
|
||||
0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20,
|
||||
0x22, 0x99, 0x01, 0x0a, 0x03, 0x47, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65,
|
||||
0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x89, 0x02, 0x0a,
|
||||
0x06, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x75,
|
||||
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75,
|
||||
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73,
|
||||
0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70,
|
||||
0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69,
|
||||
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d,
|
||||
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x76,
|
||||
0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||
0x1b, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69,
|
||||
0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0xb0, 0x01, 0x0a, 0x06, 0x47, 0x69, 0x74,
|
||||
0x6c, 0x61, 0x62, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c,
|
||||
0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70,
|
||||
0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72,
|
||||
0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d,
|
||||
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18,
|
||||
0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0xd8, 0x01, 0x0a, 0x03,
|
||||
0x47, 0x43, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65,
|
||||
0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69,
|
||||
0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x61, 0x63, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61,
|
||||
0x63, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74,
|
||||
0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65,
|
||||
0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x04, 0x4a, 0x69, 0x72, 0x61, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x69, 0x73, 0x73, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x69, 0x73, 0x73, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e,
|
||||
0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d,
|
||||
0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x22, 0x77, 0x0a, 0x03, 0x4e, 0x50, 0x4d, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
|
||||
0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
|
||||
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x78, 0x0a, 0x04, 0x50, 0x79,
|
||||
0x50, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69,
|
||||
0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65,
|
||||
0x6d, 0x61, 0x69, 0x6c, 0x22, 0x78, 0x0a, 0x02, 0x53, 0x33, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75,
|
||||
0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b,
|
||||
0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d,
|
||||
0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c,
|
||||
0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x97,
|
||||
0x02, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e,
|
||||
0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e,
|
||||
0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63,
|
||||
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49,
|
||||
0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61,
|
||||
0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12,
|
||||
0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x08, 0x20,
|
||||
0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
|
||||
0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0xb0, 0x01, 0x0a,
|
||||
0x06, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69,
|
||||
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1e, 0x0a,
|
||||
0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c,
|
||||
0x69, 0x6e, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22,
|
||||
0xd8, 0x01, 0x0a, 0x03, 0x47, 0x43, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65,
|
||||
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c,
|
||||
0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
|
||||
0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f,
|
||||
0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x64, 0x41, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x63, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x04, 0x61, 0x63, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65,
|
||||
0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x04, 0x4a,
|
||||
0x69, 0x72, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, 0x73, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x05, 0x69, 0x73, 0x73, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74,
|
||||
0x68, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f,
|
||||
0x72, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x77, 0x0a, 0x03, 0x4e, 0x50, 0x4d, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65,
|
||||
0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c,
|
||||
0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69,
|
||||
0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x78,
|
||||
0x0a, 0x04, 0x50, 0x79, 0x50, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61,
|
||||
0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x63,
|
||||
0x6b, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69,
|
||||
0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x78, 0x0a, 0x02, 0x53, 0x33, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69,
|
||||
0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65,
|
||||
0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
|
||||
0x6d, 0x70, 0x22, 0x97, 0x02, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x1d, 0x0a, 0x0a,
|
||||
0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63,
|
||||
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x17, 0x0a, 0x07,
|
||||
0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75,
|
||||
0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d,
|
||||
0x61, 0x69, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74,
|
||||
0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69,
|
||||
0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x96, 0x01, 0x0a,
|
||||
0x06, 0x47, 0x65, 0x72, 0x72, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69,
|
||||
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x1a, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x22, 0x81, 0x01, 0x0a, 0x07, 0x4a, 0x65, 0x6e, 0x6b, 0x69, 0x6e, 0x73, 0x12, 0x21, 0x0a,
|
||||
0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x21, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d,
|
||||
0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x90, 0x02, 0x0a, 0x05, 0x54, 0x65, 0x61, 0x6d, 0x73, 0x12,
|
||||
0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x21,
|
||||
0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d,
|
||||
0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12,
|
||||
0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
|
||||
0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x61, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x17, 0x0a, 0x07, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x22, 0x99, 0x01, 0x0a, 0x0b, 0x41, 0x72, 0x74,
|
||||
0x69, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
|
||||
0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65,
|
||||
0x6d, 0x61, 0x69, 0x6c, 0x22, 0xa8, 0x01, 0x0a, 0x06, 0x53, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61,
|
||||
0x70, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70,
|
||||
0x70, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x69, 0x64, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x69, 0x64, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x63,
|
||||
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x61, 0x63, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x61, 0x63, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22,
|
||||
0x56, 0x0a, 0x15, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f,
|
||||
0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x31, 0x0a, 0x06, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x48, 0x00, 0x52, 0x06, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x42, 0x0a, 0x0a, 0x08, 0x6d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xae, 0x01, 0x0a, 0x0a, 0x53, 0x68, 0x61, 0x72,
|
||||
0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68,
|
||||
0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x69, 0x65, 0x77, 0x73, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x64, 0x6f, 0x63, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x6f, 0x63,
|
||||
0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0xab, 0x01, 0x0a, 0x0b, 0x47, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x44, 0x72, 0x69, 0x76, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x10,
|
||||
0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x62, 0x79,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69,
|
||||
0x66, 0x69, 0x65, 0x64, 0x42, 0x79, 0x22, 0x88, 0x0b, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x44,
|
||||
0x61, 0x74, 0x61, 0x12, 0x2e, 0x0a, 0x05, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x05, 0x61, 0x7a,
|
||||
0x75, 0x72, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x62, 0x69, 0x74, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x74, 0x62, 0x75, 0x63, 0x6b,
|
||||
0x65, 0x74, 0x48, 0x00, 0x52, 0x09, 0x62, 0x69, 0x74, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12,
|
||||
0x37, 0x0a, 0x08, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x63, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x19, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64,
|
||||
0x61, 0x74, 0x61, 0x2e, 0x43, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x43, 0x49, 0x48, 0x00, 0x52, 0x08,
|
||||
0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x63, 0x69, 0x12, 0x3d, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66,
|
||||
0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6f, 0x6e,
|
||||
0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x64, 0x6f, 0x63, 0x6b, 0x65,
|
||||
0x72, 0x68, 0x75, 0x62, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x6f, 0x63,
|
||||
0x6b, 0x65, 0x72, 0x68, 0x75, 0x62, 0x48, 0x00, 0x52, 0x09, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72,
|
||||
0x68, 0x75, 0x62, 0x12, 0x28, 0x0a, 0x03, 0x65, 0x63, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x14, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
|
||||
0x74, 0x61, 0x2e, 0x45, 0x43, 0x52, 0x48, 0x00, 0x52, 0x03, 0x65, 0x63, 0x72, 0x12, 0x28, 0x0a,
|
||||
0x03, 0x67, 0x63, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x43, 0x53,
|
||||
0x48, 0x00, 0x52, 0x03, 0x67, 0x63, 0x73, 0x12, 0x31, 0x0a, 0x06, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x48, 0x00, 0x52, 0x06, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x12, 0x31, 0x0a, 0x06, 0x67, 0x69,
|
||||
0x74, 0x6c, 0x61, 0x62, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x69, 0x74,
|
||||
0x6c, 0x61, 0x62, 0x48, 0x00, 0x52, 0x06, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x12, 0x2b, 0x0a,
|
||||
0x04, 0x6a, 0x69, 0x72, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4a, 0x69,
|
||||
0x72, 0x61, 0x48, 0x00, 0x52, 0x04, 0x6a, 0x69, 0x72, 0x61, 0x12, 0x28, 0x0a, 0x03, 0x6e, 0x70,
|
||||
0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4e, 0x50, 0x4d, 0x48, 0x00, 0x52,
|
||||
0x03, 0x6e, 0x70, 0x6d, 0x12, 0x2b, 0x0a, 0x04, 0x70, 0x79, 0x70, 0x69, 0x18, 0x0c, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x79, 0x50, 0x69, 0x48, 0x00, 0x52, 0x04, 0x70, 0x79, 0x70,
|
||||
0x69, 0x12, 0x25, 0x0a, 0x02, 0x73, 0x33, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e,
|
||||
0x53, 0x33, 0x48, 0x00, 0x52, 0x02, 0x73, 0x33, 0x12, 0x2e, 0x0a, 0x05, 0x73, 0x6c, 0x61, 0x63,
|
||||
0x6b, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x48,
|
||||
0x00, 0x52, 0x05, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x3d, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46,
|
||||
0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x48, 0x00, 0x52, 0x0a, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x28, 0x0a, 0x03, 0x67, 0x69, 0x74, 0x18, 0x10,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65,
|
||||
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, 0x69,
|
||||
0x74, 0x12, 0x2b, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x15, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x3a,
|
||||
0x0a, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64,
|
||||
0x61, 0x74, 0x61, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x65, 0x48, 0x00, 0x52,
|
||||
0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x67, 0x65,
|
||||
0x72, 0x72, 0x69, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x72,
|
||||
0x72, 0x69, 0x74, 0x48, 0x00, 0x52, 0x06, 0x67, 0x65, 0x72, 0x72, 0x69, 0x74, 0x12, 0x34, 0x0a,
|
||||
0x07, 0x6a, 0x65, 0x6e, 0x6b, 0x69, 0x6e, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18,
|
||||
0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
|
||||
0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x96, 0x01, 0x0a, 0x06, 0x47, 0x65, 0x72,
|
||||
0x72, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e,
|
||||
0x65, 0x22, 0x1a, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x81, 0x01,
|
||||
0x0a, 0x07, 0x4a, 0x65, 0x6e, 0x6b, 0x69, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c,
|
||||
0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c,
|
||||
0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x22, 0x90, 0x02, 0x0a, 0x05, 0x54, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63,
|
||||
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x68,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x17, 0x0a, 0x07, 0x75,
|
||||
0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73,
|
||||
0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61,
|
||||
0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b,
|
||||
0x0a, 0x09, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x74, 0x65, 0x61, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74,
|
||||
0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x65,
|
||||
0x61, 0x6d, 0x49, 0x64, 0x22, 0x99, 0x01, 0x0a, 0x0b, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63,
|
||||
0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b,
|
||||
0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a,
|
||||
0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d,
|
||||
0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c,
|
||||
0x22, 0xa8, 0x01, 0x0a, 0x06, 0x53, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x68,
|
||||
0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68,
|
||||
0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d,
|
||||
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
||||
0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x66, 0x61, 0x63, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x66, 0x61, 0x63, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x56, 0x0a, 0x15, 0x50,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x12, 0x31, 0x0a, 0x06, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65,
|
||||
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x48, 0x00, 0x52,
|
||||
0x06, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x42, 0x0a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
|
||||
0x61, 0x74, 0x61, 0x22, 0xae, 0x01, 0x0a, 0x0a, 0x53, 0x68, 0x61, 0x72, 0x65, 0x50, 0x6f, 0x69,
|
||||
0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74,
|
||||
0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x05, 0x76, 0x69, 0x65, 0x77, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x6f, 0x63, 0x69,
|
||||
0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x6f, 0x63, 0x69, 0x64, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65,
|
||||
0x6d, 0x61, 0x69, 0x6c, 0x22, 0xab, 0x01, 0x0a, 0x0b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x44,
|
||||
0x72, 0x69, 0x76, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61,
|
||||
0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74,
|
||||
0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64,
|
||||
0x42, 0x79, 0x22, 0x88, 0x0b, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12,
|
||||
0x2e, 0x0a, 0x05, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16,
|
||||
0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x2e, 0x4a, 0x65, 0x6e, 0x6b, 0x69, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x07, 0x6a, 0x65, 0x6e, 0x6b,
|
||||
0x69, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x05, 0x74, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x15, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x65, 0x61, 0x6d, 0x73, 0x48, 0x00, 0x52, 0x05, 0x74, 0x65,
|
||||
0x61, 0x6d, 0x73, 0x12, 0x40, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x6f,
|
||||
0x72, 0x79, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66,
|
||||
0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61,
|
||||
0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x31, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x18,
|
||||
0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x48, 0x00,
|
||||
0x52, 0x06, 0x73, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x12, 0x5e, 0x0a, 0x15, 0x70, 0x75, 0x62, 0x6c,
|
||||
0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e,
|
||||
0x67, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
|
||||
0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x48,
|
||||
0x00, 0x52, 0x15, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f,
|
||||
0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x3d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72,
|
||||
0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53,
|
||||
0x68, 0x61, 0x72, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x68, 0x61,
|
||||
0x72, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x44, 0x72, 0x69, 0x76, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x44, 0x72, 0x69, 0x76, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x44, 0x72, 0x69, 0x76, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74,
|
||||
0x61, 0x2a, 0x3e, 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12,
|
||||
0x0a, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x70,
|
||||
0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72,
|
||||
0x65, 0x64, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10,
|
||||
0x03, 0x42, 0x43, 0x5a, 0x41, 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, 0x5f, 0x6d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x05, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x12,
|
||||
0x3a, 0x0a, 0x09, 0x62, 0x69, 0x74, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x74, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x48, 0x00,
|
||||
0x52, 0x09, 0x62, 0x69, 0x74, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x37, 0x0a, 0x08, 0x63,
|
||||
0x69, 0x72, 0x63, 0x6c, 0x65, 0x63, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e,
|
||||
0x43, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x43, 0x49, 0x48, 0x00, 0x52, 0x08, 0x63, 0x69, 0x72, 0x63,
|
||||
0x6c, 0x65, 0x63, 0x69, 0x12, 0x3d, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e,
|
||||
0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x6c,
|
||||
0x75, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x75, 0x65,
|
||||
0x6e, 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x68, 0x75, 0x62,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x68,
|
||||
0x75, 0x62, 0x48, 0x00, 0x52, 0x09, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x68, 0x75, 0x62, 0x12,
|
||||
0x28, 0x0a, 0x03, 0x65, 0x63, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45,
|
||||
0x43, 0x52, 0x48, 0x00, 0x52, 0x03, 0x65, 0x63, 0x72, 0x12, 0x28, 0x0a, 0x03, 0x67, 0x63, 0x73,
|
||||
0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x43, 0x53, 0x48, 0x00, 0x52, 0x03,
|
||||
0x67, 0x63, 0x73, 0x12, 0x31, 0x0a, 0x06, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x18, 0x08, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x48, 0x00, 0x52, 0x06,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x12, 0x31, 0x0a, 0x06, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62,
|
||||
0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x48,
|
||||
0x00, 0x52, 0x06, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x12, 0x2b, 0x0a, 0x04, 0x6a, 0x69, 0x72,
|
||||
0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4a, 0x69, 0x72, 0x61, 0x48, 0x00,
|
||||
0x52, 0x04, 0x6a, 0x69, 0x72, 0x61, 0x12, 0x28, 0x0a, 0x03, 0x6e, 0x70, 0x6d, 0x18, 0x0b, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4e, 0x50, 0x4d, 0x48, 0x00, 0x52, 0x03, 0x6e, 0x70, 0x6d,
|
||||
0x12, 0x2b, 0x0a, 0x04, 0x70, 0x79, 0x70, 0x69, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15,
|
||||
0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x2e, 0x50, 0x79, 0x50, 0x69, 0x48, 0x00, 0x52, 0x04, 0x70, 0x79, 0x70, 0x69, 0x12, 0x25, 0x0a,
|
||||
0x02, 0x73, 0x33, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x33, 0x48, 0x00,
|
||||
0x52, 0x02, 0x73, 0x33, 0x12, 0x2e, 0x0a, 0x05, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x18, 0x0e, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x05, 0x73,
|
||||
0x6c, 0x61, 0x63, 0x6b, 0x12, 0x3d, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74,
|
||||
0x65, 0x6d, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73,
|
||||
0x79, 0x73, 0x74, 0x65, 0x6d, 0x48, 0x00, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73,
|
||||
0x74, 0x65, 0x6d, 0x12, 0x28, 0x0a, 0x03, 0x67, 0x69, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x14, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
|
||||
0x74, 0x61, 0x2e, 0x47, 0x69, 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, 0x69, 0x74, 0x12, 0x2b, 0x0a,
|
||||
0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x65,
|
||||
0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x09, 0x62, 0x75,
|
||||
0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e,
|
||||
0x42, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x65, 0x48, 0x00, 0x52, 0x09, 0x62, 0x75, 0x69,
|
||||
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x67, 0x65, 0x72, 0x72, 0x69, 0x74,
|
||||
0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x72, 0x72, 0x69, 0x74, 0x48,
|
||||
0x00, 0x52, 0x06, 0x67, 0x65, 0x72, 0x72, 0x69, 0x74, 0x12, 0x34, 0x0a, 0x07, 0x6a, 0x65, 0x6e,
|
||||
0x6b, 0x69, 0x6e, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4a, 0x65, 0x6e,
|
||||
0x6b, 0x69, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x07, 0x6a, 0x65, 0x6e, 0x6b, 0x69, 0x6e, 0x73, 0x12,
|
||||
0x2e, 0x0a, 0x05, 0x74, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16,
|
||||
0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x2e, 0x54, 0x65, 0x61, 0x6d, 0x73, 0x48, 0x00, 0x52, 0x05, 0x74, 0x65, 0x61, 0x6d, 0x73, 0x12,
|
||||
0x40, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x16,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65,
|
||||
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x6f,
|
||||
0x72, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72,
|
||||
0x79, 0x12, 0x31, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x18, 0x17, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64,
|
||||
0x61, 0x74, 0x61, 0x2e, 0x53, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x06, 0x73, 0x79,
|
||||
0x73, 0x6c, 0x6f, 0x67, 0x12, 0x5e, 0x0a, 0x15, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x45, 0x76,
|
||||
0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x18, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e,
|
||||
0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x15, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x12, 0x3d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x70, 0x6f, 0x69,
|
||||
0x6e, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65,
|
||||
0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x70, 0x6f,
|
||||
0x69, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x44, 0x72, 0x69,
|
||||
0x76, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x44, 0x72, 0x69, 0x76, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x44, 0x72, 0x69, 0x76, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x3e, 0x0a,
|
||||
0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61,
|
||||
0x74, 0x65, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x10, 0x02,
|
||||
0x12, 0x0b, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x03, 0x42, 0x43, 0x5a,
|
||||
0x41, 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, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -852,8 +852,6 @@ func (m *Filesystem) validate(all bool) error {
|
||||
|
||||
// no validation rules for Email
|
||||
|
||||
// no validation rules for Line
|
||||
|
||||
if len(errors) > 0 {
|
||||
return FilesystemMultiError(errors)
|
||||
}
|
||||
|
||||
+6
-13
@@ -86,6 +86,7 @@ func (s *Source) JobID() int64 {
|
||||
|
||||
// Init returns an initialized GitHub source.
|
||||
func (s *Source) Init(aCtx context.Context, name string, jobId, sourceId int64, verify bool, connection *anypb.Any, concurrency int) error {
|
||||
|
||||
s.name = name
|
||||
s.sourceId = sourceId
|
||||
s.jobId = jobId
|
||||
@@ -227,11 +228,7 @@ func (s *Source) Chunks(ctx context.Context, chunksChan chan *sources.Chunk) err
|
||||
}
|
||||
|
||||
func RepoFromPath(path string) (*git.Repository, error) {
|
||||
options := &git.PlainOpenOptions{
|
||||
DetectDotGit: true,
|
||||
EnableDotGitCommonDir: true,
|
||||
}
|
||||
return git.PlainOpenWithOptions(path, options)
|
||||
return git.PlainOpen(path)
|
||||
}
|
||||
|
||||
func CleanOnError(err *error, path string) {
|
||||
@@ -302,11 +299,7 @@ func CloneRepo(ctx context.Context, userInfo *url.Userinfo, gitUrl string, args
|
||||
return "", nil, fmt.Errorf("could not clone repo: %s, %w", safeUrl, err)
|
||||
}
|
||||
|
||||
options := &git.PlainOpenOptions{
|
||||
DetectDotGit: true,
|
||||
EnableDotGitCommonDir: true,
|
||||
}
|
||||
repo, err := git.PlainOpenWithOptions(clonePath, options)
|
||||
repo, err := git.PlainOpen(clonePath)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("could not open cloned repo: %w", err)
|
||||
}
|
||||
@@ -385,7 +378,7 @@ func (s *Git) ScanCommits(ctx context.Context, repo *git.Repository, path string
|
||||
var email, hash, when string
|
||||
email = commit.Author
|
||||
hash = commit.Hash
|
||||
when = commit.Date.UTC().Format("2006-01-02 15:04:05 -0700")
|
||||
when = commit.Date.Format("2006-01-02 15:04:05 -0700")
|
||||
|
||||
// Handle binary files by reading the entire file rather than using the diff.
|
||||
if diff.IsBinary {
|
||||
@@ -493,7 +486,7 @@ func (s *Git) ScanStaged(ctx context.Context, repo *git.Repository, path string,
|
||||
}
|
||||
|
||||
var depth int64
|
||||
reachedBase := false
|
||||
var reachedBase = false
|
||||
|
||||
ctx.Logger().V(1).Info("scanning staged changes", "path", path)
|
||||
for commit := range commitChan {
|
||||
@@ -527,7 +520,7 @@ func (s *Git) ScanStaged(ctx context.Context, repo *git.Repository, path string,
|
||||
var email, hash, when string
|
||||
email = commit.Author
|
||||
hash = commit.Hash
|
||||
when = commit.Date.UTC().Format("2006-01-02 15:04:05 -0700")
|
||||
when = commit.Date.Format("2006-01-02 15:04:05 -0700")
|
||||
|
||||
// Handle binary files by reading the entire file rather than using the diff.
|
||||
if diff.IsBinary {
|
||||
|
||||
@@ -226,7 +226,7 @@ func TestSource_Chunks_Integration(t *testing.T) {
|
||||
"ce62d79908803153ef6e145e042d3e80488ef747-bump": {B: []byte("\n")},
|
||||
// Normally we might expect to see this commit, and we may in the future.
|
||||
// But at the moment we're ignoring any commit unless it contains at least one non-space character.
|
||||
"27fbead3bf883cdb7de9d7825ed401f28f9398f1-slack": {B: []byte("\n\n\nyup, just did that\n\ngithub_lol: \"ffc7e0f9400fb6300167009e42d2f842cd7956e2\"\n\noh, goodness. there's another one!\n")},
|
||||
"27fbead3bf883cdb7de9d7825ed401f28f9398f1-slack": {B: []byte("\n\n\n\nyup, just did that\n\ngithub_lol: \"ffc7e0f9400fb6300167009e42d2f842cd7956e2\"\n\noh, goodness. there's another one!\n")},
|
||||
"8afb0ecd4998b1179e428db5ebbcdc8221214432-slack": {B: []byte("oops might drop a slack token here\n\ngithub_secret=\"369963c1434c377428ca8531fbc46c0c43d037a0\"\n\nyup, just did that\n"), Multi: true},
|
||||
"8fe6f04ef1839e3fc54b5147e3d0e0b7ab971bd5-aws": {B: []byte("blah blaj\n\nthis is the secret: AKIA2E0A8F3B244C9986\n\nokay thank you bye\n"), Multi: true},
|
||||
"84e9c75e388ae3e866e121087ea2dd45a71068f2-aws": {B: []byte("\n\nthis is the secret: [Default]\nAccess key Id: AKIAILE3JG6KMS3HZGCA\nSecret Access Key: 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\n\nokay thank you bye\n"), Multi: false},
|
||||
|
||||
+215
-207
@@ -25,8 +25,6 @@ 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/common"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/giturl"
|
||||
@@ -45,28 +43,28 @@ const (
|
||||
)
|
||||
|
||||
type Source struct {
|
||||
name string
|
||||
githubUser string
|
||||
githubToken string
|
||||
sourceID int64
|
||||
jobID int64
|
||||
verify bool
|
||||
repos []string
|
||||
members []string
|
||||
orgsCache cache.Cache
|
||||
filteredRepoCache *filteredRepoCache
|
||||
memberCache map[string]struct{}
|
||||
git *git.Git
|
||||
scanOptions *git.ScanOptions
|
||||
httpClient *http.Client
|
||||
log logr.Logger
|
||||
conn *sourcespb.GitHub
|
||||
jobPool *errgroup.Group
|
||||
resumeInfoMutex sync.Mutex
|
||||
resumeInfoSlice []string
|
||||
apiClient *github.Client
|
||||
mu sync.Mutex
|
||||
publicMap map[string]source_metadatapb.Visibility
|
||||
name string
|
||||
githubUser string
|
||||
githubToken string
|
||||
sourceID int64
|
||||
jobID int64
|
||||
verify bool
|
||||
repos,
|
||||
orgs,
|
||||
members,
|
||||
includeRepos,
|
||||
ignoreRepos []string
|
||||
git *git.Git
|
||||
scanOptions *git.ScanOptions
|
||||
httpClient *http.Client
|
||||
log logr.Logger
|
||||
conn *sourcespb.GitHub
|
||||
jobPool *errgroup.Group
|
||||
resumeInfoMutex sync.Mutex
|
||||
resumeInfoSlice []string
|
||||
apiClient *github.Client
|
||||
mu sync.Mutex
|
||||
publicMap map[string]source_metadatapb.Visibility
|
||||
sources.Progress
|
||||
}
|
||||
|
||||
@@ -130,67 +128,6 @@ func (s *Source) UserAndToken(ctx context.Context, installationClient *github.Cl
|
||||
return "", "", errors.New("unhandled credential type for token fetch")
|
||||
}
|
||||
|
||||
// filteredRepoCache is a wrapper around cache.Cache that filters out repos
|
||||
// based on include and exclude globs.
|
||||
type filteredRepoCache struct {
|
||||
cache.Cache
|
||||
include, exclude []glob.Glob
|
||||
}
|
||||
|
||||
func (s *Source) newFilteredRepoCache(c cache.Cache, include, exclude []string) *filteredRepoCache {
|
||||
includeGlobs := make([]glob.Glob, 0, len(include))
|
||||
excludeGlobs := make([]glob.Glob, 0, len(exclude))
|
||||
for _, ig := range include {
|
||||
g, err := glob.Compile(ig)
|
||||
if err != nil {
|
||||
s.log.V(1).Info("invalid include glob", "glob", g, "err", err)
|
||||
}
|
||||
includeGlobs = append(includeGlobs, g)
|
||||
}
|
||||
for _, eg := range exclude {
|
||||
g, err := glob.Compile(eg)
|
||||
if err != nil {
|
||||
s.log.V(1).Info("invalid exclude glob", "glob", g, "err", err)
|
||||
}
|
||||
excludeGlobs = append(excludeGlobs, g)
|
||||
}
|
||||
return &filteredRepoCache{Cache: c, include: includeGlobs, exclude: excludeGlobs}
|
||||
}
|
||||
|
||||
// Set overrides the cache.Cache Set method to filter out repos based on
|
||||
// include and exclude globs.
|
||||
func (c *filteredRepoCache) Set(key, val string) {
|
||||
if c.ignoreRepo(key) {
|
||||
return
|
||||
}
|
||||
if !c.includeRepo(key) {
|
||||
return
|
||||
}
|
||||
c.Cache.Set(key, val)
|
||||
}
|
||||
|
||||
func (c *filteredRepoCache) ignoreRepo(s string) bool {
|
||||
for _, g := range c.exclude {
|
||||
if g.Match(s) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *filteredRepoCache) includeRepo(s string) bool {
|
||||
if len(c.include) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, g := range c.include {
|
||||
if g.Match(s) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Init returns an initialized GitHub source.
|
||||
func (s *Source) Init(aCtx context.Context, name string, jobID, sourceID int64, verify bool, connection *anypb.Any, concurrency int) error {
|
||||
s.log = aCtx.Logger()
|
||||
@@ -212,23 +149,10 @@ func (s *Source) Init(aCtx context.Context, name string, jobID, sourceID int64,
|
||||
}
|
||||
s.conn = &conn
|
||||
|
||||
s.filteredRepoCache = s.newFilteredRepoCache(memory.New(), s.conn.IncludeRepos, s.conn.IgnoreRepos)
|
||||
s.memberCache = make(map[string]struct{})
|
||||
|
||||
s.repos = s.conn.Repositories
|
||||
for _, repo := range s.repos {
|
||||
r, err := s.normalizeRepo(repo)
|
||||
if err != nil {
|
||||
aCtx.Logger().Error(err, "invalid repository", "repo", repo)
|
||||
continue
|
||||
}
|
||||
s.filteredRepoCache.Set(r, r)
|
||||
}
|
||||
|
||||
s.orgsCache = memory.New()
|
||||
for _, org := range s.conn.Organizations {
|
||||
s.orgsCache.Set(org, org)
|
||||
}
|
||||
s.orgs = s.conn.Organizations
|
||||
s.includeRepos = s.conn.IncludeRepos
|
||||
s.ignoreRepos = s.conn.IgnoreRepos
|
||||
|
||||
// Head or base should only be used with incoming webhooks
|
||||
if (len(s.conn.Head) > 0 || len(s.conn.Base) > 0) && len(s.repos) != 1 {
|
||||
@@ -335,67 +259,24 @@ func (s *Source) visibilityOf(repoURL string) (visibility source_metadatapb.Visi
|
||||
return
|
||||
}
|
||||
|
||||
// Chunks emits chunks of bytes over a channel.
|
||||
func (s *Source) Chunks(ctx context.Context, chunksChan chan *sources.Chunk) error {
|
||||
apiEndpoint := s.conn.Endpoint
|
||||
if len(apiEndpoint) == 0 || endsWithGithub.MatchString(apiEndpoint) {
|
||||
apiEndpoint = "https://api.github.com"
|
||||
}
|
||||
|
||||
installationClient, err := s.enumerate(ctx, apiEndpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.scan(ctx, installationClient, chunksChan)
|
||||
}
|
||||
|
||||
func (s *Source) enumerate(ctx context.Context, apiEndpoint string) (*github.Client, error) {
|
||||
var installationClient *github.Client
|
||||
var err error
|
||||
|
||||
switch cred := s.conn.GetCredential().(type) {
|
||||
case *sourcespb.GitHub_Unauthenticated:
|
||||
s.enumerateUnauthenticated(ctx)
|
||||
case *sourcespb.GitHub_Token:
|
||||
if err = s.enumerateWithToken(ctx, apiEndpoint, cred.Token); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case *sourcespb.GitHub_GithubApp:
|
||||
if installationClient, err = s.enumerateWithApp(ctx, apiEndpoint, cred.GithubApp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
// TODO: move this error to Init
|
||||
return nil, errors.Errorf("Invalid configuration given for source. Name: %s, Type: %s", s.name, s.Type())
|
||||
}
|
||||
|
||||
s.repos = s.filteredRepoCache.Values()
|
||||
s.log.Info("Completed enumeration", "num_repos", len(s.repos), "num_orgs", s.orgsCache.Count(), "num_members", len(s.memberCache))
|
||||
|
||||
// We must sort the repos so we can resume later if necessary.
|
||||
sort.Strings(s.repos)
|
||||
return installationClient, nil
|
||||
}
|
||||
|
||||
func (s *Source) enumerateUnauthenticated(ctx context.Context) {
|
||||
s.apiClient = github.NewClient(s.httpClient)
|
||||
if s.orgsCache.Count() > unauthGithubOrgRateLimt {
|
||||
if len(s.orgs) > unauthGithubOrgRateLimt {
|
||||
s.log.Info("You may experience rate limiting when using the unauthenticated GitHub api. Consider using an authenticated scan instead.")
|
||||
}
|
||||
|
||||
for _, org := range s.orgsCache.Keys() {
|
||||
if err := s.getReposByOrg(ctx, org); err != nil {
|
||||
s.log.Error(err, "error fetching repos for org or user")
|
||||
for _, org := range s.orgs {
|
||||
logger := s.log.WithValues("org", org)
|
||||
if err := s.addRepos(ctx, org, s.getReposByOrg); err != nil {
|
||||
logger.Error(err, "error fetching repos for org or user")
|
||||
}
|
||||
|
||||
// We probably don't need to do this, since getting repos by org makes more sense?
|
||||
if err := s.getReposByUser(ctx, org); err != nil {
|
||||
s.log.Error(err, "error fetching repos for org or user")
|
||||
if err := s.addRepos(ctx, org, s.getReposByUser); err != nil {
|
||||
logger.Error(err, "error fetching repos for org or user")
|
||||
}
|
||||
|
||||
if s.conn.ScanUsers {
|
||||
s.log.Info("Enumerating unauthenticated does not support scanning organization members")
|
||||
logger.Info("Enumerating unauthenticated does not support scanning organization members")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,11 +333,11 @@ func (s *Source) enumerateWithToken(ctx context.Context, apiEndpoint, token stri
|
||||
break
|
||||
}
|
||||
|
||||
if s.orgsCache.Count() > 0 {
|
||||
if len(s.orgs) > 0 {
|
||||
specificScope = true
|
||||
for _, org := range s.orgsCache.Keys() {
|
||||
for _, org := range s.orgs {
|
||||
logger := s.log.WithValues("org", org)
|
||||
if err := s.getReposByOrg(ctx, org); err != nil {
|
||||
if err := s.addRepos(ctx, org, s.getReposByOrg); err != nil {
|
||||
logger.Error(err, "error fetching repos for org")
|
||||
}
|
||||
|
||||
@@ -472,7 +353,7 @@ func (s *Source) enumerateWithToken(ctx context.Context, apiEndpoint, token stri
|
||||
|
||||
// If no scope was provided, enumerate them.
|
||||
if !specificScope {
|
||||
if err := s.getReposByUser(ctx, ghUser.GetLogin()); err != nil {
|
||||
if err := s.addRepos(ctx, ghUser.GetLogin(), s.getReposByUser); err != nil {
|
||||
s.log.Error(err, "error fetching repos by user")
|
||||
}
|
||||
|
||||
@@ -484,14 +365,14 @@ func (s *Source) enumerateWithToken(ctx context.Context, apiEndpoint, token stri
|
||||
s.addOrgsByUser(ctx, ghUser.GetLogin())
|
||||
}
|
||||
|
||||
for _, org := range s.orgsCache.Keys() {
|
||||
for _, org := range s.orgs {
|
||||
logger := s.log.WithValues("org", org)
|
||||
if err := s.getReposByOrg(ctx, org); err != nil {
|
||||
if err := s.addRepos(ctx, org, s.getReposByOrg); err != nil {
|
||||
logger.Error(err, "error fetching repos by org")
|
||||
}
|
||||
|
||||
if err := s.getReposByUser(ctx, ghUser.GetLogin()); err != nil {
|
||||
logger.Error(err, "error fetching repos by user")
|
||||
if err := s.addRepos(ctx, ghUser.GetLogin(), s.getReposByUser); err != nil {
|
||||
logger.Error(err, "error fetching repos for user", "user", ghUser.GetLogin())
|
||||
}
|
||||
|
||||
if s.conn.ScanUsers {
|
||||
@@ -504,15 +385,16 @@ func (s *Source) enumerateWithToken(ctx context.Context, apiEndpoint, token stri
|
||||
|
||||
// If we enabled ScanUsers above, we've already added the gists for the current user and users from the orgs.
|
||||
// So if we don't have ScanUsers enabled, add the user gists as normal.
|
||||
if err := s.addUserGistsToCache(ctx, ghUser.GetLogin()); err != nil {
|
||||
if err := s.addGistsByUser(ctx, ghUser.GetLogin()); err != nil {
|
||||
s.log.Error(err, "error fetching gists", "user", ghUser.GetLogin())
|
||||
}
|
||||
|
||||
s.log.Info("Completed enumeration", "num_repos", len(s.repos), "num_orgs", len(s.orgs), "num_members", len(s.members))
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.conn.ScanUsers {
|
||||
s.log.Info("Adding repos", "members", len(s.members), "orgs", s.orgsCache.Count())
|
||||
s.log.Info("Adding repos", "members", len(s.members), "orgs", len(s.orgs))
|
||||
s.addReposForMembers(ctx)
|
||||
return nil
|
||||
}
|
||||
@@ -576,10 +458,10 @@ func (s *Source) enumerateWithApp(ctx context.Context, apiEndpoint string, app *
|
||||
s.log.Info("Scanning repos", "org_members", len(s.members))
|
||||
for _, member := range s.members {
|
||||
logger := s.log.WithValues("member", member)
|
||||
if err := s.getReposByUser(ctx, member); err != nil {
|
||||
if err = s.addGistsByUser(ctx, member); err != nil {
|
||||
logger.Error(err, "error fetching gists by user")
|
||||
}
|
||||
if err := s.getReposByUser(ctx, member); err != nil {
|
||||
if err := s.addRepos(ctx, member, s.getReposByUser); err != nil {
|
||||
logger.Error(err, "error fetching repos by user")
|
||||
}
|
||||
}
|
||||
@@ -589,6 +471,40 @@ func (s *Source) enumerateWithApp(ctx context.Context, apiEndpoint string, app *
|
||||
return installationClient, nil
|
||||
}
|
||||
|
||||
// Chunks emits chunks of bytes over a channel.
|
||||
func (s *Source) Chunks(ctx context.Context, chunksChan chan *sources.Chunk) error {
|
||||
apiEndpoint := s.conn.Endpoint
|
||||
if len(apiEndpoint) == 0 || endsWithGithub.MatchString(apiEndpoint) {
|
||||
apiEndpoint = "https://api.github.com"
|
||||
}
|
||||
|
||||
var installationClient *github.Client
|
||||
var err error
|
||||
|
||||
switch cred := s.conn.GetCredential().(type) {
|
||||
case *sourcespb.GitHub_Unauthenticated:
|
||||
s.enumerateUnauthenticated(ctx)
|
||||
case *sourcespb.GitHub_Token:
|
||||
if err = s.enumerateWithToken(ctx, apiEndpoint, cred.Token); err != nil {
|
||||
return err
|
||||
}
|
||||
case *sourcespb.GitHub_GithubApp:
|
||||
if installationClient, err = s.enumerateWithApp(ctx, apiEndpoint, cred.GithubApp); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
// TODO: move this error to Init
|
||||
return errors.Errorf("Invalid configuration given for source. Name: %s, Type: %s", s.name, s.Type())
|
||||
}
|
||||
|
||||
s.normalizeRepos(ctx)
|
||||
|
||||
// We must sort the repos so we can resume later if necessary.
|
||||
sort.Strings(s.repos)
|
||||
|
||||
return s.scan(ctx, installationClient, chunksChan)
|
||||
}
|
||||
|
||||
func (s *Source) scan(ctx context.Context, installationClient *github.Client, chunksChan chan *sources.Chunk) error {
|
||||
var scanned uint64
|
||||
|
||||
@@ -598,12 +514,12 @@ func (s *Source) scan(ctx context.Context, installationClient *github.Client, ch
|
||||
reposToScan, progressIndexOffset := sources.FilterReposToResume(s.repos, s.GetProgress().EncodedResumeInfo)
|
||||
s.repos = reposToScan
|
||||
|
||||
scanErrs := sources.NewScanErrors()
|
||||
// Setup scan options if it wasn't provided.
|
||||
if s.scanOptions == nil {
|
||||
s.scanOptions = &git.ScanOptions{}
|
||||
}
|
||||
|
||||
scanErrs := sources.NewScanErrors()
|
||||
for i, repoURL := range s.repos {
|
||||
i, repoURL := i, repoURL
|
||||
s.jobPool.Go(func() error {
|
||||
@@ -632,10 +548,6 @@ func (s *Source) scan(ctx context.Context, installationClient *github.Client, ch
|
||||
var err error
|
||||
|
||||
path, repo, err = s.cloneRepo(ctx, repoURL, installationClient)
|
||||
if err != nil {
|
||||
scanErrs.Add(err)
|
||||
}
|
||||
|
||||
defer os.RemoveAll(path)
|
||||
if err != nil {
|
||||
scanErrs.Add(fmt.Errorf("error cloning repo %s: %w", repoURL, err))
|
||||
@@ -741,9 +653,10 @@ func (s *Source) handleRateLimit(errIn error, res *github.Response) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Source) getReposByOrg(ctx context.Context, org string) error {
|
||||
func (s *Source) getReposByOrg(ctx context.Context, org string) ([]string, error) {
|
||||
logger := s.log.WithValues("org", org)
|
||||
|
||||
var repos []string
|
||||
opts := &github.RepositoryListByOrgOptions{
|
||||
ListOptions: github.ListOptions{
|
||||
PerPage: defaultPagination,
|
||||
@@ -760,7 +673,7 @@ func (s *Source) getReposByOrg(ctx context.Context, org string) error {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not list repos for org %s: %w", org, err)
|
||||
return nil, fmt.Errorf("could not list repos for org %s: %w", org, err)
|
||||
}
|
||||
if len(someRepos) == 0 || res == nil {
|
||||
break
|
||||
@@ -768,29 +681,48 @@ func (s *Source) getReposByOrg(ctx context.Context, org string) error {
|
||||
|
||||
logger.V(2).Info("Listed repos", "page", opts.Page, "last_page", res.LastPage)
|
||||
for _, r := range someRepos {
|
||||
if s.ignoreRepo(r.GetFullName()) {
|
||||
continue
|
||||
}
|
||||
if !s.includeRepo(r.GetFullName()) {
|
||||
continue
|
||||
}
|
||||
|
||||
numRepos++
|
||||
if r.GetFork() {
|
||||
numForks++
|
||||
if !s.conn.IncludeForks {
|
||||
continue
|
||||
}
|
||||
numForks++
|
||||
}
|
||||
s.filteredRepoCache.Set(r.GetFullName(), r.GetCloneURL())
|
||||
numRepos++
|
||||
repos = append(repos, r.GetCloneURL())
|
||||
}
|
||||
if res.NextPage == 0 {
|
||||
break
|
||||
}
|
||||
opts.Page = res.NextPage
|
||||
}
|
||||
|
||||
logger.V(2).Info("found repos", "total", numRepos, "forks", numForks)
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
func (s *Source) addRepos(ctx context.Context, entity string, getRepos func(context.Context, string) ([]string, error)) error {
|
||||
repos, err := getRepos(ctx, entity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Add the repos to the set of repos.
|
||||
for _, repo := range repos {
|
||||
common.AddStringSliceItem(repo, &s.repos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Source) getReposByUser(ctx context.Context, user string) error {
|
||||
func (s *Source) getReposByUser(ctx context.Context, user string) ([]string, error) {
|
||||
var repos []string
|
||||
opts := &github.RepositoryListOptions{
|
||||
ListOptions: github.ListOptions{
|
||||
PerPage: defaultPagination,
|
||||
PerPage: 50,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -804,7 +736,7 @@ func (s *Source) getReposByUser(ctx context.Context, user string) error {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not list repos for user %s: %w", user, err)
|
||||
return nil, fmt.Errorf("could not list repos for user %s: %w", user, err)
|
||||
}
|
||||
if res == nil {
|
||||
break
|
||||
@@ -812,24 +744,64 @@ func (s *Source) getReposByUser(ctx context.Context, user string) error {
|
||||
|
||||
logger.V(2).Info("Listed repos", "page", opts.Page, "last_page", res.LastPage)
|
||||
for _, r := range someRepos {
|
||||
if r.GetFork() && !s.conn.IncludeForks {
|
||||
if s.ignoreRepo(r.GetFullName()) {
|
||||
continue
|
||||
}
|
||||
if !s.includeRepo(r.GetFullName()) {
|
||||
continue
|
||||
}
|
||||
|
||||
s.filteredRepoCache.Set(r.GetFullName(), r.GetCloneURL())
|
||||
if r.GetFork() && !s.conn.IncludeForks {
|
||||
continue
|
||||
}
|
||||
repos = append(repos, r.GetCloneURL())
|
||||
}
|
||||
if res.NextPage == 0 {
|
||||
break
|
||||
}
|
||||
opts.Page = res.NextPage
|
||||
}
|
||||
|
||||
return nil
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
// addUserGistsToCache collects all the gist urls for a given user,
|
||||
// and adds them to the filteredRepoCache.
|
||||
func (s *Source) addUserGistsToCache(ctx context.Context, user string) error {
|
||||
func (s *Source) includeRepo(r string) bool {
|
||||
if len(s.includeRepos) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
logger := s.log.WithValues("repo", r)
|
||||
for _, include := range s.includeRepos {
|
||||
g, err := glob.Compile(include)
|
||||
if err != nil {
|
||||
logger.V(2).Info("invalid glob", "glob", include, "error", err)
|
||||
continue
|
||||
}
|
||||
if g.Match(r) {
|
||||
logger.V(2).Info("including repo")
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Source) ignoreRepo(r string) bool {
|
||||
logger := s.log.WithValues("repo", r)
|
||||
for _, ignore := range s.ignoreRepos {
|
||||
g, err := glob.Compile(ignore)
|
||||
if err != nil {
|
||||
logger.V(2).Info("invalid glob", "glob", ignore, "error", err)
|
||||
continue
|
||||
}
|
||||
if g.Match(r) {
|
||||
logger.V(2).Info("ignoring repo")
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Source) getGistsByUser(ctx context.Context, user string) ([]string, error) {
|
||||
var gistURLs []string
|
||||
gistOpts := &github.GistListOptions{}
|
||||
logger := s.log.WithValues("user", user)
|
||||
for {
|
||||
@@ -841,10 +813,10 @@ func (s *Source) addUserGistsToCache(ctx context.Context, user string) error {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not list gists for user %s: %w", user, err)
|
||||
return nil, fmt.Errorf("could not list gists for user %s: %w", user, err)
|
||||
}
|
||||
for _, gist := range gists {
|
||||
s.filteredRepoCache.Set(gist.GetID(), gist.GetGitPullURL())
|
||||
gistURLs = append(gistURLs, gist.GetGitPullURL())
|
||||
}
|
||||
if res == nil || res.NextPage == 0 {
|
||||
break
|
||||
@@ -852,6 +824,18 @@ func (s *Source) addUserGistsToCache(ctx context.Context, user string) error {
|
||||
logger.V(2).Info("Listed gists", "page", gistOpts.Page, "last_page", res.LastPage)
|
||||
gistOpts.Page = res.NextPage
|
||||
}
|
||||
return gistURLs, nil
|
||||
}
|
||||
|
||||
func (s *Source) addGistsByUser(ctx context.Context, user string) error {
|
||||
gists, err := s.getGistsByUser(ctx, user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// add the gists to the set of repos
|
||||
for _, gist := range gists {
|
||||
common.AddStringSliceItem(gist, &s.repos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -879,11 +863,10 @@ func (s *Source) addMembersByApp(ctx context.Context, installationClient *github
|
||||
}
|
||||
|
||||
func (s *Source) addReposByApp(ctx context.Context) error {
|
||||
// Authenticated enumeration of repos.
|
||||
// Authenticated enumeration of repos
|
||||
opts := &github.ListOptions{
|
||||
PerPage: defaultPagination,
|
||||
}
|
||||
|
||||
for {
|
||||
someRepos, res, err := s.apiClient.Apps.ListRepos(ctx, opts)
|
||||
if err == nil {
|
||||
@@ -903,10 +886,9 @@ func (s *Source) addReposByApp(ctx context.Context) error {
|
||||
if r.GetFork() && !s.conn.IncludeForks {
|
||||
continue
|
||||
}
|
||||
s.filteredRepoCache.Set(r.GetFullName(), r.GetCloneURL())
|
||||
s.log.V(2).Info("Enumerated repo", "repo", r.GetFullName())
|
||||
common.AddStringSliceItem(r.GetCloneURL(), &s.repos)
|
||||
s.log.V(2).Info("Enumerated repo", "repo", r.GetCloneURL())
|
||||
}
|
||||
|
||||
if res.NextPage == 0 {
|
||||
break
|
||||
}
|
||||
@@ -954,8 +936,8 @@ func (s *Source) addAllVisibleOrgs(ctx context.Context) {
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
s.orgsCache.Set(name, name)
|
||||
s.log.V(2).Info("adding organization for repository enumeration", "id", org.ID, "name", name)
|
||||
s.log.V(2).Info("adding organization for repository enumeration", "id", org.ID, "org", name)
|
||||
common.AddStringSliceItem(name, &s.orgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -982,10 +964,13 @@ func (s *Source) addOrgsByUser(ctx context.Context, user string) {
|
||||
}
|
||||
logger.V(2).Info("Listed orgs", "page", orgOpts.Page, "last_page", resp.LastPage)
|
||||
for _, org := range orgs {
|
||||
if org.Login == nil {
|
||||
var name string
|
||||
if org.Login != nil {
|
||||
name = *org.Login
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
s.orgsCache.Set(*org.Login, *org.Login)
|
||||
common.AddStringSliceItem(name, &s.orgs)
|
||||
}
|
||||
if resp.NextPage == 0 {
|
||||
break
|
||||
@@ -1023,9 +1008,7 @@ func (s *Source) addMembersByOrg(ctx context.Context, org string) error {
|
||||
if usr == nil || *usr == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := s.memberCache[*usr]; !ok {
|
||||
s.memberCache[*usr] = struct{}{}
|
||||
}
|
||||
common.AddStringSliceItem(*usr, &s.members)
|
||||
}
|
||||
if res.NextPage == 0 {
|
||||
break
|
||||
@@ -1038,23 +1021,48 @@ func (s *Source) addMembersByOrg(ctx context.Context, org string) error {
|
||||
|
||||
func (s *Source) addReposForMembers(ctx context.Context) {
|
||||
s.log.Info("Fetching repos from members", "members", len(s.members))
|
||||
for member := range s.memberCache {
|
||||
if err := s.addUserGistsToCache(ctx, member); err != nil {
|
||||
for _, member := range s.members {
|
||||
if err := s.addGistsByUser(ctx, member); err != nil {
|
||||
s.log.Info("Unable to fetch gists by user", "user", member, "error", err)
|
||||
}
|
||||
if err := s.getReposByUser(ctx, member); err != nil {
|
||||
if err := s.addRepos(ctx, member, s.getReposByUser); err != nil {
|
||||
s.log.Info("Unable to fetch repos by user", "user", member, "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Source) normalizeRepo(repo string) (string, error) {
|
||||
// If there's a '/', assume it's a URL and try to normalize it.
|
||||
if strings.ContainsRune(repo, '/') {
|
||||
return giturl.NormalizeGithubRepo(repo)
|
||||
func (s *Source) normalizeRepos(ctx context.Context) {
|
||||
// TODO: Add check/fix for repos that are missing scheme
|
||||
normalizedRepos := map[string]struct{}{}
|
||||
for _, repo := range s.repos {
|
||||
// If there's a '/', assume it's a URL and try to normalize it.
|
||||
if strings.ContainsRune(repo, '/') {
|
||||
repoNormalized, err := giturl.NormalizeGithubRepo(repo)
|
||||
if err != nil {
|
||||
s.log.Info("Repo not in expected format", "repo", repo, "error", err)
|
||||
continue
|
||||
}
|
||||
normalizedRepos[repoNormalized] = struct{}{}
|
||||
continue
|
||||
}
|
||||
// Otherwise, assume it's a user and enumerate repositories and gists.
|
||||
if repos, err := s.getReposByUser(ctx, repo); err == nil {
|
||||
for _, repo := range repos {
|
||||
normalizedRepos[repo] = struct{}{}
|
||||
}
|
||||
}
|
||||
if gists, err := s.getGistsByUser(ctx, repo); err == nil {
|
||||
for _, gist := range gists {
|
||||
normalizedRepos[gist] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("no repositories found for %s", repo)
|
||||
// Replace s.repos.
|
||||
s.repos = s.repos[:0]
|
||||
for key := range normalizedRepos {
|
||||
s.repos = append(s.repos, key)
|
||||
}
|
||||
}
|
||||
|
||||
// setProgressCompleteWithRepo calls the s.SetProgressComplete after safely setting up the encoded resume info string.
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/cache/memory"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/credentialspb"
|
||||
@@ -53,12 +52,10 @@ func TestSource_Token(t *testing.T) {
|
||||
}
|
||||
|
||||
s := Source{
|
||||
conn: conn,
|
||||
httpClient: common.SaneHttpClient(),
|
||||
log: logr.Discard(),
|
||||
memberCache: map[string]struct{}{},
|
||||
conn: conn,
|
||||
httpClient: common.SaneHttpClient(),
|
||||
log: logr.Discard(),
|
||||
}
|
||||
s.filteredRepoCache = s.newFilteredRepoCache(memory.New(), nil, nil)
|
||||
|
||||
installationClient, err := s.enumerateWithApp(ctx, "https://api.github.com", conn.GetGithubApp())
|
||||
assert.NoError(t, err)
|
||||
@@ -529,7 +526,7 @@ func TestSource_paginateGists(t *testing.T) {
|
||||
}
|
||||
chunksCh := make(chan *sources.Chunk, 5)
|
||||
go func() {
|
||||
s.addUserGistsToCache(ctx, tt.user)
|
||||
s.addGistsByUser(ctx, tt.user)
|
||||
chunksCh <- &sources.Chunk{}
|
||||
}()
|
||||
var wantedRepo string
|
||||
@@ -545,11 +542,11 @@ func TestSource_paginateGists(t *testing.T) {
|
||||
|
||||
func gistsCheckFunc(expected string, minRepos int, s *Source) sources.ChunkFunc {
|
||||
return func(chunk *sources.Chunk) error {
|
||||
if minRepos != 0 && minRepos > s.filteredRepoCache.Count() {
|
||||
if minRepos != 0 && minRepos > len(s.repos) {
|
||||
return fmt.Errorf("didn't find enough repos. expected: %d, got :%d", minRepos, len(s.repos))
|
||||
}
|
||||
if expected != "" {
|
||||
for _, repo := range s.filteredRepoCache.Values() {
|
||||
for _, repo := range s.repos {
|
||||
if repo == expected {
|
||||
return nil
|
||||
}
|
||||
@@ -562,8 +559,8 @@ func gistsCheckFunc(expected string, minRepos int, s *Source) sources.ChunkFunc
|
||||
|
||||
func basicCheckFunc(minOrg, minRepo int, wantChunk *sources.Chunk, s *Source) sources.ChunkFunc {
|
||||
return func(chunk *sources.Chunk) error {
|
||||
if minOrg != 0 && minOrg > s.orgsCache.Count() {
|
||||
return fmt.Errorf("incorrect number of orgs. expected at least: %d, got %d", minOrg, s.orgsCache.Count())
|
||||
if minOrg != 0 && minOrg > len(s.orgs) {
|
||||
return fmt.Errorf("incorrect number of orgs. expected at least: %d, got %d", minOrg, len(s.orgs))
|
||||
}
|
||||
if minRepo != 0 && minRepo > len(s.repos) {
|
||||
return fmt.Errorf("incorrect number of repos. expected at least: %d, got %d", minRepo, len(s.repos))
|
||||
|
||||
@@ -6,22 +6,20 @@ import (
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-github/v42/github"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"gopkg.in/h2non/gock.v1"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/cache/memory"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/credentialspb"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/sourcespb"
|
||||
@@ -67,23 +65,17 @@ func TestAddReposByOrg(t *testing.T) {
|
||||
Get("/orgs/super-secret-org/repos").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{
|
||||
{"clone_url": "https://github.com/super-secret-repo.git", "full_name": "super-secret-repo"},
|
||||
{"clone_url": "https://github.com/super-secret-repo2.git", "full_name": "secret/super-secret-repo2"},
|
||||
{"clone_url": "super-secret-repo", "name": "super-secret-repo"},
|
||||
{"clone_url": "super-secret-repo2", "full_name": "secret/super-secret-repo2"},
|
||||
})
|
||||
|
||||
s := initTestSource(&sourcespb.GitHub{
|
||||
Credential: &sourcespb.GitHub_Token{
|
||||
Token: "super secret token",
|
||||
},
|
||||
IncludeRepos: nil,
|
||||
IgnoreRepos: []string{"secret/super-*-repo2"},
|
||||
})
|
||||
s := initTestSource(nil)
|
||||
s.ignoreRepos = []string{"secret/super-*-repo2"}
|
||||
// gock works here because github.NewClient is using the default HTTP Transport
|
||||
err := s.getReposByOrg(context.TODO(), "super-secret-org")
|
||||
err := s.addRepos(context.TODO(), "super-secret-org", s.getReposByOrg)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, s.filteredRepoCache.Count())
|
||||
ok := s.filteredRepoCache.Exists("super-secret-repo")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 1, len(s.repos))
|
||||
assert.Equal(t, []string{"super-secret-repo"}, s.repos)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
@@ -94,26 +86,21 @@ func TestAddReposByOrg_IncludeRepos(t *testing.T) {
|
||||
Get("/orgs/super-secret-org/repos").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{
|
||||
{"clone_url": "https://github.com/super-secret-repo.git", "full_name": "secret/super-secret-repo"},
|
||||
{"clone_url": "https://github.com/super-secret-repo2.git", "full_name": "secret/super-secret-repo2"},
|
||||
{"clone_url": "https://github.com/super-secret-repo2.git", "full_name": "secret/not-super-secret-repo"},
|
||||
{"clone_url": "super-secret-repo", "full_name": "secret/super-secret-repo"},
|
||||
{"clone_url": "super-secret-repo2", "full_name": "secret/super-secret-repo2"},
|
||||
{"clone_url": "super-secret-repo2", "full_name": "secret/not-super-secret-repo"},
|
||||
})
|
||||
|
||||
s := initTestSource(&sourcespb.GitHub{
|
||||
Credential: &sourcespb.GitHub_Token{
|
||||
Token: "super secret token",
|
||||
},
|
||||
IncludeRepos: []string{"secret/super*"},
|
||||
src := &sourcespb.GitHub{
|
||||
Organizations: []string{"super-secret-org"},
|
||||
})
|
||||
}
|
||||
s := initTestSource(src)
|
||||
s.includeRepos = []string{"secret/super*"}
|
||||
// gock works here because github.NewClient is using the default HTTP Transport
|
||||
err := s.getReposByOrg(context.TODO(), "super-secret-org")
|
||||
err := s.addRepos(context.TODO(), "super-secret-org", s.getReposByOrg)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, s.filteredRepoCache.Count())
|
||||
ok := s.filteredRepoCache.Exists("secret/super-secret-repo")
|
||||
assert.True(t, ok)
|
||||
ok = s.filteredRepoCache.Exists("secret/super-secret-repo2")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 2, len(s.repos))
|
||||
assert.Equal(t, []string{"super-secret-repo", "super-secret-repo2"}, s.repos)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
@@ -124,21 +111,16 @@ func TestAddReposByUser(t *testing.T) {
|
||||
Get("/users/super-secret-user/repos").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{
|
||||
{"clone_url": "https://github.com/super-secret-repo.git", "full_name": "super-secret-repo"},
|
||||
{"clone_url": "https://github.com/super-secret-repo2.git", "full_name": "secret/super-secret-repo2"},
|
||||
{"clone_url": "super-secret-repo", "name": "super-secret-repo"},
|
||||
{"clone_url": "super-secret-repo2", "full_name": "secret/super-secret-repo2"},
|
||||
})
|
||||
|
||||
s := initTestSource(&sourcespb.GitHub{
|
||||
Credential: &sourcespb.GitHub_Token{
|
||||
Token: "super secret token",
|
||||
},
|
||||
IgnoreRepos: []string{"secret/super-secret-repo2"},
|
||||
})
|
||||
err := s.getReposByUser(context.TODO(), "super-secret-user")
|
||||
s := initTestSource(nil)
|
||||
s.ignoreRepos = []string{"secret/super-secret-repo2"}
|
||||
err := s.addRepos(context.TODO(), "super-secret-user", s.getReposByUser)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, s.filteredRepoCache.Count())
|
||||
ok := s.filteredRepoCache.Exists("super-secret-repo")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 1, len(s.repos))
|
||||
assert.Equal(t, []string{"super-secret-repo"}, s.repos)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
@@ -148,36 +130,13 @@ func TestAddGistsByUser(t *testing.T) {
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/gists").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"git_pull_url": "https://githug.com/super-secret-gist.git", "id": "super-secret-gist"}})
|
||||
JSON([]map[string]string{{"git_pull_url": "super-secret-gist"}})
|
||||
|
||||
s := initTestSource(nil)
|
||||
err := s.addUserGistsToCache(context.TODO(), "super-secret-user")
|
||||
err := s.addGistsByUser(context.TODO(), "super-secret-user")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, s.filteredRepoCache.Count())
|
||||
ok := s.filteredRepoCache.Exists("super-secret-gist")
|
||||
assert.True(t, ok)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
func TestAddMembersByOrg(t *testing.T) {
|
||||
defer gock.Off()
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/orgs/org1/members").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{
|
||||
{"login": "testman1"},
|
||||
{"login": "testman2"},
|
||||
})
|
||||
|
||||
s := initTestSource(nil)
|
||||
err := s.addMembersByOrg(context.TODO(), "org1")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(s.memberCache))
|
||||
_, ok := s.memberCache["testman1"]
|
||||
assert.True(t, ok)
|
||||
_, ok = s.memberCache["testman2"]
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 1, len(s.repos))
|
||||
assert.Equal(t, []string{"super-secret-gist"}, s.repos)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
@@ -202,13 +161,8 @@ func TestAddMembersByApp(t *testing.T) {
|
||||
s := initTestSource(nil)
|
||||
err := s.addMembersByApp(context.TODO(), github.NewClient(nil))
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, len(s.memberCache))
|
||||
_, ok := s.memberCache["ssm1"]
|
||||
assert.True(t, ok)
|
||||
_, ok = s.memberCache["ssm2"]
|
||||
assert.True(t, ok)
|
||||
_, ok = s.memberCache["ssm3"]
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 3, len(s.members))
|
||||
assert.Equal(t, []string{"ssm1", "ssm2", "ssm3"}, s.members)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
@@ -220,19 +174,16 @@ func TestAddReposByApp(t *testing.T) {
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"repositories": []map[string]string{
|
||||
{"clone_url": "https://github/ssr1.git", "full_name": "ssr1"},
|
||||
{"clone_url": "https://github/ssr2.git", "full_name": "ssr2"},
|
||||
{"clone_url": "ssr1"},
|
||||
{"clone_url": "ssr2"},
|
||||
},
|
||||
})
|
||||
|
||||
s := initTestSource(nil)
|
||||
err := s.addReposByApp(context.TODO())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, s.filteredRepoCache.Count())
|
||||
ok := s.filteredRepoCache.Exists("ssr1")
|
||||
assert.True(t, ok)
|
||||
ok = s.filteredRepoCache.Exists("ssr2")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 2, len(s.repos))
|
||||
assert.Equal(t, []string{"ssr1", "ssr2"}, s.repos)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
@@ -250,9 +201,8 @@ func TestAddOrgsByUser(t *testing.T) {
|
||||
|
||||
s := initTestSource(nil)
|
||||
s.addOrgsByUser(context.TODO(), "super-secret-user")
|
||||
assert.Equal(t, 1, s.orgsCache.Count())
|
||||
ok := s.orgsCache.Exists("sso2")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 1, len(s.orgs))
|
||||
assert.Equal(t, []string{"sso2"}, s.orgs)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
@@ -263,15 +213,30 @@ func TestNormalizeRepos(t *testing.T) {
|
||||
name string
|
||||
setup func()
|
||||
repos []string
|
||||
expected map[string]struct{}
|
||||
wantErr bool
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "repo url",
|
||||
setup: func() {},
|
||||
repos: []string{"https://github.com/super-secret-user/super-secret-repo"},
|
||||
expected: map[string]struct{}{
|
||||
"https://github.com/super-secret-user/super-secret-repo.git": {},
|
||||
name: "repo url",
|
||||
setup: func() {},
|
||||
repos: []string{"https://github.com/super-secret-user/super-secret-repo"},
|
||||
expected: []string{"https://github.com/super-secret-user/super-secret-repo.git"},
|
||||
},
|
||||
{
|
||||
name: "username with gists",
|
||||
setup: func() {
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/gists").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"git_pull_url": "https://github.com/super-secret-user/super-secret-gist.git"}})
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/repos").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"clone_url": "https://github.com/super-secret-user/super-secret-repo.git"}})
|
||||
},
|
||||
repos: []string{"super-secret-user"},
|
||||
expected: []string{
|
||||
"https://github.com/super-secret-user/super-secret-repo.git",
|
||||
"https://github.com/super-secret-user/super-secret-gist.git",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -285,15 +250,13 @@ func TestNormalizeRepos(t *testing.T) {
|
||||
Reply(404)
|
||||
},
|
||||
repos: []string{"not-found"},
|
||||
expected: map[string]struct{}{},
|
||||
wantErr: true,
|
||||
expected: []string{},
|
||||
},
|
||||
{
|
||||
name: "unexpected format",
|
||||
setup: func() {},
|
||||
repos: []string{"/foo/"},
|
||||
expected: map[string]struct{}{},
|
||||
wantErr: true,
|
||||
expected: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -302,25 +265,16 @@ func TestNormalizeRepos(t *testing.T) {
|
||||
defer gock.Off()
|
||||
tt.setup()
|
||||
s := initTestSource(nil)
|
||||
s.repos = tt.repos
|
||||
|
||||
got, err := s.normalizeRepo(tt.repos[0])
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("normalizeRepo() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != "" {
|
||||
for k := range tt.expected {
|
||||
assert.Equal(t, got, k)
|
||||
}
|
||||
}
|
||||
res := make(map[string]struct{}, s.filteredRepoCache.Count())
|
||||
for _, v := range s.filteredRepoCache.Keys() {
|
||||
res[v] = struct{}{}
|
||||
}
|
||||
s.normalizeRepos(context.TODO())
|
||||
assert.Equal(t, len(tt.expected), len(s.repos))
|
||||
// sort and compare
|
||||
sort.Slice(tt.expected, func(i, j int) bool { return tt.expected[i] < tt.expected[j] })
|
||||
sort.Slice(s.repos, func(i, j int) bool { return s.repos[i] < s.repos[j] })
|
||||
assert.Equal(t, tt.expected, s.repos)
|
||||
|
||||
if got == "" && !cmp.Equal(res, tt.expected) {
|
||||
t.Errorf("normalizeRepo() got = %v, want %v", s.repos, tt.expected)
|
||||
}
|
||||
assert.True(t, gock.IsDone())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -342,15 +296,13 @@ func TestEnumerateUnauthenticated(t *testing.T) {
|
||||
gock.New("https://api.github.com").
|
||||
Get("/orgs/super-secret-org/repos").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"clone_url": "https://github.com/super-secret-repo.git", "full_name": "super-secret-repo"}})
|
||||
JSON([]map[string]string{{"clone_url": "super-secret-repo"}})
|
||||
|
||||
s := initTestSource(nil)
|
||||
s.orgsCache = memory.New()
|
||||
s.orgsCache.Set("super-secret-org", "super-secret-org")
|
||||
s.orgs = []string{"super-secret-org"}
|
||||
s.enumerateUnauthenticated(context.TODO())
|
||||
assert.Equal(t, 1, s.filteredRepoCache.Count())
|
||||
ok := s.filteredRepoCache.Exists("super-secret-repo")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 1, len(s.repos))
|
||||
assert.Equal(t, []string{"super-secret-repo"}, s.repos)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
@@ -365,157 +317,21 @@ func TestEnumerateWithToken(t *testing.T) {
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/repos").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"clone_url": "https://github.com/super-secret-repo.git", "full_name": "super-secret-repo"}})
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/user/orgs").
|
||||
MatchParam("per_page", "100").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"clone_url": "https://github.com/super-secret-repo.git", "full_name": "super-secret-repo"}})
|
||||
JSON([]map[string]string{{"clone_url": "super-secret-repo"}})
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/gists").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"git_pull_url": "https://github.com/super-secret-gist.git", "id": "super-secret-gist"}})
|
||||
JSON([]map[string]string{{"clone_url": ""}})
|
||||
|
||||
s := initTestSource(nil)
|
||||
err := s.enumerateWithToken(context.TODO(), "https://api.github.com", "token")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, s.filteredRepoCache.Count())
|
||||
ok := s.filteredRepoCache.Exists("super-secret-repo")
|
||||
assert.True(t, ok)
|
||||
ok = s.filteredRepoCache.Exists("super-secret-gist")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 2, len(s.repos))
|
||||
assert.Equal(t, []string{"super-secret-repo", ""}, s.repos)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
func BenchmarkEnumerateWithToken(b *testing.B) {
|
||||
defer gock.Off()
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/user").
|
||||
Reply(200).
|
||||
JSON(map[string]string{"login": "super-secret-user"})
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/repos").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"clone_url": "https://github.com/super-secret-repo.git"}})
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/user/orgs").
|
||||
MatchParam("per_page", "100").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"clone_url": "https://github.com/super-secret-repo.git"}})
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/gists").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"git_pull_url": "https://github.com/super-secret-gist.git"}})
|
||||
|
||||
s := initTestSource(nil)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = s.enumerateWithToken(context.TODO(), "https://api.github.com", "token")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnumerate(t *testing.T) {
|
||||
defer gock.Off()
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/user").
|
||||
Reply(200).
|
||||
JSON(map[string]string{"login": "super-secret-user"})
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/repos").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"clone_url": "https://github.com/super-secret-repo.git", "full_name": "super-secret-repo"}})
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/user/orgs").
|
||||
MatchParam("per_page", "100").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"clone_url": "https://github.com/super-secret-repo.git", "full_name": "super-secret-repo"}})
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/gists").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"git_pull_url": "https://github.com/super-secret-gist.git", "id": "super-secret-gist"}})
|
||||
|
||||
s := initTestSource(&sourcespb.GitHub{
|
||||
Credential: &sourcespb.GitHub_Token{
|
||||
Token: "super secret token",
|
||||
},
|
||||
})
|
||||
|
||||
_, err := s.enumerate(context.TODO(), "https://api.github.com")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, s.filteredRepoCache.Count())
|
||||
ok := s.filteredRepoCache.Exists("super-secret-repo")
|
||||
assert.True(t, ok)
|
||||
ok = s.filteredRepoCache.Exists("super-secret-gist")
|
||||
assert.True(t, ok)
|
||||
assert.True(t, gock.IsDone())
|
||||
}
|
||||
|
||||
func setupMocks(b *testing.B) {
|
||||
b.Helper()
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/user").
|
||||
Reply(200).
|
||||
JSON(map[string]string{"login": "super-secret-user"})
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/repos").
|
||||
Reply(200).
|
||||
JSON(mockRepos())
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/user/orgs").
|
||||
MatchParam("per_page", "100").
|
||||
Reply(200).
|
||||
JSON([]map[string]string{{"clone_url": "https://github.com/super-secret-repo.git"}})
|
||||
|
||||
gock.New("https://api.github.com").
|
||||
Get("/users/super-secret-user/gists").
|
||||
Reply(200).
|
||||
JSON(mockGists())
|
||||
}
|
||||
|
||||
func mockRepos() []map[string]string {
|
||||
res := make([]map[string]string, 0, 10000)
|
||||
for i := 0; i < 10000; i++ {
|
||||
res = append(res, map[string]string{"clone_url": fmt.Sprintf("https://githu/super-secret-repo-%d.git", i)})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func mockGists() []map[string]string {
|
||||
res := make([]map[string]string, 0, 100)
|
||||
for i := 0; i < 100; i++ {
|
||||
res = append(res, map[string]string{"git_pull_url": fmt.Sprintf("https://githu/super-secret-gist-%d.git", i)})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func BenchmarkEnumerate(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
s := initTestSource(&sourcespb.GitHub{
|
||||
Credential: &sourcespb.GitHub_Token{
|
||||
Token: "super secret token",
|
||||
},
|
||||
})
|
||||
setupMocks(b)
|
||||
|
||||
b.StartTimer()
|
||||
_, _ = s.enumerate(context.TODO(), "https://api.github.com")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnumerateWithToken_IncludeRepos(t *testing.T) {
|
||||
defer gock.Off()
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ type ChunkFunc func(chunk *Chunk) error
|
||||
|
||||
var MatchError = errors.New("chunk doesn't match")
|
||||
|
||||
func HandleTestChannel(chunksCh chan *Chunk, cf ChunkFunc) error {
|
||||
func HandleTestChannel(chunksCh chan *Chunk, cf ChunkFunc, timeout int) error {
|
||||
for {
|
||||
select {
|
||||
case gotChunk := <-chunksCh:
|
||||
@@ -22,8 +22,8 @@ func HandleTestChannel(chunksCh chan *Chunk, cf ChunkFunc) error {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case <-time.After(10 * time.Second):
|
||||
return fmt.Errorf("no new chunks received after 10 seconds")
|
||||
case <-time.After(time.Duration(timeout) * time.Second):
|
||||
return fmt.Errorf("no new chunks received after %d seconds", timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,6 @@ message Filesystem {
|
||||
string file = 1;
|
||||
string link = 2;
|
||||
string email = 3;
|
||||
int64 line = 4;
|
||||
}
|
||||
|
||||
message Git {
|
||||
|
||||
Reference in New Issue
Block a user