﻿---
title: "GroupImageRepository"
summary: API reference for GroupImageRepository
status: draft
owner: SAIF.Core documentation team
last_reviewed: 2026-09-24
library: SAIF.Data.NHibernate
reference_type: package
---


# GroupImageRepository

> **âš  High-severity security finding (SC-SDN-01):** `GetFilteredImageGroups`' deleted-image filter is inverted relative to the deletion convention used elsewhere in the codebase. See Behavioral notes and [Security and authorization](../../security-authorization.md) before relying on this method for access control.

`GroupImageRepository` is the `RepositoryBase<ImageGroup>` implementation backing group image search and soft-delete, and it is the subject of this library's highest-severity security finding: its in-memory deleted-image filter (`ImageDeleteCode != null || CanUserSeeDeletedImages`) is inverted, so users without the `GroupImagingDeleted` permission are shown soft-deleted images while never-deleted images with a null delete code are hidden (SC-SDN-01, [Security and authorization](../../security-authorization.md)). Both visibility filters (deleted and confidential) run in memory after `ToList()`, so every image in scope is loaded into the process before filtering (SC-SDN-02).

## Purpose
- Retrieve a single `ImageGroup` by id, with existence-check helpers (`ImageFound`, `GetImageGroupOrDefault`).
- Soft-delete an image by setting its `ImageDeleteCode` to `"Y"` and stamping the update user/date, only if it is not already deleted, per [SDN-BR-040](../../business-rules.md#sdn-br-040-group-image-delete-is-a-soft-delete).
- Search group images by group/parent group, category, document type, create user, and date range, applying sentinel-value "no filter" semantics ([SDN-BR-041](../../business-rules.md#sdn-br-041-filter-sentinels-%22---%22)) and deleted/confidential visibility rules ([SDN-BR-042](../../business-rules.md#sdn-br-042-deleted-images-are-visible-only-to-users-permitted-to-see-deleted-images), [SDN-BR-043](../../business-rules.md#sdn-br-043-confidential-images-are-visible-only-to-users-permitted-to-see-confidential-images)) — subject to the SC-SDN-01 inversion noted above.

## Context
- Namespace: `SAIF.Data.NHibernate.Repositories.Groups`
- Assembly/package: `SAIF.Data.NHibernate` (ships inside the `SAIF.SAIFCode.Core` NuGet package)
- Base class: `RepositoryBase<ImageGroup>` from `SAIF.Framework.Data.NHibernate` (external, resolved via Legends CLI — see Inherited public members below).
- Implements: `IGroupImageRepository`, defined in `SAIF.Data.Interfaces.Repositories.Groups`.

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| GroupImageRepository(NHibernateUnitOfWork) | `public GroupImageRepository(NHibernateUnitOfWork uow)` | Constructor; passes `uow` to the `RepositoryBase<ImageGroup>` base. |
| ImageFound | `public bool ImageFound(long groupImageId)` | Returns `true` if an `ImageGroup` with the given id exists, by calling `GetImageGroupOrDefault` and checking for a non-null result ([SQL-022](../../sql/SQL-022-group-image-repository-image-found.md)). |
| Delete | `public void Delete(ImageDelete imageDelete)` | Loads the `ImageGroup` for `imageDelete.ImageGroupId`; if its `Image.ImageDeleteCode` is blank/null/`" "`, sets it to `"Y"` and stamps `UpdateUser`/`UpdateDate` from `imageDelete`. No-op (does not re-stamp) if already marked deleted ([SDN-BR-040](../../business-rules.md#sdn-br-040-group-image-delete-is-a-soft-delete), [SQL-054](../../sql/SQL-054-group-image-repository-delete.md)). Does not check `CanUserEditImages`; enforcement is expected in the caller (SC-SDN-06, [Security and authorization](../../security-authorization.md)). |
| GetImageGroup | `public ImageGroup GetImageGroup(long groupImageId)` | Returns the single `ImageGroup` matching `groupImageId` via `Session.Query<ImageGroup>().Single()`, throwing if none exists. Applies neither the confidential nor the deleted-image visibility filter ([SQL-023](../../sql/SQL-023-group-image-repository-get-image-group.md); see Security and authorization). |
| GetImageGroupOrDefault | `public ImageGroup GetImageGroupOrDefault(long groupImageId)` | Same as `GetImageGroup` but returns `null` instead of throwing when no match exists ([SQL-024](../../sql/SQL-024-group-image-repository-get-image-group-or-default.md); applies neither visibility filter — see Security and authorization). |
| GetFilteredImageGroups | `public IEnumerable<ImageGroup> GetFilteredImageGroups(string groupId, ImageFilterCriteria filter)` | Returns `ImageGroup`s for the given group/parent-group id, filtered by category, document type, create user, and date range (sentinel values mean "no filter", [SDN-BR-041](../../business-rules.md#sdn-br-041-filter-sentinels-%22---%22)), then applies the deleted-image filter (`ImageDeleteCode != null \|\| filter.CanUserSeeDeletedImages`, inverted — see SC-SDN-01) and the confidential-image filter (`SecurityLevel == NonConfidentialSecurityLevel \|\| filter.CanUserSeeConfidentialImages`, [SDN-BR-043](../../business-rules.md#sdn-br-043-confidential-images-are-visible-only-to-users-permitted-to-see-confidential-images)) in memory after materializing the query with `ToList()` ([SQL-025](../../sql/SQL-025-group-image-repository-get-filtered-image-groups.md)). |

## Inherited public members

Members in this section are inherited from `RepositoryBase<ImageGroup>` in `SAIF.Framework.Data.NHibernate`. They are available on this type through inheritance.

| Member | Signature | Purpose | Origin |
| --- | --- | --- | --- |
| Add | `public void Add(ImageGroup entity)` | Registers a new `ImageGroup` entity for insertion on the next unit-of-work commit.† | `SAIF.Framework.Data.NHibernate` — `RepositoryBase<ImageGroup>` |
| Update | `public void Update(ImageGroup entity)` | Marks an existing `ImageGroup` entity as modified for the next unit-of-work commit.† | `SAIF.Framework.Data.NHibernate` — `RepositoryBase<ImageGroup>` |
| Delete(ImageGroup) | `public void Delete(ImageGroup entity)` | Registers an `ImageGroup` entity for deletion on the next unit-of-work commit; distinct from this type's own `Delete(ImageDelete)` overload above, which performs a soft delete instead.† | `SAIF.Framework.Data.NHibernate` — `RepositoryBase<ImageGroup>` |
| Query | `public IQueryable<ImageGroup> Query()` | Returns a LINQ-queryable session projection over `ImageGroup` for building ad hoc filters.† | `SAIF.Framework.Data.NHibernate` — `RepositoryBase<ImageGroup>` |
| Get | `public ImageGroup Get(object id)` | Loads an `ImageGroup` by primary key, returning `null` if not found.† | `SAIF.Framework.Data.NHibernate` — `RepositoryBase<ImageGroup>` |
| Load | `public ImageGroup Load(object id)` | Loads an `ImageGroup` by primary key as a (possibly proxied) reference, throwing if not found.† | `SAIF.Framework.Data.NHibernate` — `RepositoryBase<ImageGroup>` |
| SystemDate | `public DateTime SystemDate { get; }` | Current system date/time as tracked by the underlying session/unit of work.† | `SAIF.Framework.Data.NHibernate` — `RepositoryBase<ImageGroup>` |

## Behavioral notes
- **SC-SDN-01 (High):** `GetFilteredImageGroups` keeps an image when `ImageDeleteCode != null || CanUserSeeDeletedImages`. Elsewhere (`GroupImageRepository.Delete`, `ImagingDataModelExtensions.IsDeleted`), null/empty/`" "` means *not* deleted and `"Y"` means deleted — so this predicate is backwards: it returns soft-deleted images (`"Y"`, non-null) to users without `CanUserSeeDeletedImages`, while hiding never-deleted images (`null` code). `Services/SAIF.Services/Groups/Imaging/ImageService.GetImages` relies on this filter and applies no compensating filter of its own; by contrast, `Services/SAIF.Services/Agencies/Imaging/ImageService.cs` uses the correct `!Image.IsDeleted() || CanUserSeeDeletedImages` pattern. This is an authorization bypass for deleted group images (`saif-data-nhibernate-security-analysis.md` SC-SDN-01).
- **SC-SDN-02 (Medium):** Both the deleted and confidential filters in `GetFilteredImageGroups` run in memory after `ToList()`, so every image in the group is loaded before filtering — a performance and exposure-surface concern.
- `GetImageGroup`, `GetImageGroupOrDefault`, and `ImageFound` apply neither the confidential nor the deleted filter; any caller exposing an image by id via these members must enforce visibility itself (DLA-SDN-01/02, [Security and authorization](../../security-authorization.md)).
- `Delete` performs a soft delete only and does not check `CanUserEditImages`; enforcement of edit permission is expected in the caller (SC-SDN-06).

## Constraints and usage notes
- Do not treat `GetFilteredImageGroups`' current deleted-image behavior as correct access control until SC-SDN-01 is fixed or confirmed intentional; verify with the owning team before relying on it in a new caller.
- `GetImageGroup` throws if no matching `ImageGroup` exists; use `GetImageGroupOrDefault` or `ImageFound` first when existence is not guaranteed.

> **Note:** Statements marked with `†` are derived from dependency library
> documentation via the Legends CLI. Statements marked with `*` were inferred
> from code structure or contextual evidence. Statements marked with `**` could
> not be confirmed; treat as unknown until verified.

## Related documentation
- [Index](../../index.md)
- [Overview](../../overview.md)
- [Architecture](../../architecture.md)
- [Dependencies](../../dependencies.md)
- [Operations and processes](../../operations-processes.md)
- [Business rules](../../business-rules.md)
- [Database tables](../../database-tables.md)
- [SQL catalog](../../sql/index.md)
- [Procedures](../../procedures/index.md)
- [Security and authorization](../../security-authorization.md)
- [API reference](../index.md)

## Sources
- `Data/SAIF.Data.NHibernate/Repositories/Groups/GroupImageRepository.cs`
