diff --git a/Gemfile.lock b/Gemfile.lock index 4c9ee4f..7e9be44 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -16,19 +16,19 @@ GEM base64 (0.3.0) bigdecimal (3.3.1) colorator (1.1.0) - concurrent-ruby (1.3.5) + concurrent-ruby (1.3.6) csv (3.3.5) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) eventmachine (1.2.7) - ffi (1.17.2) + ffi (1.17.3) forwardable-extended (2.6.0) google-protobuf (4.33.2) bigdecimal rake (>= 13) http_parser.rb (0.8.0) - i18n (1.14.7) + i18n (1.14.8) concurrent-ruby (~> 1.0) jekyll (4.4.1) addressable (~> 2.4) @@ -60,7 +60,7 @@ GEM nokogiri (~> 1.12) jekyll-watch (2.2.1) listen (~> 3.0) - json (2.17.1) + json (2.18.0) kramdown (2.5.1) rexml (>= 3.3.9) kramdown-parser-gfm (1.1.0) @@ -74,7 +74,7 @@ GEM mercenary (0.4.0) mini_portile2 (2.8.9) nio4r (2.7.5) - nokogiri (1.18.10) + nokogiri (1.19.0) mini_portile2 (~> 2.8.2) racc (~> 1.4) parallel (1.27.0) @@ -83,7 +83,7 @@ GEM racc pathutil (0.16.2) forwardable-extended (~> 2.6) - prism (1.6.0) + prism (1.7.0) public_suffix (7.0.0) puma (7.1.0) nio4r (~> 2.0) @@ -97,7 +97,7 @@ GEM ffi (~> 1.0) regexp_parser (2.11.3) rexml (3.4.4) - rouge (4.6.1) + rouge (4.7.0) rubocop (1.81.7) json (~> 2.3) language_server-protocol (~> 3.17.0.2) @@ -109,13 +109,13 @@ GEM rubocop-ast (>= 1.47.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.48.0) + rubocop-ast (1.49.0) parser (>= 3.3.7.2) - prism (~> 1.4) - rubocop-performance (1.25.0) + prism (~> 1.7) + rubocop-performance (1.26.1) lint_roller (~> 1.1) rubocop (>= 1.75.0, < 2.0) - rubocop-ast (>= 1.38.0, < 2.0) + rubocop-ast (>= 1.47.1, < 2.0) ruby-progressbar (1.13.0) safe_yaml (1.0.5) sass-embedded (1.94.2) @@ -130,9 +130,9 @@ GEM standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.8.0) + standard-performance (1.9.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.25.0) + rubocop-performance (~> 1.26.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) unicode-display_width (2.6.0) diff --git a/_scalingo_api/events.md b/_scalingo_api/events.md index 6c9d5dc..c8d7bf5 100644 --- a/_scalingo_api/events.md +++ b/_scalingo_api/events.md @@ -2111,6 +2111,200 @@ Example object: --- row --- +* **Project transfer invitation event base** + +_When:_ Common attributes for project transfer invitation events. + +{:.table} +| field | type | description | +| ----------------------------- | ------ | --------------------------------------------- | +| transfer_invitation_id | string | ID of the transfer invitation | +| invited_user.id | string | ID of the invited collaborator | +| invited_user.email | string | Email of the invited collaborator | +| invited_user.username | string | Username of the invited collaborator | +| inviter.id | string | ID of the inviter | +| inviter.email | string | Email of the inviter | +| inviter.username | string | Username of the inviter | +| status | string | Invitation status | +| status_reason | string | Reason of transfer action failure | +| expires_at | date | Expiration date of the invitation | + +--- row --- + +* **Accept project transfer invitation event** + +_When:_ A project transfer invitation is accepted +`type=accept_project_transfer_invitation` + +||| col ||| + +Example object: + +```json +{ + "id": "650312574002c001afcdf988", + "created_at": "2023-09-14T14:01:59.916Z", + "project_id": "649e9d0389bca600016ea61b", + "project_name": "project-1", + "type": "accept_project_transfer_invitation", + "user": { + "username": "alice", + "email": "alice@example.com", + "id": "us-0e6d8e46-5cd0-42a4-acba-372b2be605ac" + }, + "type_data": { + "transfer_invitation_id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "accepted", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00" + } +} +``` + +--- row --- + +* **Accept project transfer invitation error event** + +_When:_ Accepting a project transfer invitation fails +`type=accept_project_transfer_invitation_error` + +{:.table} +| field | type | description | +| ----- | ------ | -------------------------------- | +| error | string | Error message for the failure | + +||| col ||| + +Example object: + +```json +{ + "id": "650312574002c001afcdf988", + "created_at": "2023-09-14T14:01:59.916Z", + "project_id": "649e9d0389bca600016ea61b", + "project_name": "project-1", + "type": "accept_project_transfer_invitation_error", + "user": { + "username": "alice", + "email": "alice@example.com", + "id": "us-0e6d8e46-5cd0-42a4-acba-372b2be605ac" + }, + "type_data": { + "transfer_invitation_id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "failed", + "status_reason": "Transfer ownership failed", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "error": "Project transfer invitation already expired." + } +} +``` + +--- row --- + +* **Cancel project transfer invitation event** + +_When:_ A project transfer invitation is canceled by the inviter +`type=cancel_project_transfer_invitation` + +||| col ||| + +Example object: + +```json +{ + "id": "650312574002c001afcdf988", + "created_at": "2023-09-14T14:01:59.916Z", + "project_id": "649e9d0389bca600016ea61b", + "project_name": "project-1", + "type": "cancel_project_transfer_invitation", + "user": { + "username": "john", + "email": "user@example.com", + "id": "us-0e6d8e46-5cd0-42a4-acba-372b2be605ac" + }, + "type_data": { + "transfer_invitation_id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "canceled", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00" + } +} +``` + +--- row --- + +* **Decline project transfer invitation event** + +_When:_ A project transfer invitation is declined by the invited collaborator +`type=decline_project_transfer_invitation` + +||| col ||| + +Example object: + +```json +{ + "id": "650312574002c001afcdf988", + "created_at": "2023-09-14T14:01:59.916Z", + "project_id": "649e9d0389bca600016ea61b", + "project_name": "project-1", + "type": "decline_project_transfer_invitation", + "user": { + "username": "alice", + "email": "alice@example.com", + "id": "us-0e6d8e46-5cd0-42a4-acba-372b2be605ac" + }, + "type_data": { + "transfer_invitation_id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "invited_user": { + "id": "54100245736f7563d5000000", + "username": "alice", + "email": "alice@example.com" + }, + "inviter": { + "id": "54100245736f7563d5000000", + "username": "john", + "email": "user@example.com" + }, + "status": "declined", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00" + } +} +``` + +--- row --- + * **Project Deleted** _When:_ A project has been deleted diff --git a/_scalingo_api/projects.md b/_scalingo_api/projects.md index 0f795aa..4769c37 100644 --- a/_scalingo_api/projects.md +++ b/_scalingo_api/projects.md @@ -291,3 +291,292 @@ Returns 204 No Content ```json {} ``` + +--- row --- + +## Project transfer invitations + +--- row --- + +Project transfer invitations let a project owner transfer ownership to another collaborator. + + +**Transfer invitation attributes** + +{:.table} +| field | type | description | +| --------------- | ------- | -------------------------------------------------------------------------- | +| id | string | unique ID of the invitation | +| project_id | string | ID of the project targeted by the transfer | +| invited_user_id | string | invited collaborator | +| invited_user_name | string | username of the invited collaborator | +| inviter_user_id | string | user who created the invitation | +| status | string | one of `pending`, `accepted`, `declined`, `canceled`, `failed` | +| status_reason | string | reason of transfer action failure | +| expires_at | date | expiration date of the invitation | +| created_at | date | creation date | +| updated_at | date | last update date | + +||| col ||| + +Example object: + +```json +{ + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", + "status": "pending", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T10:17:52.690+02:00" +} +``` + +--- row --- + +## List all your project transfer invitations + +--- row --- + +`GET https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations` + +By default only not expired `pending` invitations are returned. Pass the `status` query parameter (for example `?status=all`) to disable the pending-only filter. + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X GET https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations +``` + +Returns 200 OK + +```json +{ + "transfer_invitations": [ + { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", + "status": "pending", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T10:17:52.690+02:00" + } + ] +} +``` + +--- row --- + +## Get a project transfer invitation + +--- row --- + +`GET https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]` + +Retrieve a specific project transfer invitation. The invitation is visible to the inviter or the invited collaborator. + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X GET https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef +``` + +Returns 200 OK + +```json +{ + "transfer_invitation": { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", + "status": "pending", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T10:17:52.690+02:00" + } +} +``` + +--- row --- + +## Create a project transfer invitation + +--- row --- + +`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations` + +Project owners can create a transfer invitation for a collaborator who has access to all applications in the project. The API sets the expiration (`expires_at`) to `now + 3 days` and fails if a `pending` invitation already exists for the project. + +### Parameters + +* `transfer_invitation.invited_user_id`: ID of the collaborator to invite + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations -d \ + '{ + "transfer_invitation": { + "invited_user_id": "54100245736f7563d5000000" + } + }' +``` + +Returns 201 Created + +```json +{ + "transfer_invitation": { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", + "status": "pending", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T10:17:52.690+02:00" + } +} +``` + +--- row --- + +## Accept a project transfer invitation + +--- row --- + +`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]/accept` + +The invited collaborator can accept a project transfer invitation. + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef/accept +``` + +Returns 200 OK + +```json +{ + "transfer_invitation": { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", + "status": "accepted", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T11:00:00.000+02:00" + } +} +``` + +--- row --- + +## Decline a project transfer invitation + +--- row --- + +`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]/decline` + +The invited collaborator can decline a project transfer invitation. + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef/decline +``` + +Returns 200 OK + +```json +{ + "transfer_invitation": { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", + "status": "declined", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T11:00:00.000+02:00" + } +} +``` + +--- row --- + +## Cancel a project transfer invitation + +--- row --- + +`POST https://$SCALINGO_API_URL/v1/projects/[:project_id]/transfer_invitations/[:id]/cancel` + +The project's owner can cancel a project transfer invitation. + +||| col ||| + +Example request + +```shell +curl -H "Accept: application/json" -H "Content-Type: application/json" \ + -H "Authorization: Bearer $BEARER_TOKEN" \ + -X POST https://$SCALINGO_API_URL/v1/projects/pr-82a3cac5-9b25-473e-b33d-6272b87e636f/transfer_invitations/tin-01234567-89ab-cdef-0123-456789abcdef/cancel +``` + +Returns 200 OK + +```json +{ + "transfer_invitation": { + "id": "tin-01234567-89ab-cdef-0123-456789abcdef", + "project_id": "pr-82a3cac5-9b25-473e-b33d-6272b87e636f", + "invited_user_id": "54100245736f7563d5000000", + "invited_user_name": "alice", + "inviter_user_id": "54100245736f7563d5000000", + "status": "canceled", + "status_reason": "", + "expires_at": "2014-09-13T10:17:52.690+02:00", + "created_at": "2014-09-10T10:17:52.690+02:00", + "updated_at": "2014-09-10T11:00:00.000+02:00" + } +} +```