Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-04-20 13:00:54 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-04-20 13:00:54 +0300
commit3cccd102ba543e02725d247893729e5c73b38295 (patch)
treef36a04ec38517f5deaaacb5acc7d949688d1e187 /doc/development/spam_protection_and_captcha
parent205943281328046ef7b4528031b90fbda70c75ac (diff)
Add latest changes from gitlab-org/gitlab@14-10-stable-eev14.10.0-rc42
Diffstat (limited to 'doc/development/spam_protection_and_captcha')
-rw-r--r--doc/development/spam_protection_and_captcha/graphql_api.md44
-rw-r--r--doc/development/spam_protection_and_captcha/index.md2
-rw-r--r--doc/development/spam_protection_and_captcha/rest_api.md90
-rw-r--r--doc/development/spam_protection_and_captcha/web_ui.md4
4 files changed, 116 insertions, 24 deletions
diff --git a/doc/development/spam_protection_and_captcha/graphql_api.md b/doc/development/spam_protection_and_captcha/graphql_api.md
index b47e3f84320..e3f4e9069e5 100644
--- a/doc/development/spam_protection_and_captcha/graphql_api.md
+++ b/doc/development/spam_protection_and_captcha/graphql_api.md
@@ -13,28 +13,27 @@ related to changing a model's confidential/public flag.
## Add support to the GraphQL mutations
-This implementation is very similar to the controller implementation. You create a `spam_params`
-instance based on the request, and pass it to the relevant Service class constructor.
+The main steps are:
-The three main differences from the controller implementation are:
+1. Use `include Mutations::SpamProtection` in your mutation.
+1. Create a `spam_params` instance based on the request. Obtain the request from the context
+ via `context[:request]` when creating the `SpamParams` instance.
+1. Pass `spam_params` to the relevant Service class constructor.
+1. After you create or update the `Spammable` model instance, call `#check_spam_action_response!`
+ and pass it the model instance. This call:
+ 1. Performs the necessary spam checks on the model.
+ 1. If spam is detected:
+ - Raises a `GraphQL::ExecutionError` exception.
+ - Includes the relevant information added as error fields to the response via the `extensions:` parameter.
+ For more details on these fields, refer to the section in the GraphQL API documentation on
+ [Resolve mutations detected as spam](../../api/graphql/index.md#resolve-mutations-detected-as-spam).
-1. Use `include Mutations::SpamProtection` instead of `...JsonFormatActionsSupport`.
-1. Obtain the request from the context via `context[:request]` when creating the `SpamParams`
- instance.
-1. After you create or updated the `Spammable` model instance, call `#check_spam_action_response!`
- and pass it the model instance. This call will:
- 1. Perform the necessary spam checks on the model.
- 1. If spam is detected:
- - Raise a `GraphQL::ExecutionError` exception.
- - Include the relevant information added as error fields to the response via the `extensions:` parameter.
- For more details on these fields, refer to the section on
- [Spam and CAPTCHA support in the GraphQL API](../../api/graphql/index.md#resolve-mutations-detected-as-spam).
-
- NOTE:
- If you use the standard ApolloLink or Axios interceptor CAPTCHA support described
- above, the field details are unimportant. They become important if you
- attempt to use the GraphQL API directly to process a failed check for potential spam, and
- resubmit the request with a solved CAPTCHA response.
+ NOTE:
+ If you use the standard ApolloLink or Axios interceptor CAPTCHA support described
+ above, you can ignore the field details, because they are handled
+ automatically. They become relevant if you attempt to use the GraphQL API directly to
+ process a failed check for potential spam, and resubmit the request with a solved
+ CAPTCHA response.
For example:
@@ -57,10 +56,13 @@ module Mutations
widget = service_response.payload[:widget]
check_spam_action_response!(widget)
- # If possible spam wasdetected, an exception would have been thrown by
+ # If possible spam was detected, an exception would have been thrown by
# `#check_spam_action_response!`, so the normal resolve return logic can follow below.
end
end
end
end
```
+
+Refer to the [Exploratory Testing](exploratory_testing.md) section for instructions on how to test
+CAPTCHA behavior in the GraphQL API.
diff --git a/doc/development/spam_protection_and_captcha/index.md b/doc/development/spam_protection_and_captcha/index.md
index 9b195df536d..dbe8c4aa4e9 100644
--- a/doc/development/spam_protection_and_captcha/index.md
+++ b/doc/development/spam_protection_and_captcha/index.md
@@ -16,7 +16,7 @@ To add this support, you must implement the following areas as applicable:
1. [Model and Services](model_and_services.md): The basic prerequisite
changes to the backend code which are required to add spam or CAPTCHA API and UI support
for a feature which does not yet have support.
-1. REST API (Supported, documentation coming soon): The changes needed to add
+1. [REST API](rest_api.md): The changes needed to add
spam or CAPTCHA support to Grape REST API endpoints. Refer to the related
[REST API documentation](../../api/index.md#resolve-requests-detected-as-spam).
1. [GraphQL API](graphql_api.md): The changes needed to add spam or CAPTCHA support to GraphQL
diff --git a/doc/development/spam_protection_and_captcha/rest_api.md b/doc/development/spam_protection_and_captcha/rest_api.md
new file mode 100644
index 00000000000..ad74977eb67
--- /dev/null
+++ b/doc/development/spam_protection_and_captcha/rest_api.md
@@ -0,0 +1,90 @@
+---
+stage: Manage
+group: Authentication and Authorization
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# REST API spam protection and CAPTCHA support
+
+If the model can be modified via the REST API, you must also add support to all of the
+relevant API endpoints which may modify spammable or spam-related attributes. This
+definitely includes the `POST` and `PUT` mutations, but may also include others, such as those
+related to changing a model's confidential/public flag.
+
+## Add support to the REST endpoints
+
+The main steps are:
+
+1. Add `helpers SpammableActions::CaptchaCheck::RestApiActionsSupport` in your `resource`.
+1. Create a `spam_params` instance based on the request.
+1. Pass `spam_params` to the relevant Service class constructor.
+1. After you create or update the `Spammable` model instance, call `#check_spam_action_response!`,
+ save the created or updated instance in a variable.
+1. Identify the error handling logic for the `failure` case of the request,
+ when create or update was not successful. These indicate possible spam detection,
+ which adds an error to the `Spammable` instance.
+ The error is usually similar to `render_api_error!` or `render_validation_error!`.
+1. Wrap the existing error handling logic in a
+ `with_captcha_check_rest_api(spammable: my_spammable_instance)` call, passing the `Spammable`
+ model instance you saved in a variable as the `spammable:` named argument. This call will:
+ 1. Perform the necessary spam checks on the model.
+ 1. If spam is detected:
+ - Raise a Grape `#error!` exception with a descriptive spam-specific error message.
+ - Include the relevant information added as error fields to the response.
+ For more details on these fields, refer to the section in the REST API documentation on
+ [Resolve requests detected as spam](../../api/index.md#resolve-requests-detected-as-spam).
+
+ NOTE:
+ If you use the standard ApolloLink or Axios interceptor CAPTCHA support described
+ above, you can ignore the field details, because they are handled
+ automatically. They become relevant if you attempt to use the GraphQL API directly to
+ process a failed check for potential spam, and resubmit the request with a solved
+ CAPTCHA response.
+
+Here is an example for the `post` and `put` actions on the `snippets` resource:
+
+```ruby
+module API
+ class Snippets < ::API::Base
+ #...
+ resource :snippets do
+ # This helper provides `#with_captcha_check_rest_api`
+ helpers SpammableActions::CaptchaCheck::RestApiActionsSupport
+
+ post do
+ #...
+ spam_params = ::Spam::SpamParams.new_from_request(request: request)
+ service_response = ::Snippets::CreateService.new(project: nil, current_user: current_user, params: attrs, spam_params: spam_params).execute
+ snippet = service_response.payload[:snippet]
+
+ if service_response.success?
+ present snippet, with: Entities::PersonalSnippet, current_user: current_user
+ else
+ # Wrap the normal error response in a `with_captcha_check_rest_api(spammable: snippet)` block
+ with_captcha_check_rest_api(spammable: snippet) do
+ # If possible spam was detected, an exception would have been thrown by
+ # `#with_captcha_check_rest_api` for Grape to handle via `error!`
+ render_api_error!({ error: service_response.message }, service_response.http_status)
+ end
+ end
+ end
+
+ put ':id' do
+ #...
+ spam_params = ::Spam::SpamParams.new_from_request(request: request)
+ service_response = ::Snippets::UpdateService.new(project: nil, current_user: current_user, params: attrs, spam_params: spam_params).execute(snippet)
+
+ snippet = service_response.payload[:snippet]
+
+ if service_response.success?
+ present snippet, with: Entities::PersonalSnippet, current_user: current_user
+ else
+ # Wrap the normal error response in a `with_captcha_check_rest_api(spammable: snippet)` block
+ with_captcha_check_rest_api(spammable: snippet) do
+ # If possible spam was detected, an exception would have been thrown by
+ # `#with_captcha_check_rest_api` for Grape to handle via `error!`
+ render_api_error!({ error: service_response.message }, service_response.http_status)
+ end
+ end
+ end
+```
diff --git a/doc/development/spam_protection_and_captcha/web_ui.md b/doc/development/spam_protection_and_captcha/web_ui.md
index 6aa01f401bd..9aeb9e96d44 100644
--- a/doc/development/spam_protection_and_captcha/web_ui.md
+++ b/doc/development/spam_protection_and_captcha/web_ui.md
@@ -37,7 +37,7 @@ additional fields being added to the models. Instead, communication is handled:
The spam and CAPTCHA-related logic is also cleanly abstracted into reusable modules and helper methods
which can wrap existing logic, and only alter the existing flow if potential spam
is detected or a CAPTCHA display is needed. This approach allows the spam and CAPTCHA
-support to be easily added to new areas of the application with minimal changes to
+support to be added to new areas of the application with minimal changes to
existing logic. In the case of the frontend, potentially **zero** changes are needed!
On the frontend, this is handled abstractly and transparently using `ApolloLink` for Apollo, and an
@@ -75,7 +75,7 @@ sequenceDiagram
The backend is also cleanly abstracted via mixin modules and helper methods. The three main
changes required to the relevant backend controller actions (normally just `create`/`update`) are:
-1. Create a `SpamParams` parameter object instance based on the request, using the simple static
+1. Create a `SpamParams` parameter object instance based on the request, using the static
`#new_from_request` factory method. This method takes a request, and returns a `SpamParams` instance.
1. Pass the created `SpamParams` instance as the `spam_params` named argument to the
Service class constructor, which you should have already added. If the spam check indicates