Skip to content

feat: recognize symbolic links#309

Merged
allison-truhlar merged 39 commits intomainfrom
recognize-symbolic-links
Feb 12, 2026
Merged

feat: recognize symbolic links#309
allison-truhlar merged 39 commits intomainfrom
recognize-symbolic-links

Conversation

@allison-truhlar
Copy link
Collaborator

@allison-truhlar allison-truhlar commented Feb 4, 2026

Clickup id: 86aewngc6

This PR adds full support for symlinks in the file browser of Fileglancer, with visual distinction and navigation. Users can identify symlinks by a link icon and "Symlink" type label in the file table and the properties panel. Broken symlinks show a broken link icon. Clicking on a working symlink navigates to its target location within the same or different file share.

This PR also contains two related, but not symlink functionality/display only, changes:

  1. Data link creation now correctly targets the selected item in the file browser, if applicable. Previously, creating a data link for a subdirectory or symlink selected from its parent would create the link for the parent directory instead. Viewer icons (Neuroglancer, etc.) always create data links for the current browsed directory, even when a subdirectory row is selected in the properties panel.
  2. Pressing 'escape' now clears the selected row and reverts the properties panel data to the current directory.

To verify working symlink detection, display, and navigation:

  • In the dev Fileglancer launched from this branch, navigate to /nrs/cellmap/data/jrc_22ak351-leaf-2l. You should see the N5 directory identified as a symlink. Clicking on the name, you can navigate to the symlinked path.
  • If you navigate to the same directory in the production Fileglancer (here), the N5 directory is identified as a regular Folder. If you click on the name, the file browser can't navigate to it. The breadcrumbs display the error "Error loading path" and eventually the file table shows the error "Folder not found."

Tests

  • Added tests in tests/test_filestore.py covering symlink detection, same-share/cross-share resolution, relative symlinks, broken symlink handling, and symlinks to directories
  • Added Playwright tests for symlinks in frontend/ui-tests/tests/symlink-navigation.spec.ts covering icon display, navigation, type labeling, context menu, broken symlinks, and properties panel content
  • Added Playwright tests in frontend/ui-tests/tests/data-link-operations.spec.ts verifying data link targets the selected subdirectory (not parent) and viewer icon targets the current directory (not selected row)

@krokicki

allison-truhlar and others added 20 commits February 9, 2026 10:37
- Add is_symlink and symlink_target_fsp fields to FileInfo model
- Implement symlink detection in from_stat method using lstat
- Resolve symlink targets to file share paths when session is provided
- Add session parameter to get_file_info, yield_file_infos, and helper methods
Update /api/files endpoint to open a database session and pass it to
filestore methods, enabling symlink target resolution.
Add 7 comprehensive pytest test cases for symlink support:
- Symlink detection and basic properties
- Same-share symlink resolution via directory listing
- Cross-share symlink resolution via directory listing
- Relative symlink resolution
- Symlink listing in directory (yield_file_infos)
- Broken symlink handling (filtered from listings)
- Symlink to directory detection

All tests use mocked database sessions and verify:
- is_symlink flag is correctly set
- symlink_target_fsp contains correct fsp_name and subpath
- Broken symlinks are skipped in directory listings
- Symlinks to directories preserve is_dir=True
Add comprehensive E2E tests for symlink support:
- Display symlink icon and type in file table
- Navigate to symlink target within same share
- Directory symlinks display as Symlink type (not Folder)
- Context menu works on symlinks
- Broken symlinks are not displayed
- Selection shows symlink in properties panel

Uses custom Playwright fixtures to create symlink test data.
…in path expression

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
- flagged by CodeQL
- Adds root_path parameter to _safe_readlink and from_stat to verify the symlink's parent directory is within the allowed root before calling os.readlink(). Uses parent directory check (not realpath) to preserve  cross-share symlink support.
@allison-truhlar allison-truhlar force-pushed the recognize-symbolic-links branch from 7474b38 to 4a9981e Compare February 9, 2026 15:45
Keep all filesystem I/O in the same method as the path validation
so CodeQL can trace the sanitizer to the os.stat calls.
@allison-truhlar
Copy link
Collaborator Author

Note: commit 08fff7f adds tests for these cases we discussed - can you access sensitive data from a data link to a directory that contains a symlink to a:

  • sensitive directory/file?
  • another symlink to a sensitive directory/file (ie., symlink -> symlink -> target)?

It simulates a data link by using /api/content/.

Copy link
Member

@neomorphic neomorphic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@allison-truhlar I haven't looked at the changes, but I did check out the code and create a broken symbolic link in my home directory and it is not being displayed on the site. I am guessing it is being ignored. Is there any way to show broken links in the same way that disallowed links are displayed?

@allison-truhlar
Copy link
Collaborator Author

allison-truhlar commented Feb 9, 2026

@allison-truhlar I haven't looked at the changes, but I did check out the code and create a broken symbolic link in my home directory and it is not being displayed on the site. I am guessing it is being ignored. Is there any way to show broken links in the same way that disallowed links are displayed?

@neomorphic This was added to this branch - it should look like the below. Maybe try pixi run dev-install and then launch again?
Screenshot 2026-02-09 at 6 02 44 PM

@neomorphic
Copy link
Member

@neomorphic This was added to this branch - it should look like the below. Maybe try pixi run dev-install and then launch again? Screenshot 2026-02-09 at 6 02 44 PM

I tried the dev-install and now I can see one of the broken links. I will investigate further as to why the other is not being displayed as expected.

@neomorphic
Copy link
Member

It looks like the properties panel is still labeling the type of symbolic links as 'File'
Screenshot 2026-02-10 at 09 40 58

- Adds os.path.exists(target) check before attempting file share resolution
  - Returns None immediately for broken symlinks
- Valid symlinks proceed to normal resolution logic
Copy link
Member

@neomorphic neomorphic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good to me now.

@allison-truhlar allison-truhlar changed the title fix: recognize symbolic links feat: recognize symbolic links Feb 11, 2026
@allison-truhlar
Copy link
Collaborator Author

@neomorphic The properties panel should now display the symlink (or broken symlink) info when a symlink is selected. Also, I confirmed that you can access data from a data link to symlink, including accessing data in subdirectories of the linked directory, and that you cannot access data via a data link to a symlink that points to a directory that is not in a valid file share path, as determined by the database file share paths.

@neomorphic
Copy link
Member

I can see the correct info in the properties panel now. Let's merge it

@allison-truhlar allison-truhlar merged commit 4c09664 into main Feb 12, 2026
7 checks passed
@allison-truhlar allison-truhlar deleted the recognize-symbolic-links branch February 12, 2026 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants