fix(iam): keep revocation core active when new flows are disabled

This commit is contained in:
2026-10-29 20:38:08 +08:00
parent 3f3b4b400a
commit 27cab30c48
13 changed files with 59 additions and 20 deletions
@@ -17,6 +17,9 @@ final class IamV2Controller extends BaseAdminController
{
try {
if (!IamV2Client::enabled()) { throw new RuntimeException('FEATURE_DISABLED'); }
$action = strtolower((string) $this->request->action());
if (in_array($action, ['operation','preflight','batch','retry','selfstart','passwordsetup'], true) && !IamV2Client::feature('management')) { throw new RuntimeException('FEATURE_DISABLED'); }
if (in_array($action, ['launchstart','targetprepare','targetexchange'], true) && !IamV2Client::feature('launch')) { throw new RuntimeException('FEATURE_DISABLED'); }
$reads = ['status','accounts','identities','operationresult','audit','job','targetconfig'];
$read = in_array(strtolower((string) $this->request->action()), $reads, true);
if (($read && !$this->request->isGet()) || (!$read && !$this->request->isPost())) { throw new RuntimeException('METHOD_NOT_ALLOWED'); }
@@ -48,7 +51,7 @@ final class IamV2Controller extends BaseAdminController
}
public function status()
{
if (!IamV2Client::enabled()) { return $this->data(['enabled' => false]); }
if (!IamV2Client::enabled()) { return $this->data(['enabled' => false, 'management_enabled' => false, 'launch_enabled' => false]); }
return $this->invokeV2(function () {
$token = (string) $this->request->header('token', '');
$legacy = Db::name('admin_session')->where('token', $token)->where('expire_time', '>', time())->find();
@@ -56,7 +59,7 @@ final class IamV2Controller extends BaseAdminController
IamV2Source::admin((int) $legacy['admin_id']);
$fresh = false; try { $s = IamV2Source::current($token); $fresh = $s['auth_time'] >= time() - 300; } catch (\Throwable $e) { $s = null; }
$b = (new IamV2Manager())->binding((int) $legacy['admin_id']);
return ['enabled' => true, 'session_ready' => $s !== null, 'reauth_required' => !$fresh,
return ['enabled' => true, 'management_enabled' => IamV2Client::feature('management'), 'launch_enabled' => IamV2Client::feature('launch'), 'session_ready' => $s !== null, 'reauth_required' => !$fresh,
'management_capabilities' => IamV2Source::capabilities((int) $legacy['admin_id']),
'protected_review_operator' => IamV2Source::reviewOperator((int) $legacy['admin_id']),
'protected_account' => IamV2Source::protectedAccount((int) $legacy['admin_id'])] + $b;
@@ -117,6 +120,7 @@ final class IamV2Controller extends BaseAdminController
public function launchContinue()
{
try {
IamV2Source::requirePurpose('launch');
$client = new IamV2Client(); $s = IamV2Source::check((string) ($_COOKIE[IamV2Source::COOKIE] ?? ''));
$intent = (string) $this->request->get('intent', ''); $cookie = (string) ($_COOKIE['ZYT_IAM_V2_INTENT'] ?? '');
if ($intent === '' || !hash_equals($cookie, $intent)) { throw new RuntimeException('ACCOUNT_MISMATCH'); }
@@ -147,6 +151,7 @@ final class IamV2Controller extends BaseAdminController
public function selfCallback()
{
try {
IamV2Source::requirePurpose('self_link');
$central = new IamV2Client(); $s = IamV2Source::check((string) ($_COOKIE[IamV2Source::COOKIE] ?? ''));
$flow = IamV2Flow::take('self_link', (string) $this->request->get('state', ''), $s['session_id']);
$oidc = new IamOidcClient($this->selfConfig()); $oidc->exchange((string) $this->request->get('code', ''), $flow['verifier'], $flow['nonce']);
@@ -172,6 +177,7 @@ final class IamV2Controller extends BaseAdminController
public function passwordContinue()
{
try {
IamV2Source::requirePurpose('password_setup');
$client = new IamV2Client(); $s = IamV2Source::check((string) ($_COOKIE[IamV2Source::COOKIE] ?? ''));
$f = IamV2Flow::take('password_setup', (string) ($_COOKIE['ZYT_IAM_PASSWORD_INTENT'] ?? ''), $s['session_id']);
$id = (string) $this->request->get('request_id', ''); $state = (string) $this->request->get('state', '');
@@ -187,10 +193,10 @@ final class IamV2Controller extends BaseAdminController
}
public function targetConfig()
{
if (!IamV2Client::enabled()) { return $this->data(['enabled' => false]); }
if (!IamV2Client::enabled()) { return $this->data(['enabled' => false, 'management_enabled' => false, 'launch_enabled' => false]); }
return $this->invokeV2(function () {
$source = (string) $this->request->get('source', 'iam-portal');
return ['enabled' => true, 'restart_url' => IamV2Client::origin((string) Config::get('iam.portal_url')) . ($source === 'iam-admin' ? '/admin' : '/portal')];
return ['enabled' => IamV2Client::feature('launch'), 'global_enabled' => true, 'management_enabled' => IamV2Client::feature('management'), 'launch_enabled' => IamV2Client::feature('launch'), 'restart_url' => IamV2Client::origin((string) Config::get('iam.portal_url')) . ($source === 'iam-admin' ? '/admin' : '/portal')];
});
}
public function targetPrepare()