Under attack mode

This commit is contained in:
Piero Toffanin 2025-04-18 14:41:12 -04:00
parent e4eb96482f
commit bdb9b6a224
5 changed files with 36 additions and 11 deletions

View File

@ -200,6 +200,7 @@ Arguments passed to the process or set via environment variables are split into
| --require-api-key-origin | Require use of an API key for programmatic access to the API, unless the request origin matches this domain | `No restrictions on domain origin` | LT_REQUIRE_API_KEY_ORIGIN | | --require-api-key-origin | Require use of an API key for programmatic access to the API, unless the request origin matches this domain | `No restrictions on domain origin` | LT_REQUIRE_API_KEY_ORIGIN |
| --require-api-key-secret | Require use of an API key for programmatic access to the API, unless the client also sends a secret match | `No secrets required` | LT_REQUIRE_API_KEY_SECRET | | --require-api-key-secret | Require use of an API key for programmatic access to the API, unless the client also sends a secret match | `No secrets required` | LT_REQUIRE_API_KEY_SECRET |
| --require-api-key-fingerprint | Require use of an API key for programmatic access to the API, unless the client also matches a fingerprint | `No fingerprinting required` | LT_REQUIRE_API_KEY_FINGERPRINT | | --require-api-key-fingerprint | Require use of an API key for programmatic access to the API, unless the client also matches a fingerprint | `No fingerprinting required` | LT_REQUIRE_API_KEY_FINGERPRINT |
| --under-attack | Enable under attack mode. When enabled, requests must be made with an API key | `Disabled` | LT_UNDER_ATTACK |
| --suggestions | Allow user suggestions | `Disabled` | LT_SUGGESTIONS | | --suggestions | Allow user suggestions | `Disabled` | LT_SUGGESTIONS |
| --disable-files-translation | Disable files translation | `File translation allowed` | LT_DISABLE_FILES_TRANSLATION | | --disable-files-translation | Disable files translation | `File translation allowed` | LT_DISABLE_FILES_TRANSLATION |
| --disable-web-ui | Disable web ui | `Web Ui enabled` | LT_DISABLE_WEB_UI | | --disable-web-ui | Disable web ui | `Web Ui enabled` | LT_DISABLE_WEB_UI |

View File

@ -364,6 +364,9 @@ def create_app(args):
if flood.fingerprint_mismatch(ip, get_fingerprint()): if flood.fingerprint_mismatch(ip, get_fingerprint()):
need_key = True need_key = True
if args.under_attack and key_missing:
need_key = True
if need_key: if need_key:
description = _("Please contact the server operator to get an API key") description = _("Please contact the server operator to get an API key")
if args.get_api_key_link: if args.get_api_key_link:
@ -441,7 +444,8 @@ def create_app(args):
swagger_url=swagger_url, swagger_url=swagger_url,
available_locales=sorted([{'code': l['code'], 'name': _lazy(l['name'])} for l in get_available_locales(not args.debug)], key=lambda s: s['name']), available_locales=sorted([{'code': l['code'], 'name': _lazy(l['name'])} for l in get_available_locales(not args.debug)], key=lambda s: s['name']),
current_locale=get_locale(), current_locale=get_locale(),
alternate_locales=get_alternate_locale_links() alternate_locales=get_alternate_locale_links(),
under_attack=args.under_attack,
)) ))
if args.require_api_key_secret: if args.require_api_key_secret:

View File

@ -151,6 +151,11 @@ _default_options_objects = [
'default_value': False, 'default_value': False,
'value_type': 'bool' 'value_type': 'bool'
}, },
{
'name': 'UNDER_ATTACK',
'default_value': False,
'value_type': 'bool'
},
{ {
'name': 'REQUIRE_API_KEY_FINGERPRINT', 'name': 'REQUIRE_API_KEY_FINGERPRINT',
'default_value': False, 'default_value': False,

View File

@ -153,6 +153,12 @@ def get_args():
action="store_true", action="store_true",
help="Require use of an API key for programmatic access to the API, unless the client also matches a fingerprint", help="Require use of an API key for programmatic access to the API, unless the client also matches a fingerprint",
) )
parser.add_argument(
"--under-attack",
default=DEFARGS['UNDER_ATTACK'],
action="store_true",
help="Enable under attack mode. When enabled, requests must be made with an API key",
)
parser.add_argument( parser.add_argument(
"--shared-storage", "--shared-storage",
type=str, type=str,

View File

@ -150,18 +150,18 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col s12 m12"> <div class="col s12 m12">
<div class="card horizontal"> <div class="card horizontal">
<div class="card-stacked"> <div class="card-stacked">
<div class="card-content"> <div class="card-content">
<i class="material-icons">warning</i><p> [[ error ]]</p> <i class="material-icons">warning</i><p> [[ error ]]</p>
</div> </div>
<div class="card-action"> <div class="card-action">
<a href="#" @click="dismissError">{{ _h("Dismiss") }}</a> <a href="#" @click="dismissError">{{ _h("Dismiss") }}</a>
</div> </div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -170,6 +170,15 @@
<div class="section no-pad-bot"> <div class="section no-pad-bot">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
{% if under_attack %}
<div class="card horizontal">
<div class="card-stacked">
<div class="card-content center">
<i class="material-icons" style="position: relative; top: 4px;">warning</i> {{ _h("Due to bot abuse, translation requests are temporarily limited to users with a valid API key. Sorry for the inconvenience!") }}</p>
</div>
</div>
</div>
{% endif %}
<h3 class="header center">{{ _h("Translation API") }}</h3> <h3 class="header center">{{ _h("Translation API") }}</h3>
<div id="translation-type-btns" class="s12 center" v-if="filesTranslation === true"> <div id="translation-type-btns" class="s12 center" v-if="filesTranslation === true">
<button type="button" class="btn btn-switch-type" @click="switchType('text')" :class="{'active': translationType === 'text'}"> <button type="button" class="btn btn-switch-type" @click="switchType('text')" :class="{'active': translationType === 'text'}">