Class GroupsWebService

java.lang.Object
ubic.gemma.rest.GroupsWebService

@Service @Path("/groups") public class GroupsWebService extends Object
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_READ so 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 / delete run under GROUP_USER + ACL_SECURABLE_EDIT, so only group owners / admins succeed. Anonymous callers get a 401/403 at the PreAuthorize layer.

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
  • Constructor Details

  • 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 via query matches 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. With includeSummaries=true the 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 on UserService.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 — currently name (rename) and description. 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 underlying UserService.delete(UserGroup) runs under GROUP_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. memberId is the AbstractIdentifiable.getId().
    • summariesForGroupNames

      public List<GroupsWebService.GroupSummaryValueObject> summariesForGroupNames(Collection<String> groupNames)
      Public hook for DatasetsWebService so the dataset-groups route can reuse the GroupSummary projection without duplicating the mapping. Returns one summary per group name; unknown group names are skipped.