Some checks failed
go: build dev binaries / cleanup (push) Successful in 4s
Codespell / Check for spelling errors (push) Failing after 3s
docker: build dev containers / build-rust-binaries (amd64, x86_64-unknown-linux-musl) (push) Failing after 3s
docker: build dev containers / build-dev-containers (push) Has been skipped
docker: build dev containers / build-rust-binaries (arm64, true, aarch64-unknown-linux-musl) (push) Failing after 3s
End to End / FUSE Mount (push) Failing after 2s
EC Integration Tests / EC Integration Tests (push) Failing after 30s
FUSE DLM Integration Tests / FUSE DLM Integration Tests (push) Failing after 3s
FUSE Volume Server Failover Tests / FUSE Volume Server Failover (push) Failing after 3s
FUSE Integration Tests / FUSE Integration Testing (push) Failing after 2s
FUSE P2P Peer Chunk Sharing Integration Tests / FUSE P2P Peer Chunk Sharing (push) Failing after 3s
go: build binary / Go Vet (push) Failing after 2s
go: build binary / Go Vet 32-bit (push) Failing after 3s
go: build binary / Build (push) Failing after 4s
go: build binary / Build cross-platform (freebsd/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (darwin/arm64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/arm64) (push) Failing after 3s
go: build binary / Test (push) Failing after 2s
go: build binary / Test 32-bit (push) Failing after 3s
helm: lint and test charts / lint-test (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (11) (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (17) (push) Failing after 3s
go: build dev binaries / build_dev_linux_windows (amd64, linux) (push) Failing after 2s
go: build dev binaries / build_dev_linux_windows (amd64, windows) (push) Failing after 3s
go: build dev binaries / build_dev_darwin (amd64, darwin) (push) Has been skipped
go: build dev binaries / build_dev_darwin (arm64, darwin) (push) Has been skipped
Java Client Unit Tests / Java Unit Tests (11) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (17) (push) Failing after 2s
Java Client Unit Tests / Java Unit Tests (21) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (8) (push) Failing after 3s
Kafka Quick Test (Load Test with Schema Registry) / Kafka Client Load Test (Quick) (push) Failing after 3s
Kafka Gateway Tests / Kafka Unit Tests (unit-tests-1) (push) Failing after 11s
Kafka Gateway Tests / Kafka Integration Tests (Critical) (integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka End-to-End Tests (with SMQ) (e2e-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Consumer Group Tests (Highly Isolated) (consumer-group-1) (push) Failing after 2s
Kafka Gateway Tests / Kafka Client Compatibility (with SMQ) (client-compat-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka SMQ Integration Tests (Full Stack) (smq-integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Protocol Tests (Isolated) (protocol-1) (push) Failing after 3s
KMS Tests / KMS Provider Integration Tests (push) Failing after 2s
KMS Tests / S3 KMS End-to-End Tests (push) Failing after 3s
Master Cold Start Tests / Master Cold Start Tests (push) Failing after 4s
Metadata Subscribe Integration Tests / Metadata Subscribe Integration Tests (push) Failing after 3s
Multi-Master Tests / Multi-Master Failover Tests (push) Failing after 3s
Performance / CPU and Heap Profile (push) Failing after 2s
Performance / S3 Read/Write Benchmark (rust volume) (push) Failing after 3s
pjdfstest POSIX Compliance / pjdfstest (push) Failing after 2s
Plugin Worker Integration Tests / Plugin Worker: erasure_coding (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: vacuum (push) Failing after 3s
Rust Volume Server Tests / Rust Integration Tests (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 1) (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 1) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 3) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Distributed Tests (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Performance Tests (push) Failing after 3s
Performance / Throughput Benchmark (go volume) (push) Failing after 3s
Performance / Throughput Benchmark (rust volume) (push) Failing after 2s
Performance / S3 Read/Write Benchmark (go volume) (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: volume_balance (push) Failing after 3s
PostgreSQL Gateway Tests / PostgreSQL Basic Tests (push) Failing after 3s
Rust Volume Server Tests / Rust Unit Tests (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 3) (push) Failing after 3s
Rust Plugin Worker Tests / Rust Plugin Worker Build and Unit Tests (push) Failing after 3s
rust: build dev volume server binaries / cleanup (push) Successful in 3s
S3 ETag and ACL Tests / S3 ETag + ACL Integration Tests (push) Failing after 3s
S3 IAM Integration Tests / IAM Unit Tests (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (advanced) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (basic) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (group) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (policy-enforcement) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (sts) (push) Failing after 4s
S3 Keycloak Integration Tests / S3 Keycloak Integration Tests (push) Failing after 3s
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.11) (push) Failing after 3s
S3 PyArrow Parquet Tests / Go Unit Tests (Implicit Directory) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.12) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-amd64, x86_64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-arm64, aarch64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-linux (linux-amd64, x86_64-unknown-linux-gnu) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.9) (push) Has been cancelled
S3 Proxy Signature Tests / S3 Proxy Signature Verification Tests (push) Has been cancelled
S3 SDK V2 Route Disambiguation Tests / S3 SDK V2 Routing Tests (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (quick) (push) Has been cancelled
S3 SSE Tests / S3 SSE Compatibility Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Metadata Persistence Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Copy Operations Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Multipart Upload Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Performance Test (push) Has been cancelled
S3 SSE Tests / S3 Volume Encryption Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (comprehensive) (push) Has been cancelled
Spark Integration Tests / Spark Integration Tests (push) Failing after 2s
Telemetry Integration Tests / telemetry-integration-test (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 1) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 1) (push) Failing after 3s
Ceph S3 tests / Basic S3 tests (KV store) (push) Has been cancelled
Ceph S3 tests / S3 Versioning & Object Lock tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Unit Tests (push) Failing after 3s
Ceph S3 tests / S3 CORS tests (push) Has been cancelled
Ceph S3 tests / SeaweedFS Custom S3 Copy tests (push) Has been cancelled
Ceph S3 tests / Basic S3 tests (SQL store) (push) Has been cancelled
test s3 over https using aws-cli / awscli-tests (push) Has been cancelled
TLS Rotation Integration Tests / TLS Rotation Integration Tests (push) Has been cancelled
Vacuum Integration Tests / Vacuum Integration Tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Variables Integration Tests (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (advanced-policy) (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (basic-policy) (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (contextual-policy) (push) Failing after 4s
S3 Policy Integration Tests / Trusted Proxy Detection Tests (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Shell Integration Tests (push) Failing after 3s
Samba on FUSE Integration / samba-integration (push) Failing after 2s
SFTP Integration Tests / SFTP Integration Testing (push) Failing after 3s
terraform: validate and test modules / fmt, validate, plan-level tests (push) Failing after 3s
terraform: validate and test modules / local cluster smoke test (real weed) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 3) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 2) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 2) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 3) (push) Failing after 5s
mount: windows conformance / WinFsp conformance (push) Has been cancelled
mount: windows / Mount on Windows (push) Has been cancelled
397 lines
14 KiB
Go
397 lines
14 KiB
Go
package s3api
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
"testing"
|
|
"time"
|
|
|
|
iamlib "github.com/seaweedfs/seaweedfs/weed/iam"
|
|
"github.com/seaweedfs/seaweedfs/weed/iam/integration"
|
|
"github.com/seaweedfs/seaweedfs/weed/iam/policy"
|
|
"github.com/seaweedfs/seaweedfs/weed/iam/sts"
|
|
)
|
|
|
|
// stubIntegration is the smallest IAMManagerProvider that lets the OIDC
|
|
// dispatcher reach an IAMManager. The other IAMIntegration methods are
|
|
// unused by these tests and panic if invoked, which is what we want — any
|
|
// unexpected call signals a routing bug.
|
|
type stubIntegration struct {
|
|
IAMIntegration
|
|
mgr *integration.IAMManager
|
|
}
|
|
|
|
func (s *stubIntegration) GetIAMManager() *integration.IAMManager { return s.mgr }
|
|
|
|
func newOIDCTestAPI(t *testing.T) (*EmbeddedIamApiForTest, *integration.IAMManager) {
|
|
t.Helper()
|
|
mgr := integration.NewIAMManager()
|
|
cfg := &integration.IAMConfig{
|
|
STS: &sts.STSConfig{
|
|
TokenDuration: sts.FlexibleDuration{Duration: time.Hour},
|
|
MaxSessionLength: sts.FlexibleDuration{Duration: 12 * time.Hour},
|
|
Issuer: "test-sts",
|
|
SigningKey: []byte("test-signing-key-32-characters-long"),
|
|
AccountId: "111122223333",
|
|
Providers: []*sts.ProviderConfig{
|
|
{
|
|
Name: "google",
|
|
Type: sts.ProviderTypeOIDC,
|
|
Enabled: true,
|
|
Config: map[string]interface{}{
|
|
"issuer": "https://accounts.google.com",
|
|
"clientId": "client-google",
|
|
},
|
|
},
|
|
{
|
|
Name: "github",
|
|
Type: sts.ProviderTypeOIDC,
|
|
Enabled: true,
|
|
Config: map[string]interface{}{
|
|
"issuer": "https://token.actions.githubusercontent.com",
|
|
"clientId": "sts.amazonaws.com",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Policy: &policy.PolicyEngineConfig{DefaultEffect: "Deny", StoreType: "memory"},
|
|
Roles: &integration.RoleStoreConfig{StoreType: "memory"},
|
|
}
|
|
if err := mgr.Initialize(cfg, func() string { return "localhost:8888" }); err != nil {
|
|
t.Fatalf("Initialize IAM manager: %v", err)
|
|
}
|
|
|
|
api := NewEmbeddedIamApiForTest()
|
|
api.iam.iamIntegration = &stubIntegration{mgr: mgr}
|
|
return api, mgr
|
|
}
|
|
|
|
func TestListOpenIDConnectProviders(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
values := url.Values{}
|
|
values.Set("Action", actionListOpenIDConnectProviders)
|
|
|
|
resp, iamErr := api.ExecuteAction(context.Background(), values, true, "test-req-1")
|
|
if iamErr != nil {
|
|
t.Fatalf("ExecuteAction: code=%s err=%v", iamErr.Code, iamErr.Error)
|
|
}
|
|
listResp, ok := resp.(*iamlib.ListOpenIDConnectProvidersResponse)
|
|
if !ok {
|
|
t.Fatalf("unexpected response type %T", resp)
|
|
}
|
|
got := listResp.ListOpenIDConnectProvidersResult.OpenIDConnectProviderList
|
|
if len(got) != 2 {
|
|
t.Fatalf("expected 2 providers, got %d", len(got))
|
|
}
|
|
}
|
|
|
|
func TestGetOpenIDConnectProvider(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
arn := "arn:aws:iam::111122223333:oidc-provider/accounts.google.com"
|
|
|
|
values := url.Values{}
|
|
values.Set("Action", actionGetOpenIDConnectProvider)
|
|
values.Set("OpenIDConnectProviderArn", arn)
|
|
|
|
resp, iamErr := api.ExecuteAction(context.Background(), values, true, "test-req-2")
|
|
if iamErr != nil {
|
|
t.Fatalf("ExecuteAction: code=%s err=%v", iamErr.Code, iamErr.Error)
|
|
}
|
|
getResp, ok := resp.(*iamlib.GetOpenIDConnectProviderResponse)
|
|
if !ok {
|
|
t.Fatalf("unexpected response type %T", resp)
|
|
}
|
|
if getResp.GetOpenIDConnectProviderResult.Url != "https://accounts.google.com" {
|
|
t.Fatalf("URL mismatch: %s", getResp.GetOpenIDConnectProviderResult.Url)
|
|
}
|
|
if len(getResp.GetOpenIDConnectProviderResult.ClientIDList) != 1 ||
|
|
getResp.GetOpenIDConnectProviderResult.ClientIDList[0] != "client-google" {
|
|
t.Fatalf("ClientIDList wrong: %v", getResp.GetOpenIDConnectProviderResult.ClientIDList)
|
|
}
|
|
}
|
|
|
|
func TestGetOpenIDConnectProviderMissing(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
values := url.Values{}
|
|
values.Set("Action", actionGetOpenIDConnectProvider)
|
|
values.Set("OpenIDConnectProviderArn", "arn:aws:iam::111122223333:oidc-provider/nope.example")
|
|
|
|
_, iamErr := api.ExecuteAction(context.Background(), values, true, "test-req-3")
|
|
if iamErr == nil {
|
|
t.Fatal("expected NoSuchEntity error")
|
|
}
|
|
if iamErr.Code != "NoSuchEntity" {
|
|
t.Fatalf("expected NoSuchEntity code, got %s", iamErr.Code)
|
|
}
|
|
}
|
|
|
|
func TestGetOpenIDConnectProviderRequiresArn(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
values := url.Values{}
|
|
values.Set("Action", actionGetOpenIDConnectProvider)
|
|
|
|
_, iamErr := api.ExecuteAction(context.Background(), values, true, "test-req-4")
|
|
if iamErr == nil {
|
|
t.Fatal("expected error for missing ARN")
|
|
}
|
|
if iamErr.Code != "InvalidInput" {
|
|
t.Fatalf("expected InvalidInput code, got %s", iamErr.Code)
|
|
}
|
|
}
|
|
|
|
func TestReadOnlyAllowsOIDCList(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
api.readOnly = true
|
|
values := url.Values{}
|
|
values.Set("Action", actionListOpenIDConnectProviders)
|
|
|
|
if _, iamErr := api.ExecuteAction(context.Background(), values, true, "ro-1"); iamErr != nil {
|
|
t.Fatalf("read-only mode should allow ListOpenIDConnectProviders: %v", iamErr.Error)
|
|
}
|
|
}
|
|
|
|
func TestReadOnlyDeniesOIDCMutations(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
api.readOnly = true
|
|
mutations := []string{
|
|
actionCreateOpenIDConnectProvider,
|
|
actionDeleteOpenIDConnectProvider,
|
|
actionAddClientIDToOpenIDConnectProvider,
|
|
actionRemoveClientIDFromOpenIDConnectProvider,
|
|
actionUpdateOpenIDConnectProviderThumbprint,
|
|
actionTagOpenIDConnectProvider,
|
|
actionUntagOpenIDConnectProvider,
|
|
}
|
|
for _, action := range mutations {
|
|
t.Run(action, func(t *testing.T) {
|
|
values := url.Values{}
|
|
values.Set("Action", action)
|
|
_, iamErr := api.ExecuteAction(context.Background(), values, true, "ro-deny")
|
|
if iamErr == nil {
|
|
t.Fatalf("expected denial for %s in read-only mode", action)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCreateOpenIDConnectProvider(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
values := url.Values{}
|
|
values.Set("Action", actionCreateOpenIDConnectProvider)
|
|
values.Set("Url", "https://auth.example.com")
|
|
values.Set("ClientIDList.member.1", "alpha")
|
|
values.Set("ClientIDList.member.2", "beta")
|
|
values.Set("ThumbprintList.member.1", "9e99a48a9960b14926bb7f3b02e22da2b0ab7280")
|
|
values.Set("Tags.member.1.Key", "team")
|
|
values.Set("Tags.member.1.Value", "infra")
|
|
|
|
resp, iamErr := api.ExecuteAction(context.Background(), values, true, "create-1")
|
|
if iamErr != nil {
|
|
t.Fatalf("ExecuteAction: %v", iamErr.Error)
|
|
}
|
|
createResp, ok := resp.(*iamlib.CreateOpenIDConnectProviderResponse)
|
|
if !ok {
|
|
t.Fatalf("unexpected response type %T", resp)
|
|
}
|
|
wantArn := "arn:aws:iam::111122223333:oidc-provider/auth.example.com"
|
|
if createResp.CreateOpenIDConnectProviderResult.OpenIDConnectProviderArn != wantArn {
|
|
t.Fatalf("ARN mismatch: got=%s want=%s",
|
|
createResp.CreateOpenIDConnectProviderResult.OpenIDConnectProviderArn, wantArn)
|
|
}
|
|
|
|
// Get the new provider back to confirm persistence and clientId list.
|
|
getValues := url.Values{}
|
|
getValues.Set("Action", actionGetOpenIDConnectProvider)
|
|
getValues.Set("OpenIDConnectProviderArn", wantArn)
|
|
getResp, iamErr := api.ExecuteAction(context.Background(), getValues, true, "get-after-create")
|
|
if iamErr != nil {
|
|
t.Fatalf("Get after create: %v", iamErr.Error)
|
|
}
|
|
gr := getResp.(*iamlib.GetOpenIDConnectProviderResponse).GetOpenIDConnectProviderResult
|
|
if len(gr.ClientIDList) != 2 || gr.ClientIDList[0] != "alpha" || gr.ClientIDList[1] != "beta" {
|
|
t.Fatalf("ClientIDList persisted incorrectly: %v", gr.ClientIDList)
|
|
}
|
|
if len(gr.ThumbprintList) != 1 || gr.ThumbprintList[0] != "9e99a48a9960b14926bb7f3b02e22da2b0ab7280" {
|
|
t.Fatalf("ThumbprintList persisted incorrectly: %v", gr.ThumbprintList)
|
|
}
|
|
if len(gr.Tags) != 1 || gr.Tags[0].Key != "team" || gr.Tags[0].Value != "infra" {
|
|
t.Fatalf("Tags persisted incorrectly: %v", gr.Tags)
|
|
}
|
|
}
|
|
|
|
func TestCreateOpenIDConnectProviderRejectsBadInput(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
|
|
t.Run("missing Url", func(t *testing.T) {
|
|
values := url.Values{}
|
|
values.Set("Action", actionCreateOpenIDConnectProvider)
|
|
values.Set("ClientIDList.member.1", "x")
|
|
_, iamErr := api.ExecuteAction(context.Background(), values, true, "")
|
|
if iamErr == nil || iamErr.Code != "InvalidInput" {
|
|
t.Fatalf("expected InvalidInput, got %v", iamErr)
|
|
}
|
|
})
|
|
|
|
t.Run("missing ClientIDList", func(t *testing.T) {
|
|
values := url.Values{}
|
|
values.Set("Action", actionCreateOpenIDConnectProvider)
|
|
values.Set("Url", "https://auth.example.com")
|
|
_, iamErr := api.ExecuteAction(context.Background(), values, true, "")
|
|
if iamErr == nil || iamErr.Code != "InvalidInput" {
|
|
t.Fatalf("expected InvalidInput, got %v", iamErr)
|
|
}
|
|
})
|
|
|
|
t.Run("invalid thumbprint", func(t *testing.T) {
|
|
values := url.Values{}
|
|
values.Set("Action", actionCreateOpenIDConnectProvider)
|
|
values.Set("Url", "https://auth.example.com")
|
|
values.Set("ClientIDList.member.1", "x")
|
|
values.Set("ThumbprintList.member.1", "not-a-sha1")
|
|
_, iamErr := api.ExecuteAction(context.Background(), values, true, "")
|
|
if iamErr == nil || iamErr.Code != "InvalidInput" {
|
|
t.Fatalf("expected InvalidInput, got %v", iamErr)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCreateOpenIDConnectProviderConflict(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
values := url.Values{}
|
|
values.Set("Action", actionCreateOpenIDConnectProvider)
|
|
values.Set("Url", "https://accounts.google.com") // already mirrored from static config
|
|
values.Set("ClientIDList.member.1", "x")
|
|
|
|
_, iamErr := api.ExecuteAction(context.Background(), values, true, "")
|
|
if iamErr == nil {
|
|
t.Fatal("expected conflict for duplicate provider")
|
|
}
|
|
if iamErr.Code != "EntityAlreadyExists" {
|
|
t.Fatalf("expected EntityAlreadyExists, got %s", iamErr.Code)
|
|
}
|
|
}
|
|
|
|
func TestDeleteOpenIDConnectProvider(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
arn := "arn:aws:iam::111122223333:oidc-provider/accounts.google.com"
|
|
|
|
values := url.Values{}
|
|
values.Set("Action", actionDeleteOpenIDConnectProvider)
|
|
values.Set("OpenIDConnectProviderArn", arn)
|
|
|
|
if _, iamErr := api.ExecuteAction(context.Background(), values, true, ""); iamErr != nil {
|
|
t.Fatalf("delete: %v", iamErr.Error)
|
|
}
|
|
// Verify gone.
|
|
getValues := url.Values{}
|
|
getValues.Set("Action", actionGetOpenIDConnectProvider)
|
|
getValues.Set("OpenIDConnectProviderArn", arn)
|
|
if _, iamErr := api.ExecuteAction(context.Background(), getValues, true, ""); iamErr == nil {
|
|
t.Fatal("expected not-found after delete")
|
|
}
|
|
// Idempotent.
|
|
if _, iamErr := api.ExecuteAction(context.Background(), values, true, ""); iamErr != nil {
|
|
t.Fatalf("idempotent delete failed: %v", iamErr.Error)
|
|
}
|
|
}
|
|
|
|
func TestAddRemoveClientID(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
arn := "arn:aws:iam::111122223333:oidc-provider/accounts.google.com"
|
|
|
|
add := url.Values{}
|
|
add.Set("Action", actionAddClientIDToOpenIDConnectProvider)
|
|
add.Set("OpenIDConnectProviderArn", arn)
|
|
add.Set("ClientID", "extra-client")
|
|
if _, iamErr := api.ExecuteAction(context.Background(), add, true, ""); iamErr != nil {
|
|
t.Fatalf("add: %v", iamErr.Error)
|
|
}
|
|
|
|
getValues := url.Values{}
|
|
getValues.Set("Action", actionGetOpenIDConnectProvider)
|
|
getValues.Set("OpenIDConnectProviderArn", arn)
|
|
resp, iamErr := api.ExecuteAction(context.Background(), getValues, true, "")
|
|
if iamErr != nil {
|
|
t.Fatalf("get: %v", iamErr.Error)
|
|
}
|
|
got := resp.(*iamlib.GetOpenIDConnectProviderResponse).GetOpenIDConnectProviderResult.ClientIDList
|
|
if len(got) != 2 {
|
|
t.Fatalf("expected 2 clients after add, got %v", got)
|
|
}
|
|
|
|
// Idempotent add.
|
|
if _, iamErr := api.ExecuteAction(context.Background(), add, true, ""); iamErr != nil {
|
|
t.Fatalf("idempotent add: %v", iamErr.Error)
|
|
}
|
|
|
|
// Remove.
|
|
rm := url.Values{}
|
|
rm.Set("Action", actionRemoveClientIDFromOpenIDConnectProvider)
|
|
rm.Set("OpenIDConnectProviderArn", arn)
|
|
rm.Set("ClientID", "extra-client")
|
|
if _, iamErr := api.ExecuteAction(context.Background(), rm, true, ""); iamErr != nil {
|
|
t.Fatalf("remove: %v", iamErr.Error)
|
|
}
|
|
resp, _ = api.ExecuteAction(context.Background(), getValues, true, "")
|
|
got = resp.(*iamlib.GetOpenIDConnectProviderResponse).GetOpenIDConnectProviderResult.ClientIDList
|
|
if len(got) != 1 || got[0] != "client-google" {
|
|
t.Fatalf("unexpected clients after remove: %v", got)
|
|
}
|
|
|
|
// Removing a missing client is a no-op.
|
|
if _, iamErr := api.ExecuteAction(context.Background(), rm, true, ""); iamErr != nil {
|
|
t.Fatalf("idempotent remove: %v", iamErr.Error)
|
|
}
|
|
}
|
|
|
|
func TestUpdateThumbprintAndTags(t *testing.T) {
|
|
api, _ := newOIDCTestAPI(t)
|
|
arn := "arn:aws:iam::111122223333:oidc-provider/accounts.google.com"
|
|
|
|
upd := url.Values{}
|
|
upd.Set("Action", actionUpdateOpenIDConnectProviderThumbprint)
|
|
upd.Set("OpenIDConnectProviderArn", arn)
|
|
upd.Set("ThumbprintList.member.1", "0000000000000000000000000000000000000000")
|
|
upd.Set("ThumbprintList.member.2", "1111111111111111111111111111111111111111")
|
|
if _, iamErr := api.ExecuteAction(context.Background(), upd, true, ""); iamErr != nil {
|
|
t.Fatalf("update thumbprints: %v", iamErr.Error)
|
|
}
|
|
|
|
tag := url.Values{}
|
|
tag.Set("Action", actionTagOpenIDConnectProvider)
|
|
tag.Set("OpenIDConnectProviderArn", arn)
|
|
tag.Set("Tags.member.1.Key", "owner")
|
|
tag.Set("Tags.member.1.Value", "platform")
|
|
if _, iamErr := api.ExecuteAction(context.Background(), tag, true, ""); iamErr != nil {
|
|
t.Fatalf("tag: %v", iamErr.Error)
|
|
}
|
|
|
|
get := url.Values{}
|
|
get.Set("Action", actionGetOpenIDConnectProvider)
|
|
get.Set("OpenIDConnectProviderArn", arn)
|
|
resp, iamErr := api.ExecuteAction(context.Background(), get, true, "")
|
|
if iamErr != nil {
|
|
t.Fatalf("get: %v", iamErr.Error)
|
|
}
|
|
gr := resp.(*iamlib.GetOpenIDConnectProviderResponse).GetOpenIDConnectProviderResult
|
|
if len(gr.ThumbprintList) != 2 {
|
|
t.Fatalf("ThumbprintList persisted incorrectly: %v", gr.ThumbprintList)
|
|
}
|
|
if len(gr.Tags) != 1 || gr.Tags[0].Key != "owner" {
|
|
t.Fatalf("Tags persisted incorrectly: %v", gr.Tags)
|
|
}
|
|
|
|
untag := url.Values{}
|
|
untag.Set("Action", actionUntagOpenIDConnectProvider)
|
|
untag.Set("OpenIDConnectProviderArn", arn)
|
|
untag.Set("TagKeys.member.1", "owner")
|
|
if _, iamErr := api.ExecuteAction(context.Background(), untag, true, ""); iamErr != nil {
|
|
t.Fatalf("untag: %v", iamErr.Error)
|
|
}
|
|
resp, _ = api.ExecuteAction(context.Background(), get, true, "")
|
|
gr = resp.(*iamlib.GetOpenIDConnectProviderResponse).GetOpenIDConnectProviderResult
|
|
if len(gr.Tags) != 0 {
|
|
t.Fatalf("Tags should be empty after untag, got: %v", gr.Tags)
|
|
}
|
|
}
|