Class GroupsWebService
java.lang.Object
ubic.gemma.rest.GroupsWebService
RESTful CRUD + member management for user groups (gap §3c of
GEMMA_UI_ENDPOINT_GAP.md). The curation-UI needs a stable surface
for the existing group machinery — there is no dedicated group service in
gemma-core, so the endpoints delegate to UserManager (which mixes
GroupManager + user lookups) and UserReadService for
id-keyed lookups.
Auth model (also enforced at the service / DAO layer via
@Secured / @PreAuthorize on UserManager +
UserService):
- LIST / READ — open to authenticated users; the underlying
facade applies
AFTER_ACL_COLLECTION_READso non-readable groups are filtered out. - CREATE — authenticated.
UserService.create(UserGroup)is@Secured("GROUP_USER"). - PATCH (rename) / DELETE / member add / member remove —
authenticated;
UserService.update / deleterun underGROUP_USER + ACL_SECURABLE_EDIT, so only group owners / admins succeed. Anonymous callers get a 401/403 at thePreAuthorizelayer.
Note: the three system groups (Administrators,
Users, Agents) are protected at the DAO layer — creating /
deleting / updating them raises IllegalArgumentException, which
Jersey maps to 400.
- Author:
- paul
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classBody for POST /groups.static classLightweight per-member projection — just the fields needed to render a member-list row.static classLightweight projection for list pages — only the fields the curation UI needs to render a row.static classBody for PATCH /groups/{id}.static classSingle-group response (no members list — useGroupsWebService.GroupWithMembersValueObjectfor that).static classFull response including member summaries; used forGET /groups/{id}?includeSummaries=trueand the membership-mutating endpoints so the caller doesn't need a follow-up GET.static classBody for POST /groups/{id}/members. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionAdd a member to a group.jakarta.ws.rs.core.ResponseCreate a new group.jakarta.ws.rs.core.ResponsedeleteGroup(Long id) Delete a group.Retrieve a single group by id.List groups (paginated; offset/limit).jakarta.ws.rs.core.ResponseremoveMember(Long id, Long memberId) Remove a member from a group.summariesForGroupNames(Collection<String> groupNames) Public hook forDatasetsWebServiceso the dataset-groups route can reuse the GroupSummary projection without duplicating the mapping.Partial update — currentlyname(rename) anddescription.
-
Constructor Details
-
GroupsWebService
-
-
Method Details
-
getGroups
@GET @Produces("application/json") @PreAuthorize("isAuthenticated()") public PaginatedResponseDataObject<GroupsWebService.GroupSummaryValueObject> getGroups(@QueryParam("query") @Nullable String query, @QueryParam("offset") @DefaultValue("0") OffsetArg offsetArg, @QueryParam("limit") @DefaultValue("20") LimitArg limitArg) List groups (paginated; offset/limit). Optional name-substring filter viaquerymatches group names case-insensitively. -
getGroup
@GET @Path("/{id}") @Produces("application/json") @PreAuthorize("isAuthenticated()") public ResponseDataObject<? extends GroupsWebService.GroupValueObject> getGroup(@PathParam("id") Long id, @QueryParam("includeSummaries") @DefaultValue("false") boolean includeSummaries, @QueryParam("include_summaries") @DefaultValue("false") boolean includeSummariesLegacy) Retrieve a single group by id. WithincludeSummaries=truethe response carries lightweight member summaries; otherwise only counts. -
createGroup
@POST @Consumes("application/json") @Produces("application/json") @PreAuthorize("isAuthenticated()") public jakarta.ws.rs.core.Response createGroup(GroupsWebService.GroupCreateRequest req) Create a new group. Body:{name, description?}. The current authenticated user becomes the owner via the ACL plumbing onUserService.create(UserGroup). -
updateGroup
@PATCH @Path("/{id}") @Consumes("application/json") @Produces("application/json") @PreAuthorize("isAuthenticated()") public ResponseDataObject<GroupsWebService.GroupValueObject> updateGroup(@PathParam("id") Long id, GroupsWebService.GroupUpdateRequest req) Partial update — currentlyname(rename) anddescription. Authority modification is intentionally out of scope (admin-only via the SecurityService backchannel). -
deleteGroup
@DELETE @Path("/{id}") @Produces("application/json") @PreAuthorize("isAuthenticated()") public jakarta.ws.rs.core.Response deleteGroup(@PathParam("id") Long id) Delete a group. Soft-failing on the three system groups (400). The underlyingUserService.delete(UserGroup)runs underGROUP_USER + ACL_SECURABLE_EDIT. -
addMember
@POST @Path("/{id}/members") @Consumes("application/json") @Produces("application/json") @PreAuthorize("isAuthenticated()") public ResponseDataObject<GroupsWebService.GroupWithMembersValueObject> addMember(@PathParam("id") Long id, GroupsWebService.MemberAddRequest req) Add a member to a group. Body accepts either{username}or{userId}(one is required). Idempotent — adding an already- member returns the current group state without error. -
removeMember
@DELETE @Path("/{id}/members/{memberId}") @Produces("application/json") @PreAuthorize("isAuthenticated()") public jakarta.ws.rs.core.Response removeMember(@PathParam("id") Long id, @PathParam("memberId") Long memberId) Remove a member from a group.memberIdis theAbstractIdentifiable.getId(). -
summariesForGroupNames
public List<GroupsWebService.GroupSummaryValueObject> summariesForGroupNames(Collection<String> groupNames) Public hook forDatasetsWebServiceso the dataset-groups route can reuse the GroupSummary projection without duplicating the mapping. Returns one summary per group name; unknown group names are skipped.
-