Files
seaweedFS/weed/s3api/s3_token_differentiation_test.go
Chris Lu 1261e93ef2 fix: comprehensive go vet error fixes and add CI enforcement (#7861)
* fix: use keyed fields in struct literals

- Replace unsafe reflect.StringHeader/SliceHeader with safe unsafe.String/Slice (weed/query/sqltypes/unsafe.go)
- Add field names to Type_ScalarType struct literals (weed/mq/schema/schema_builder.go)
- Add Duration field name to FlexibleDuration struct literals across test files
- Add field names to bson.D struct literals (weed/filer/mongodb/mongodb_store_kv.go)

Fixes go vet warnings about unkeyed struct literals.

* fix: remove unreachable code

- Remove unreachable return statements after infinite for loops
- Remove unreachable code after if/else blocks where all paths return
- Simplify recursive logic by removing unnecessary for loop (inode_to_path.go)
- Fix Type_ScalarType literal to use enum value directly (schema_builder.go)
- Call onCompletionFn on stream error (subscribe_session.go)

Files fixed:
- weed/query/sqltypes/unsafe.go
- weed/mq/schema/schema_builder.go
- weed/mq/client/sub_client/connect_to_sub_coordinator.go
- weed/filer/redis3/ItemList.go
- weed/mq/client/agent_client/subscribe_session.go
- weed/mq/broker/broker_grpc_pub_balancer.go
- weed/mount/inode_to_path.go
- weed/util/skiplist/name_list.go

* fix: avoid copying lock values in protobuf messages

- Use proto.Merge() instead of direct assignment to avoid copying sync.Mutex in S3ApiConfiguration (iamapi_server.go)
- Add explicit comments noting that channel-received values are already copies before taking addresses (volume_grpc_client_to_master.go)

The protobuf messages contain sync.Mutex fields from the message state, which should not be copied.
Using proto.Merge() properly merges messages without copying the embedded mutex.

* fix: correct byte array size for uint32 bit shift operations

The generateAccountId() function only needs 4 bytes to create a uint32 value.
Changed from allocating 8 bytes to 4 bytes to match the actual usage.

This fixes go vet warning about shifting 8-bit values (bytes) by more than 8 bits.

* fix: ensure context cancellation on all error paths

In broker_client_subscribe.go, ensure subscriberCancel() is called on all error return paths:
- When stream creation fails
- When partition assignment fails
- When sending initialization message fails

This prevents context leaks when an error occurs during subscriber creation.

* fix: ensure subscriberCancel called for CreateFreshSubscriber stream.Send error

Ensure subscriberCancel() is called when stream.Send fails in CreateFreshSubscriber.

* ci: add go vet step to prevent future lint regressions

- Add go vet step to GitHub Actions workflow
- Filter known protobuf lock warnings (MessageState sync.Mutex)
  These are expected in generated protobuf code and are safe
- Prevents accumulation of go vet errors in future PRs
- Step runs before build to catch issues early

* fix: resolve remaining syntax and logic errors in vet fixes

- Fixed syntax errors in filer_sync.go caused by missing closing braces
- Added missing closing brace for if block and function
- Synchronized fixes to match previous commits on branch

* fix: add missing return statements to daemon functions

- Add 'return false' after infinite loops in filer_backup.go and filer_meta_backup.go
- Satisfies declared bool return type signatures
- Maintains consistency with other daemon functions (runMaster, runFilerSynchronize, runWorker)
- While unreachable, explicitly declares the return satisfies function signature contract

* fix: add nil check for onCompletionFn in SubscribeMessageRecord

- Check if onCompletionFn is not nil before calling it
- Prevents potential panic if nil function is passed
- Matches pattern used in other callback functions

* docs: clarify unreachable return statements in daemon functions

- Add comments documenting that return statements satisfy function signature
- Explains that these returns follow infinite loops and are unreachable
- Improves code clarity for future maintainers
2025-12-23 14:48:50 -08:00

118 lines
3.0 KiB
Go

package s3api
import (
"strings"
"testing"
"time"
"github.com/seaweedfs/seaweedfs/weed/iam/integration"
"github.com/seaweedfs/seaweedfs/weed/iam/sts"
"github.com/stretchr/testify/assert"
)
func TestS3IAMIntegration_isSTSIssuer(t *testing.T) {
// Create test STS service with configuration
stsService := sts.NewSTSService()
// Set up STS configuration with a specific issuer
testIssuer := "https://seaweedfs-prod.company.com/sts"
stsConfig := &sts.STSConfig{
Issuer: testIssuer,
SigningKey: []byte("test-signing-key-32-characters-long"),
TokenDuration: sts.FlexibleDuration{Duration: time.Hour},
MaxSessionLength: sts.FlexibleDuration{Duration: 12 * time.Hour}, // Required field
}
// Initialize STS service with config (this sets the Config field)
err := stsService.Initialize(stsConfig)
assert.NoError(t, err)
// Create S3IAM integration with configured STS service
s3iam := &S3IAMIntegration{
iamManager: &integration.IAMManager{}, // Mock
stsService: stsService,
filerAddress: "test-filer:8888",
enabled: true,
}
tests := []struct {
name string
issuer string
expected bool
}{
// Only exact match should return true
{
name: "exact match with configured issuer",
issuer: testIssuer,
expected: true,
},
// All other issuers should return false (exact matching)
{
name: "similar but not exact issuer",
issuer: "https://seaweedfs-prod.company.com/sts2",
expected: false,
},
{
name: "substring of configured issuer",
issuer: "seaweedfs-prod.company.com",
expected: false,
},
{
name: "contains configured issuer as substring",
issuer: "prefix-" + testIssuer + "-suffix",
expected: false,
},
{
name: "case sensitive - different case",
issuer: strings.ToUpper(testIssuer),
expected: false,
},
{
name: "Google OIDC",
issuer: "https://accounts.google.com",
expected: false,
},
{
name: "Azure AD",
issuer: "https://login.microsoftonline.com/tenant-id/v2.0",
expected: false,
},
{
name: "Auth0",
issuer: "https://mycompany.auth0.com",
expected: false,
},
{
name: "Keycloak",
issuer: "https://keycloak.mycompany.com/auth/realms/master",
expected: false,
},
{
name: "Empty string",
issuer: "",
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := s3iam.isSTSIssuer(tt.issuer)
assert.Equal(t, tt.expected, result, "isSTSIssuer should use exact matching against configured issuer")
})
}
}
func TestS3IAMIntegration_isSTSIssuer_NoSTSService(t *testing.T) {
// Create S3IAM integration without STS service
s3iam := &S3IAMIntegration{
iamManager: &integration.IAMManager{},
stsService: nil, // No STS service
filerAddress: "test-filer:8888",
enabled: true,
}
// Should return false when STS service is not available
result := s3iam.isSTSIssuer("seaweedfs-sts")
assert.False(t, result, "isSTSIssuer should return false when STS service is nil")
}