* @param array $payload * @return array */
(McpOpsContext $ctx, array $payload)
| 1218 | * @return array<string,mixed> |
| 1219 | */ |
| 1220 | private static function opRenameFile(McpOpsContext $ctx, array $payload): array |
| 1221 | { |
| 1222 | return self::withSourceContext($ctx, $payload, true, function () use ($ctx, $payload): array { |
| 1223 | self::assertWritableAccount($ctx, false); |
| 1224 | |
| 1225 | $folder = self::normalizeFolder((string)($payload['folder'] ?? 'root')); |
| 1226 | $oldName = self::normalizeFileName((string)($payload['oldName'] ?? ($payload['old_name'] ?? ''))); |
| 1227 | $newName = self::normalizeFileName((string)($payload['newName'] ?? ($payload['new_name'] ?? ''))); |
| 1228 | if (strcasecmp($oldName, $newName) === 0) { |
| 1229 | throw new RuntimeException('Old and new file names are the same.', 400); |
| 1230 | } |
| 1231 | |
| 1232 | $username = $ctx->username(); |
| 1233 | $perms = $ctx->permissions(); |
| 1234 | |
| 1235 | $hasRename = ACL::canRename($username, $perms, $folder) |
| 1236 | || ACL::ownsFolderOrAncestor($username, $perms, $folder); |
| 1237 | if (!$hasRename) { |
| 1238 | throw new RuntimeException('Forbidden: no rename permission.', 403); |
| 1239 | } |
| 1240 | |
| 1241 | self::assertFolderScope($ctx, $folder, 'rename'); |
| 1242 | |
| 1243 | if ( |
| 1244 | !$ctx->canBypassOwnership() |
| 1245 | && !ACL::canRead($username, $perms, $folder) |
| 1246 | && ACL::hasGrant($username, $folder, 'read_own') |
| 1247 | ) { |
| 1248 | self::assertFilesOwnedByUser($folder, [$oldName], $username); |
| 1249 | } |
| 1250 | |
| 1251 | $result = FileModel::renameFile($folder, $oldName, $newName); |
| 1252 | if (!is_array($result)) { |
| 1253 | throw new RuntimeException('Failed to rename file.', 500); |
| 1254 | } |
| 1255 | if (isset($result['error'])) { |
| 1256 | throw new RuntimeException((string)$result['error'], 400); |
| 1257 | } |
| 1258 | |
| 1259 | $resolvedNewName = trim((string)($result['newName'] ?? $newName)); |
| 1260 | if ($resolvedNewName === '') { |
| 1261 | $resolvedNewName = $newName; |
| 1262 | } |
| 1263 | |
| 1264 | return [ |
| 1265 | 'ok' => true, |
| 1266 | 'folder' => $folder, |
| 1267 | 'oldName' => $oldName, |
| 1268 | 'newName' => $resolvedNewName, |
| 1269 | 'result' => $result, |
| 1270 | ]; |
| 1271 | }); |
| 1272 | } |
| 1273 | |
| 1274 | /** |
| 1275 | * @param array<string,mixed> $payload |
no test coverage detected