blocked('POST'); if ($blocked) { return $blocked; } $input = json_decode((string) $this->request->getInput(), true); if (!is_array($input)) { $input = $this->request->post(); } $ip = $this->request->ip(); try { $data = GrantService::issue($input, $ip); AuditLogger::log(['grant_id' => $data['grant_id'], 'admin_id' => $data['admin']['id'], 'tool' => 'auth.grant', 'arguments' => ['client' => $input['client'] ?? '', 'client_instance' => $input['client_instance'] ?? ''], 'status' => 'ok', 'ip' => $ip]); return Guard::envelope(1, '授权成功', $data); } catch (McpException $e) { AuditLogger::log(['tool' => 'auth.grant', 'arguments' => ['account' => (string) ($input['account'] ?? '')], 'status' => 'denied', 'message' => $e->reason, 'ip' => $ip]); return Guard::envelope(0, $e->getMessage(), ['reason' => $e->reason], $e->httpStatus === 401 ? 200 : $e->httpStatus, 1); } } public function revoke(): Response { $blocked = $this->blocked('POST'); if ($blocked) { return $blocked; } try { $identity = GrantService::authenticate($this->request); } catch (McpException $e) { return Guard::envelope(-1, $e->getMessage(), ['reason' => $e->reason], 401); } GrantService::close((int) $identity->grant['id'], GrantService::STATUS_REVOKED, 'client_revoke'); AuditLogger::log(['grant_id' => $identity->grant['id'], 'admin_id' => $identity->adminId, 'tool' => 'auth.revoke', 'status' => 'ok', 'ip' => $this->request->ip()]); return Guard::envelope(1, '已撤销'); } public function whoami(): Response { $blocked = $this->blocked('GET'); if ($blocked) { return $blocked; } try { $identity = GrantService::authenticate($this->request); } catch (McpException $e) { return Guard::envelope(-1, $e->getMessage(), ['reason' => $e->reason], 401); } return Guard::envelope(1, '', [ 'admin' => $identity->publicProfile(), 'grant' => GrantService::publicGrant($identity->grant), 'data_scope' => $identity->dataScopeText(), 'resources' => ['open' => count(Catalog::openFor($identity))], ]); } private function blocked(string $method): ?Response { if (!McpConfig::enabled()) { return Guard::envelope(0, 'AI 助手接口未启用', ['reason' => 'feature_disabled'], 503, 1); } if ($this->request->method(true) !== $method) { return response('', 405)->header(['Allow' => $method]); } $guard = Guard::check($this->request); if ($guard !== null) { return Guard::envelope(0, $guard[1], ['reason' => $guard[2]], 200, 1); } return null; } }