diff --git a/app/Http/Controllers/Api/ServerResourceController.php b/app/Http/Controllers/Api/ServerResourceController.php index fbcf571..afa0959 100644 --- a/app/Http/Controllers/Api/ServerResourceController.php +++ b/app/Http/Controllers/Api/ServerResourceController.php @@ -89,6 +89,7 @@ class ServerResourceController extends Controller $description = (string) ($permission->description ?? ''); if (preg_match('/资源ID[::]\s*(\d+)/u', $description, $matches) === 1) { $resourceIds->push((int) $matches[1]); + continue; } @@ -316,9 +317,12 @@ class ServerResourceController extends Controller public function useResource(Request $request, int $id): JsonResponse { $validated = $request->validate([ - 'account_name' => ['nullable', 'string', 'max:255'], - 'password' => ['nullable', 'string', 'max:255'], + 'account_name' => ['required', 'string', 'max:255'], + 'password' => ['required', 'string', 'max:255'], 'protocol' => ['required', 'string', 'max:64'], + ], [ + 'account_name.required' => '请输入访问用户名。', + 'password.required' => '请输入访问密码。', ]); $resource = ServerResource::query()->with('parent')->findOrFail($id); @@ -456,6 +460,11 @@ class ServerResourceController extends Controller ], 502); } + $tempPassword = null; + if ((bool) $resource->allow_copy_temp_password) { + $tempPassword = $this->extractSsoTokenFromUrl($ssoUrl); + } + AccessLog::query()->create([ 'user_id' => $user->id, 'server_resource_id' => $resource->id, @@ -493,10 +502,42 @@ class ServerResourceController extends Controller 'bastion_account_id' => $bastionAccount->id, 'client_type' => (string) data_get($result, 'data.client_type', ''), 'response' => $result, + 'allow_copy_temp_password' => (bool) $resource->allow_copy_temp_password, + 'temp_password' => $tempPassword, ], ]); } + private function extractSsoTokenFromUrl(string $ssoUrl): ?string + { + if (! str_starts_with($ssoUrl, 'sso://')) { + return null; + } + + $encoded = trim(substr($ssoUrl, strlen('sso://'))); + $encoded = rtrim($encoded, '/'); + if ($encoded === '') { + return null; + } + + $decoded = base64_decode($encoded, true); + if ($decoded === false || $decoded === '') { + return null; + } + + $payload = json_decode($decoded, true); + if (! is_array($payload)) { + return null; + } + + $token = data_get($payload, 'NODE_COMMON.SSOToken'); + if (! is_string($token) || trim($token) === '') { + return null; + } + + return trim($token); + } + private function syncDirectPermissionsByPivot(ServerResource $resource, Permission $permission, array $syncData): void { if (! $resource->parent_id) { diff --git a/app/Http/Requests/StoreServerResourceRequest.php b/app/Http/Requests/StoreServerResourceRequest.php index 8d540a6..36cfc42 100644 --- a/app/Http/Requests/StoreServerResourceRequest.php +++ b/app/Http/Requests/StoreServerResourceRequest.php @@ -22,6 +22,7 @@ class StoreServerResourceRequest extends FormRequest 'account_id' => ['nullable', 'integer', 'min:1'], 'protocol' => ['nullable', 'string', 'max:64'], 'description' => ['nullable', 'string', 'max:255'], + 'allow_copy_temp_password' => ['sometimes', 'boolean'], 'is_active' => ['sometimes', 'boolean'], ]; } diff --git a/app/Http/Requests/UpdateServerResourceRequest.php b/app/Http/Requests/UpdateServerResourceRequest.php index 25910b0..eedacef 100644 --- a/app/Http/Requests/UpdateServerResourceRequest.php +++ b/app/Http/Requests/UpdateServerResourceRequest.php @@ -22,6 +22,7 @@ class UpdateServerResourceRequest extends FormRequest 'account_id' => ['nullable', 'integer', 'min:1'], 'protocol' => ['nullable', 'string', 'max:64'], 'description' => ['nullable', 'string', 'max:255'], + 'allow_copy_temp_password' => ['sometimes', 'boolean'], 'is_active' => ['sometimes', 'boolean'], ]; } diff --git a/app/Models/ServerResource.php b/app/Models/ServerResource.php index 47a5fe8..16b1a2b 100644 --- a/app/Models/ServerResource.php +++ b/app/Models/ServerResource.php @@ -21,6 +21,7 @@ class ServerResource extends Model 'account_id', 'protocols', 'description', + 'allow_copy_temp_password', 'is_active', ]; @@ -50,6 +51,7 @@ class ServerResource extends Model { return [ 'protocols' => 'array', + 'allow_copy_temp_password' => 'boolean', 'is_active' => 'boolean', ]; } diff --git a/database/migrations/2026_04_30_120000_add_allow_copy_temp_password_to_server_resources_table.php b/database/migrations/2026_04_30_120000_add_allow_copy_temp_password_to_server_resources_table.php new file mode 100644 index 0000000..ac9235d --- /dev/null +++ b/database/migrations/2026_04_30_120000_add_allow_copy_temp_password_to_server_resources_table.php @@ -0,0 +1,25 @@ +boolean('allow_copy_temp_password') + ->default(false) + ->after('protocols') + ->comment('是否允许用户复制临时密码'); + }); + } + + public function down(): void + { + Schema::table('server_resources', function (Blueprint $table) { + $table->dropColumn('allow_copy_temp_password'); + }); + } +};