param( [string]$MysqlPassword = "123456", [string]$AdminPassword = "ChangeMe123!", [string]$GatewayBaseUrl = "http://127.0.0.1:9000", [string]$IamBaseUrl = "" ) $ErrorActionPreference = "Stop" $results = [System.Collections.Generic.List[object]]::new() if ([string]::IsNullOrWhiteSpace($IamBaseUrl)) { $IamBaseUrl = $GatewayBaseUrl } function Add-Result([string]$Name, [bool]$Passed, [string]$Evidence) { $results.Add([pscustomobject]@{ Test = $Name; Passed = $Passed; Evidence = $Evidence }) Write-Host "[$(if ($Passed) { 'PASS' } else { 'FAIL' })] $Name - $Evidence" if (-not $Passed) { throw "FAILED: $Name - $Evidence" } } function Invoke-Json([string]$Method, [string]$Uri, [hashtable]$Headers = @{}, [object]$Body = $null) { $args = @{ Method = $Method; Uri = $Uri; Headers = $Headers; TimeoutSec = 10 } if ($null -ne $Body) { $args.ContentType = "application/json" $args.Body = $Body | ConvertTo-Json -Depth 10 } Invoke-RestMethod @args } function Decode-JwtPayload([string]$Token) { $part = $Token.Split('.')[1].Replace('-', '+').Replace('_', '/') switch ($part.Length % 4) { 2 { $part += '==' } 3 { $part += '=' } } [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($part)) | ConvertFrom-Json } function Assert-ApiSuccess([string]$Name, [string]$Uri, [hashtable]$Headers) { $response = Invoke-Json GET $Uri $Headers Add-Result $Name ($response.code -eq '0') "code=$($response.code)" } $mysql = "D:\baiyue-runtime\mysql\server\bin\mysql.exe" $redisCli = "D:\baiyue-runtime\redis\redis-cli.exe" $verifySql = "D:/baiyue/iam/src/test/resources/db/verify-phase1-admin-rbac.sql" $env:MYSQL_PWD = $MysqlPassword $dbFailures = & $mysql '--host=127.0.0.1' '--port=3306' '--user=root' '--batch' '--raw' '--skip-column-names' "--execute=source $verifySql" Add-Result "database seed assertions" ([string]::IsNullOrWhiteSpace(($dbFailures -join ''))) "no assertion rows" $pong = & $redisCli -h 127.0.0.1 -p 6379 PING Add-Result "redis connectivity" ($pong -eq 'PONG') "PING=$pong" $nacosReady = (Invoke-WebRequest -UseBasicParsing -Uri 'http://127.0.0.1:8848/nacos/v1/console/health/readiness' -TimeoutSec 5).Content Add-Result "nacos readiness" ($nacosReady -eq 'OK') "readiness=$nacosReady" $nacosServices = Invoke-Json GET 'http://127.0.0.1:8848/nacos/v1/ns/service/list?pageNo=1&pageSize=50&groupName=BAIYUE&namespaceId=public' $expectedServices = @('gateway', 'auth-service', 'iam-service', 'order-service', 'warehouse-service', 'firstleg-service', 'lastleg-service', 'audit-service') $missingServices = @($expectedServices | Where-Object { $_ -notin $nacosServices.doms }) Add-Result "phase-one service registration" ($missingServices.Count -eq 0) "registered=$($nacosServices.count), missing=$($missingServices -join ',')" $platformLogin = Invoke-Json POST "$GatewayBaseUrl/api/auth/login" @{} @{ username = 'platform_admin'; password = $AdminPassword } $merchantLogin = Invoke-Json POST "$GatewayBaseUrl/api/auth/login" @{} @{ username = 'merchant_admin'; password = $AdminPassword } Add-Result "platform administrator login" ($platformLogin.code -eq '0') "login success" Add-Result "merchant administrator login" ($merchantLogin.code -eq '0') "login success" $platformClaims = Decode-JwtPayload $platformLogin.data.accessToken $merchantClaims = Decode-JwtPayload $merchantLogin.data.accessToken Add-Result "platform JWT identity" ( $platformClaims.app_code -eq 'PLATFORM' -and $platformClaims.tenant_id -eq 0 -and $platformClaims.membership_id -eq 3000001 -and 'PLATFORM_ADMIN' -in $platformClaims.roles -and @($platformClaims.permissions).Count -eq 31 ) "tenant=$($platformClaims.tenant_id), roles=$($platformClaims.roles -join ','), permissions=$(@($platformClaims.permissions).Count)" Add-Result "merchant JWT identity" ( $merchantClaims.app_code -eq 'MERCHANT' -and $merchantClaims.tenant_id -eq 10001 -and $merchantClaims.membership_id -eq 3000002 -and 'MERCHANT_OWNER' -in $merchantClaims.roles -and @($merchantClaims.permissions).Count -eq 21 ) "tenant=$($merchantClaims.tenant_id), roles=$($merchantClaims.roles -join ','), permissions=$(@($merchantClaims.permissions).Count)" $platformHeaders = @{ Authorization = "Bearer $($platformLogin.data.accessToken)" } $merchantHeaders = @{ Authorization = "Bearer $($merchantLogin.data.accessToken)" } Assert-ApiSuccess "platform role list" "$IamBaseUrl/api/platform/v1/iam/roles" $platformHeaders Assert-ApiSuccess "platform menu/button list" "$IamBaseUrl/api/platform/v1/iam/permissions" $platformHeaders Assert-ApiSuccess "platform enterprise review list" "$IamBaseUrl/api/platform/v1/iam/reviews" $platformHeaders Assert-ApiSuccess "platform first-leg order list" "$GatewayBaseUrl/api/platform/v1/orders/first-leg?tenantId=10001&page=1&size=10" $platformHeaders Assert-ApiSuccess "platform warehouse list" "$GatewayBaseUrl/api/platform/v1/warehouse-admin?tenantId=10001&page=1&size=10" $platformHeaders Assert-ApiSuccess "merchant enterprise profile" "$IamBaseUrl/api/merchant/v1/iam/tenant/profile" $merchantHeaders Assert-ApiSuccess "merchant role list" "$IamBaseUrl/api/merchant/v1/iam/roles" $merchantHeaders Assert-ApiSuccess "merchant menu/button list" "$IamBaseUrl/api/merchant/v1/iam/permissions" $merchantHeaders Assert-ApiSuccess "merchant warehouse list" "$GatewayBaseUrl/api/merchant/v1/warehouses?page=1&size=10" $merchantHeaders Assert-ApiSuccess "merchant first-leg order list" "$GatewayBaseUrl/api/merchant/v1/orders/first-leg?page=1&size=10" $merchantHeaders $crossScopeStatus = 0 try { Invoke-WebRequest -UseBasicParsing -Uri "$IamBaseUrl/api/merchant/v1/iam/tenant/profile" -Headers $platformHeaders -TimeoutSec 5 | Out-Null $crossScopeStatus = 200 } catch { $crossScopeStatus = [int]$_.Exception.Response.StatusCode } Add-Result "platform token denied from merchant APIs" ($crossScopeStatus -eq 403) "HTTP $crossScopeStatus" $results | Format-Table -AutoSize "PHASE1_ACCEPTANCE_PASSED=$($results.Count)"