Related samples table is not permission filtered - names samples the user can't view
- Dominant language
- Python
- Stars
- 30
- Forks
- 3
- Avg merge
- 9h 28m
- Merged PRs (30d)
- 42
Description
🤖 Written by Claude
The related samples table on the sample page is not permission filtered, so it names samples the viewer has no access to.
`snpdb/models/models_somalier.py:SomalierRelatePairs.get_for_sample` is the whole query:
```python
@staticmethod
def get_for_sample(sample: Sample):
return SomalierRelatePairs.objects.filter(Q(sample_a=sample) | Q(sample_b=sample))
```
No `Sample.filter_for_user`, and `snpdb/views/views_data.py:_related_samples` feeds it straight to the template, which renders for each pair:
* `{{ related.sample }}` - `Sample.__str__` is `" ()"`, so the sample name **and** the name of a VCF the viewer may not be able to open
* the patient name, linked to `view_patient`, when the other sample has one
Following either link is correctly refused, but the names are already on the page by then. The relatedness numbers alongside them say how closely the two samples are related, which on clinical data is itself informative.
This predates the recent somalier work (#183) - that change added a Patient column and sorted the rows, but the queryset was unfiltered before it. It is the "User security for related samples" line on the #162 checklist.
### Suggested fix
There is already a pattern for this on the variant page: `snpdb/variant_sample_information.py:VariantZygosityCounts` counts every sample but only names the ones the user can see, and exposes `num_user_samples` / `has_hidden_samples` so the template can say "showing 3 of 11" without disclosing the other 8.
The related samples table wants the same shape - filter the pairs through `Sample.filter_for_user` and tell the viewer how many were hidden, rather than silently dropping rows (a duplicate sample they cannot see is still something they may need to know exists).
Worth deciding at the same time whether the count itself is safe to disclose, or whether hidden pairs should be invisible entirely.
### Note
`settings.SOMALIER["admin_only"]` limits the whole Ancestry/Relatedness tab to superusers, which would mitigate this, but it defaults to `False` and no deployment settings file sets it - `variantgrid/settings/env/*.py` only ever set `SOMALIER["enabled"]`.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with `SomalierRelatePairs.get_for_sample` in `snpdb/models/models_somalier.py` and `_related_samples` in `snpdb/views/views_data.py`; compare the variant-page pattern in `snpdb/variant_sample_information.py`. Decide whether hidden-pair counts are safe to disclose, as the issue leaves this open. Done means the related-samples table does not reveal names or relatedness details for inaccessible samples and handles hidden pairs according to the chosen policy.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100