Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
3562d69d
Commit
3562d69d
authored
Jan 19, 2021
by
Jackie Fraser
Committed by
Rémy Coutable
Jan 19, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add API command to remove pending member invitation
parent
434987d1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
127 additions
and
4 deletions
+127
-4
changelogs/unreleased/add-api-command-to-delete-pending-invitation.yml
...released/add-api-command-to-delete-pending-invitation.yml
+5
-0
doc/api/invitations.md
doc/api/invitations.md
+24
-0
lib/api/invitations.rb
lib/api/invitations.rb
+18
-0
spec/requests/api/invitations_spec.rb
spec/requests/api/invitations_spec.rb
+80
-4
No files found.
changelogs/unreleased/add-api-command-to-delete-pending-invitation.yml
0 → 100644
View file @
3562d69d
---
title
:
Add API command to remove pending member invitation
merge_request
:
51134
author
:
type
:
added
doc/api/invitations.md
View file @
3562d69d
...
...
@@ -106,3 +106,27 @@ Example response:
},
]
```
## Delete an invitation to a group or project
Deletes a pending invitation by email address.
```
plaintext
DELETE /groups/:id/invitations/:email
DELETE /projects/:id/invitations/:email
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
|
`id`
| integer/string | yes | The ID or
[
URL-encoded path of the project or group
](
README.md#namespaced-path-encoding
)
owned by the authenticated user |
|
`email`
| string | yes | The email address to which the invitation was previously sent |
```
shell
curl
--request
DELETE
--header
"PRIVATE-TOKEN: <your_access_token>"
"https://gitlab.example.com/api/v4/groups/55/invitations/email@example.org"
curl
--request
DELETE
--header
"PRIVATE-TOKEN: <your_access_token>"
"https://gitlab.example.com/api/v4/projects/55/invitations/email@example.org"
```
-
Returns
`204`
and no content on success.
-
Returns
`403`
forbidden if unauthorized to delete the invitation.
-
Returns
`404`
not found if authorized and no invitation is found for that email address.
-
Returns
`409`
if the request was valid but the invitation could not be deleted.
lib/api/invitations.rb
View file @
3562d69d
...
...
@@ -48,6 +48,24 @@ module API
present_member_invitations
invitations
end
desc
'Removes an invitation from a group or project.'
params
do
requires
:email
,
type:
String
,
desc:
'The email address of the invitation'
end
delete
":id/invitations/:email"
,
requirements:
{
email:
/[^\/]+/
}
do
source
=
find_source
(
source_type
,
params
[
:id
])
invite_email
=
params
[
:email
]
authorize_admin_source!
(
source_type
,
source
)
invite
=
retrieve_member_invitations
(
source
,
invite_email
).
first
not_found!
unless
invite
destroy_conditionally!
(
invite
)
do
::
Members
::
DestroyService
.
new
(
current_user
,
params
).
execute
(
invite
)
unprocessable_entity!
unless
invite
.
destroyed?
end
end
end
end
end
...
...
spec/requests/api/invitations_spec.rb
View file @
3562d69d
...
...
@@ -30,6 +30,10 @@ RSpec.describe API::Invitations do
api
(
"/
#{
source
.
model_name
.
plural
}
/
#{
source
.
id
}
/invitations"
,
user
)
end
def
invite_member_by_email
(
source
,
source_type
,
email
,
created_by
)
create
(
:"
#{
source_type
}
_member"
,
invite_token:
'123'
,
invite_email:
email
,
source:
source
,
user:
nil
,
created_by:
created_by
)
end
shared_examples
'POST /:source_type/:id/invitations'
do
|
source_type
|
context
"with :source_type ==
#{
source_type
.
pluralize
}
"
do
it_behaves_like
'a 404 response when source is private'
do
...
...
@@ -280,10 +284,6 @@ RSpec.describe API::Invitations do
expect
(
json_response
.
first
[
'created_by_name'
]).
to
eq
(
developer
.
name
)
expect
(
json_response
.
first
[
'user_name'
]).
to
eq
(
nil
)
end
def
invite_member_by_email
(
source
,
source_type
,
email
,
created_by
)
create
(
:"
#{
source_type
}
_member"
,
invite_token:
'123'
,
invite_email:
email
,
source:
source
,
user:
nil
,
created_by:
created_by
)
end
end
end
...
...
@@ -298,4 +298,80 @@ RSpec.describe API::Invitations do
let
(
:source
)
{
group
}
end
end
shared_examples
'DELETE /:source_type/:id/invitations/:email'
do
|
source_type
|
def
invite_api
(
source
,
user
,
email
)
api
(
"/
#{
source
.
model_name
.
plural
}
/
#{
source
.
id
}
/invitations/
#{
email
}
"
,
user
)
end
context
"with :source_type ==
#{
source_type
.
pluralize
}
"
do
let!
(
:invite
)
{
invite_member_by_email
(
source
,
source_type
,
developer
.
email
,
developer
)
}
it_behaves_like
'a 404 response when source is private'
do
let
(
:route
)
{
delete
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/invitations/
#{
invite
.
invite_email
}
"
,
stranger
)
}
end
context
'when authenticated as a non-member or member with insufficient rights'
do
%i[access_requester stranger]
.
each
do
|
type
|
context
"as a
#{
type
}
"
do
it
'returns 403'
do
user
=
public_send
(
type
)
delete
invite_api
(
source
,
user
,
invite
.
invite_email
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
end
end
context
'when authenticated as a member and deleting themself'
do
it
'does not delete the member'
do
expect
do
delete
invite_api
(
source
,
developer
,
invite
.
invite_email
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
.
not_to
change
{
source
.
members
.
count
}
end
end
context
'when authenticated as a maintainer/owner'
do
it
'deletes the member and returns 204 with no content'
do
expect
do
delete
invite_api
(
source
,
maintainer
,
invite
.
invite_email
)
expect
(
response
).
to
have_gitlab_http_status
(
:no_content
)
end
.
to
change
{
source
.
members
.
count
}.
by
(
-
1
)
end
end
it
'returns 404 if member does not exist'
do
delete
invite_api
(
source
,
maintainer
,
non_existing_record_id
)
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
it
'returns 422 for a valid request if the resource was not destroyed'
do
allow_next_instance_of
(
::
Members
::
DestroyService
)
do
|
instance
|
allow
(
instance
).
to
receive
(
:execute
).
with
(
invite
).
and_return
(
invite
)
end
delete
invite_api
(
source
,
maintainer
,
invite
.
invite_email
)
expect
(
response
).
to
have_gitlab_http_status
(
:unprocessable_entity
)
end
end
end
describe
'DELETE /projects/:id/inviations/:email'
do
it_behaves_like
'DELETE /:source_type/:id/invitations/:email'
,
'project'
do
let
(
:source
)
{
project
}
end
end
describe
'DELETE /groups/:id/inviations/:email'
do
it_behaves_like
'DELETE /:source_type/:id/invitations/:email'
,
'group'
do
let
(
:source
)
{
group
}
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment