MCPcopy Create free account
hub / github.com/error311/FileRise / opReadFile

Method opReadFile

src/FileRise/Domain/McpCoreOpsService.php:689–762  ·  view source on GitHub ↗

* @param array $payload * @return array */

(McpOpsContext $ctx, array $payload)

Source from the content-addressed store, hash-verified

687 * @return array<string,mixed>
688 */
689 private static function opReadFile(McpOpsContext $ctx, array $payload): array
690 {
691 return self::withSourceContext($ctx, $payload, false, function () use ($ctx, $payload): array {
692 $folder = self::normalizeFolder((string)($payload['folder'] ?? 'root'));
693 $file = self::normalizeFileName((string)($payload['file'] ?? ($payload['filename'] ?? '')));
694 $maxBytes = self::boundedInt(
695 $payload['maxBytes'] ?? self::DEFAULT_READ_FILE_PREVIEW_BYTES,
696 256,
697 self::MAX_READ_FILE_PREVIEW_BYTES,
698 self::DEFAULT_READ_FILE_PREVIEW_BYTES
699 );
700
701 $username = $ctx->username();
702 $perms = $ctx->permissions();
703
704 $fullView = ACL::canRead($username, $perms, $folder)
705 || ACL::ownsFolderOrAncestor($username, $perms, $folder);
706 $ownOnlyGrant = ACL::hasGrant($username, $folder, 'read_own');
707 if (!$fullView && !$ownOnlyGrant) {
708 throw new RuntimeException('Forbidden: no view access to this folder.', 403);
709 }
710
711 self::assertFolderScope($ctx, $folder, $fullView ? 'read' : 'read_own');
712
713 if (
714 !$ctx->canBypassOwnership()
715 && !$fullView
716 && $ownOnlyGrant
717 ) {
718 self::assertFilesOwnedByUser($folder, [$file], $username);
719 }
720
721 $storage = StorageRegistry::getAdapter();
722 $baseDir = rtrim(SourceContext::uploadRoot(), '/\\');
723 $dir = ($folder === 'root')
724 ? $baseDir
725 : $baseDir . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $folder);
726 $path = $dir . DIRECTORY_SEPARATOR . $file;
727
728 $stat = $storage->stat($path);
729 if ($stat === null || ($stat['type'] ?? '') !== 'file') {
730 throw new RuntimeException('File not found.', 404);
731 }
732
733 $size = max(0, (int)($stat['size'] ?? 0));
734 if ($size > self::MAX_READ_FILE_SIZE_BYTES) {
735 throw new RuntimeException('File is too large for AI text preview.', 413);
736 }
737
738 $raw = $storage->read($path, $maxBytes, 0);
739 if (!is_string($raw)) {
740 throw new RuntimeException('Failed to read file.', 500);
741 }
742 if ($raw !== '' && strpos($raw, "\0") !== false) {
743 throw new RuntimeException('File appears to be binary; text preview is unavailable.', 415);
744 }
745
746 $content = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $raw);

Callers 1

dispatchMethod · 0.95

Calls 15

withSourceContextMethod · 0.95
normalizeFolderMethod · 0.95
normalizeFileNameMethod · 0.95
boundedIntMethod · 0.95
assertFolderScopeMethod · 0.95
usernameMethod · 0.80
permissionsMethod · 0.80
canReadMethod · 0.80
hasGrantMethod · 0.80
getAdapterMethod · 0.80
ownsFolderOrAncestorMethod · 0.45

Tested by

no test coverage detected