updated Dao.CanAccessRecord to return the invalid filter or db error
This commit is contained in:
		
							parent
							
								
									7bb33d4453
								
							
						
					
					
						commit
						3d3fe5c614
					
				| 
						 | 
					@ -230,7 +230,7 @@ func (dao *Dao) FindFirstRecordByData(
 | 
				
			||||||
// If the limit argument is <= 0, no limit is applied to the query and
 | 
					// If the limit argument is <= 0, no limit is applied to the query and
 | 
				
			||||||
// all matching records are returned.
 | 
					// all matching records are returned.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// NB Don't put untrusted user input in the filter string as it
 | 
					// NB! Don't put untrusted user input in the filter string as it
 | 
				
			||||||
// practically would allow the users to inject their own custom filter.
 | 
					// practically would allow the users to inject their own custom filter.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Example:
 | 
					// Example:
 | 
				
			||||||
| 
						 | 
					@ -294,7 +294,7 @@ func (dao *Dao) FindRecordsByFilter(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FindFirstRecordByFilter returns the first available record matching the provided filter.
 | 
					// FindFirstRecordByFilter returns the first available record matching the provided filter.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// NB Don't put untrusted user input in the filter string as it
 | 
					// NB! Don't put untrusted user input in the filter string as it
 | 
				
			||||||
// practically would allow the users to inject their own custom filter.
 | 
					// practically would allow the users to inject their own custom filter.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Example:
 | 
					// Example:
 | 
				
			||||||
| 
						 | 
					@ -484,30 +484,35 @@ func (dao *Dao) SuggestUniqueAuthRecordUsername(
 | 
				
			||||||
// CanAccessRecord checks if a record is allowed to be accessed by the
 | 
					// CanAccessRecord checks if a record is allowed to be accessed by the
 | 
				
			||||||
// specified requestData and accessRule.
 | 
					// specified requestData and accessRule.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Always return false on invalid access rule or db error.
 | 
					// Rule and db checks are ignored in case requestData.Admin is set.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The returned error indicate that something unexpected happened during
 | 
				
			||||||
 | 
					// the check (eg. invalid rule or db error).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The method always return false on invalid access rule or db error.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Example:
 | 
					// Example:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//	requestData := apis.RequestData(c /* echo.Context */)
 | 
					//	requestData := apis.RequestData(c /* echo.Context */)
 | 
				
			||||||
//	record, _ := dao.FindRecordById("example", "RECORD_ID")
 | 
					//	record, _ := dao.FindRecordById("example", "RECORD_ID")
 | 
				
			||||||
//	// custom rule
 | 
					 | 
				
			||||||
//	// or use one of the record collection's, eg. record.Collection().ViewRule
 | 
					 | 
				
			||||||
//	rule := types.Pointer("@request.auth.id != '' || status = 'public'")
 | 
					//	rule := types.Pointer("@request.auth.id != '' || status = 'public'")
 | 
				
			||||||
 | 
					//	// ... or use one of the record collection's rule, eg. record.Collection().ViewRule
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//	canAccess := dao.CanAccessRecord(record, requestData, rule)
 | 
					//	if ok, _ := dao.CanAccessRecord(record, requestData, rule); ok { ... }
 | 
				
			||||||
func (dao *Dao) CanAccessRecord(record *models.Record, requestData *models.RequestData, accessRule *string) bool {
 | 
					func (dao *Dao) CanAccessRecord(record *models.Record, requestData *models.RequestData, accessRule *string) (bool, error) {
 | 
				
			||||||
	if requestData.Admin != nil {
 | 
						if requestData.Admin != nil {
 | 
				
			||||||
		// admins can access everything
 | 
							// admins can access everything
 | 
				
			||||||
		return true
 | 
							return true, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if accessRule == nil {
 | 
						if accessRule == nil {
 | 
				
			||||||
		// only admins can access this record
 | 
							// only admins can access this record
 | 
				
			||||||
		return false
 | 
							return false, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if *accessRule == "" {
 | 
						if *accessRule == "" {
 | 
				
			||||||
		return true // empty public rule, aka. everyone can access
 | 
							// empty public rule, aka. everyone can access
 | 
				
			||||||
 | 
							return true, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var exists bool
 | 
						var exists bool
 | 
				
			||||||
| 
						 | 
					@ -520,16 +525,16 @@ func (dao *Dao) CanAccessRecord(record *models.Record, requestData *models.Reque
 | 
				
			||||||
	resolver := resolvers.NewRecordFieldResolver(dao, record.Collection(), requestData, true)
 | 
						resolver := resolvers.NewRecordFieldResolver(dao, record.Collection(), requestData, true)
 | 
				
			||||||
	expr, err := search.FilterData(*accessRule).BuildExpr(resolver)
 | 
						expr, err := search.FilterData(*accessRule).BuildExpr(resolver)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return false
 | 
							return false, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	resolver.UpdateQuery(query)
 | 
						resolver.UpdateQuery(query)
 | 
				
			||||||
	query.AndWhere(expr)
 | 
						query.AndWhere(expr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := query.Limit(1).Row(&exists); err != nil {
 | 
						if err := query.Limit(1).Row(&exists); err != nil && !errors.Is(err, sql.ErrNoRows) {
 | 
				
			||||||
		return false
 | 
							return false, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return exists
 | 
						return exists, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SaveRecord persists the provided Record model in the database.
 | 
					// SaveRecord persists the provided Record model in the database.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -607,6 +607,7 @@ func TestCanAccessRecord(t *testing.T) {
 | 
				
			||||||
		requestData *models.RequestData
 | 
							requestData *models.RequestData
 | 
				
			||||||
		rule        *string
 | 
							rule        *string
 | 
				
			||||||
		expected    bool
 | 
							expected    bool
 | 
				
			||||||
 | 
							expectError bool
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"as admin with nil rule",
 | 
								"as admin with nil rule",
 | 
				
			||||||
| 
						 | 
					@ -616,6 +617,7 @@ func TestCanAccessRecord(t *testing.T) {
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			nil,
 | 
								nil,
 | 
				
			||||||
			true,
 | 
								true,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"as admin with non-empty rule",
 | 
								"as admin with non-empty rule",
 | 
				
			||||||
| 
						 | 
					@ -625,6 +627,17 @@ func TestCanAccessRecord(t *testing.T) {
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			types.Pointer("id = ''"), // the filter rule should be ignored
 | 
								types.Pointer("id = ''"), // the filter rule should be ignored
 | 
				
			||||||
			true,
 | 
								true,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"as admin with invalid rule",
 | 
				
			||||||
 | 
								record,
 | 
				
			||||||
 | 
								&models.RequestData{
 | 
				
			||||||
 | 
									Admin: admin,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								types.Pointer("id ?!@ 1"), // the filter rule should be ignored
 | 
				
			||||||
 | 
								true,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"as guest with nil rule",
 | 
								"as guest with nil rule",
 | 
				
			||||||
| 
						 | 
					@ -632,13 +645,23 @@ func TestCanAccessRecord(t *testing.T) {
 | 
				
			||||||
			&models.RequestData{},
 | 
								&models.RequestData{},
 | 
				
			||||||
			nil,
 | 
								nil,
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"as guest with empty rule",
 | 
								"as guest with empty rule",
 | 
				
			||||||
			nil,
 | 
								record,
 | 
				
			||||||
			&models.RequestData{},
 | 
								&models.RequestData{},
 | 
				
			||||||
			types.Pointer(""),
 | 
								types.Pointer(""),
 | 
				
			||||||
			true,
 | 
								true,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"as guest with invalid rule",
 | 
				
			||||||
 | 
								record,
 | 
				
			||||||
 | 
								&models.RequestData{},
 | 
				
			||||||
 | 
								types.Pointer("id ?!@ 1"),
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"as guest with mismatched rule",
 | 
								"as guest with mismatched rule",
 | 
				
			||||||
| 
						 | 
					@ -646,6 +669,7 @@ func TestCanAccessRecord(t *testing.T) {
 | 
				
			||||||
			&models.RequestData{},
 | 
								&models.RequestData{},
 | 
				
			||||||
			types.Pointer("@request.auth.id != ''"),
 | 
								types.Pointer("@request.auth.id != ''"),
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"as guest with matched rule",
 | 
								"as guest with matched rule",
 | 
				
			||||||
| 
						 | 
					@ -655,6 +679,7 @@ func TestCanAccessRecord(t *testing.T) {
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			types.Pointer("@request.auth.id != '' || @request.data.test = 1"),
 | 
								types.Pointer("@request.auth.id != '' || @request.data.test = 1"),
 | 
				
			||||||
			true,
 | 
								true,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"as auth record with nil rule",
 | 
								"as auth record with nil rule",
 | 
				
			||||||
| 
						 | 
					@ -664,15 +689,27 @@ func TestCanAccessRecord(t *testing.T) {
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			nil,
 | 
								nil,
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"as auth record with empty rule",
 | 
								"as auth record with empty rule",
 | 
				
			||||||
			nil,
 | 
								record,
 | 
				
			||||||
			&models.RequestData{
 | 
								&models.RequestData{
 | 
				
			||||||
				AuthRecord: authRecord,
 | 
									AuthRecord: authRecord,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			types.Pointer(""),
 | 
								types.Pointer(""),
 | 
				
			||||||
			true,
 | 
								true,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"as auth record with invalid rule",
 | 
				
			||||||
 | 
								record,
 | 
				
			||||||
 | 
								&models.RequestData{
 | 
				
			||||||
 | 
									AuthRecord: authRecord,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								types.Pointer("id ?!@ 1"),
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
 | 
								true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"as auth record with mismatched rule",
 | 
								"as auth record with mismatched rule",
 | 
				
			||||||
| 
						 | 
					@ -683,6 +720,7 @@ func TestCanAccessRecord(t *testing.T) {
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			types.Pointer("@request.auth.id != '' && @request.data.test > 1"),
 | 
								types.Pointer("@request.auth.id != '' && @request.data.test > 1"),
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"as auth record with matched rule",
 | 
								"as auth record with matched rule",
 | 
				
			||||||
| 
						 | 
					@ -693,15 +731,21 @@ func TestCanAccessRecord(t *testing.T) {
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			types.Pointer("@request.auth.id != '' && @request.data.test > 1"),
 | 
								types.Pointer("@request.auth.id != '' && @request.data.test > 1"),
 | 
				
			||||||
			true,
 | 
								true,
 | 
				
			||||||
 | 
								false,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, s := range scenarios {
 | 
						for _, s := range scenarios {
 | 
				
			||||||
		result := app.Dao().CanAccessRecord(s.record, s.requestData, s.rule)
 | 
							result, err := app.Dao().CanAccessRecord(s.record, s.requestData, s.rule)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if result != s.expected {
 | 
							if result != s.expected {
 | 
				
			||||||
			t.Errorf("[%s] Expected %v, got %v", s.name, s.expected, result)
 | 
								t.Errorf("[%s] Expected %v, got %v", s.name, s.expected, result)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							hasErr := err != nil
 | 
				
			||||||
 | 
							if hasErr != s.expectError {
 | 
				
			||||||
 | 
								t.Errorf("[%s] Expected hasErr %v, got %v (%v)", s.name, s.expectError, hasErr, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										4
									
								
								go.mod
								
								
								
								
							| 
						 | 
					@ -4,7 +4,7 @@ go 1.18
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/AlecAivazis/survey/v2 v2.3.7
 | 
						github.com/AlecAivazis/survey/v2 v2.3.7
 | 
				
			||||||
	github.com/aws/aws-sdk-go v1.44.298
 | 
						github.com/aws/aws-sdk-go v1.44.299
 | 
				
			||||||
	github.com/disintegration/imaging v1.6.2
 | 
						github.com/disintegration/imaging v1.6.2
 | 
				
			||||||
	github.com/domodwyer/mailyak/v3 v3.6.0
 | 
						github.com/domodwyer/mailyak/v3 v3.6.0
 | 
				
			||||||
	github.com/dop251/goja v0.0.0-20230707174833-636fdf960de1
 | 
						github.com/dop251/goja v0.0.0-20230707174833-636fdf960de1
 | 
				
			||||||
| 
						 | 
					@ -79,7 +79,7 @@ require (
 | 
				
			||||||
	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
 | 
						golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
 | 
				
			||||||
	google.golang.org/api v0.130.0 // indirect
 | 
						google.golang.org/api v0.130.0 // indirect
 | 
				
			||||||
	google.golang.org/appengine v1.6.7 // indirect
 | 
						google.golang.org/appengine v1.6.7 // indirect
 | 
				
			||||||
	google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130 // indirect
 | 
						google.golang.org/genproto/googleapis/rpc v0.0.0-20230710151506-e685fd7b542b // indirect
 | 
				
			||||||
	google.golang.org/grpc v1.56.2 // indirect
 | 
						google.golang.org/grpc v1.56.2 // indirect
 | 
				
			||||||
	google.golang.org/protobuf v1.31.0 // indirect
 | 
						google.golang.org/protobuf v1.31.0 // indirect
 | 
				
			||||||
	lukechampine.com/uint128 v1.3.0 // indirect
 | 
						lukechampine.com/uint128 v1.3.0 // indirect
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										10
									
								
								go.sum
								
								
								
								
							| 
						 | 
					@ -773,8 +773,8 @@ github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4
 | 
				
			||||||
github.com/aws/aws-sdk-go v1.44.156/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 | 
					github.com/aws/aws-sdk-go v1.44.156/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 | 
				
			||||||
github.com/aws/aws-sdk-go v1.44.245/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 | 
					github.com/aws/aws-sdk-go v1.44.245/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 | 
				
			||||||
github.com/aws/aws-sdk-go v1.44.284/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 | 
					github.com/aws/aws-sdk-go v1.44.284/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 | 
				
			||||||
github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g=
 | 
					github.com/aws/aws-sdk-go v1.44.299 h1:HVD9lU4CAFHGxleMJp95FV/sRhtg7P4miHD1v88JAQk=
 | 
				
			||||||
github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 | 
					github.com/aws/aws-sdk-go v1.44.299/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 | 
				
			||||||
github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
 | 
					github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
 | 
				
			||||||
github.com/aws/aws-sdk-go-v2 v1.18.1 h1:+tefE750oAb7ZQGzla6bLkOwfcQCEtC5y2RqoqCeqKo=
 | 
					github.com/aws/aws-sdk-go-v2 v1.18.1 h1:+tefE750oAb7ZQGzla6bLkOwfcQCEtC5y2RqoqCeqKo=
 | 
				
			||||||
github.com/aws/aws-sdk-go-v2 v1.18.1/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
 | 
					github.com/aws/aws-sdk-go-v2 v1.18.1/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
 | 
				
			||||||
| 
						 | 
					@ -3091,7 +3091,7 @@ google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOl
 | 
				
			||||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
 | 
					google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
 | 
				
			||||||
google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY=
 | 
					google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY=
 | 
				
			||||||
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64=
 | 
					google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64=
 | 
				
			||||||
google.golang.org/genproto v0.0.0-20230629202037-9506855d4529 h1:9JucMWR7sPvCxUFd6UsOUNmA5kCcWOfORaT3tpAsKQs=
 | 
					google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8=
 | 
				
			||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8=
 | 
					google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8=
 | 
				
			||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
 | 
					google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
 | 
				
			||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
 | 
					google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
 | 
				
			||||||
| 
						 | 
					@ -3102,8 +3102,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.
 | 
				
			||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
 | 
					google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
 | 
				
			||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
 | 
					google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
 | 
				
			||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
 | 
					google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
 | 
				
			||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130 h1:2FZP5XuJY9zQyGM5N0rtovnoXjiMUEIUMvw0m9wlpLc=
 | 
					google.golang.org/genproto/googleapis/rpc v0.0.0-20230710151506-e685fd7b542b h1:BC7Q0uXfp6VFXnNWp5RqATIN/viqCGkqBO8+HxzH/jY=
 | 
				
			||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:8mL13HKkDa+IuJ8yruA3ci0q+0vsUz4m//+ottjwS5o=
 | 
					google.golang.org/genproto/googleapis/rpc v0.0.0-20230710151506-e685fd7b542b/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
 | 
				
			||||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 | 
					google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 | 
				
			||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 | 
					google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 | 
				
			||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 | 
					google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue