Skip to content

Fix organization invitation endpoints to return 201 with Location header - #51558

Open
SaadAhmed7 wants to merge 3 commits into
keycloak:mainfrom
SaadAhmed7:fix/org-invitation-return-201-with-location
Open

Fix organization invitation endpoints to return 201 with Location header#51558
SaadAhmed7 wants to merge 3 commits into
keycloak:mainfrom
SaadAhmed7:fix/org-invitation-return-201-with-location

Conversation

@SaadAhmed7

Copy link
Copy Markdown

Summary

Closes #51298

The organization invitation endpoints (invite-user, invite-existing-user, and resend) were returning HTTP 204 No Content. Per REST conventions, creating a resource should return HTTP 201 Created with a Location header pointing to the newly created resource.

Changes

  • OrganizationInvitationResource.sendInvitation(): Changed Response.noContent().build() to Response.created(location).build(), where the Location URI points to /admin/realms/{realm}/organizations/{orgId}/invitations/{invitationId}
  • OpenAPI annotations: Updated @APIResponse annotations on inviteUser, inviteExistingUser, and resendInvitation from 204 No Content to 201 Created
  • The Location URI is built using AdminRoot.realmsUrl() following the existing Keycloak pattern used in other admin resources (OrganizationsResource, UsersResource, ClientsResource, etc.)

Affected endpoints

Endpoint Before After
POST /admin/realms/{realm}/organizations/{orgId}/members/invite-user 204 No Content 201 Created + Location
POST /admin/realms/{realm}/organizations/{orgId}/members/invite-existing-user 204 No Content 201 Created + Location
POST /admin/realms/{realm}/organizations/{orgId}/invitations/{id}/resend 204 No Content 201 Created + Location

…tion header

The invitation endpoints (invite-user, invite-existing-user, resend) were
returning HTTP 204 No Content. Per REST conventions, resource creation
should return 201 Created with a Location header pointing to the new
resource. The Location header now points to the invitation resource at
/admin/realms/{realm}/organizations/{orgId}/invitations/{invitationId}.

Closes keycloak#51298

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@SaadAhmed7
SaadAhmed7 requested a review from a team as a code owner August 8, 2026 13:28
Copilot AI balanced review requested due to automatic review settings August 8, 2026 13:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates organization invitation creation and resend endpoints to follow REST resource-creation semantics.

Changes:

  • Returns 201 Created with the new invitation’s Location.
  • Updates OpenAPI response annotations from 204 to 201.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
OrganizationMemberResource.java Updates invitation endpoint response documentation.
OrganizationInvitationResource.java Builds the invitation URI and returns it with 201 responses.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

.path("invitations")
.path(invitation.getId())
.build();
return Response.created(location).build();
Update OrganizationInvitationManagementTest and
OrganizationInvitationLinkTest to expect HTTP 201 Created for
invite-user, invite-existing-user, and resend endpoints. Delete
endpoint assertions remain at 204 No Content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 13:38
@SaadAhmed7
SaadAhmed7 requested review from a team as code owners August 8, 2026 13:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (1)

services/src/main/java/org/keycloak/organization/admin/resource/OrganizationInvitationResource.java:216

  • The defining part of the new contract is still untested: the updated tests only assert 201, so a missing or malformed Location header (including one that retains the old ID after resend) would pass. Add assertions for all three endpoints that response.getLocation() targets /admin/realms/{realm}/organizations/{orgId}/invitations/{newInvitationId}, with the resend assertion using the replacement invitation ID.
        return Response.created(location).build();

Verify that invite and resend responses include a non-null Location
header pointing to the correct invitations resource path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 9, 2026 09:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (1)

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/organization/admin/OrganizationInvitationManagementTest.java:159

  • The resend test only checks a path prefix, so it still passes if Location contains the old or an unrelated invitation ID. Capture the returned path and compare its final segment with newInvitationId, which is the key resend requirement from #51298.
            assertThat(response.getLocation(), notNullValue());
            assertThat(response.getLocation().getPath(), containsString("/organizations/" + organizationId + "/invitations/"));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Organization invitation creation and resend endpoints should return 201 with the created invitation location

2 participants