From 7a7c33fa191fab8890cd04eeb8cf4f6cb70e6011 Mon Sep 17 00:00:00 2001 From: vdbhb59 Date: Sat, 19 Apr 2025 13:26:54 +0530 Subject: [PATCH] Synced (yesterday's) Add fingerprinting mechanism (https://github.com/LibreTranslate/LibreTranslate/commit/f2268fe4d9b4c1349f3deac34d7218513a6866c8) --- README.md | 29 +++++++++++++++-------------- VERSION | 2 +- libretranslate/flood.py | 13 +++++++++++++ libretranslate/secret.py | 2 +- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index bbec0b1..f40ff1a 100644 --- a/README.md +++ b/README.md @@ -192,19 +192,20 @@ Arguments passed to the process or set via environment variables are split into ### Settings / Flags -| Argument | Description | Default Setting | Env. name | -| --------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------- | ---------------------------- | -| --debug | Enable debug environment | `Disabled` | LT_DEBUG | -| --ssl | Whether to enable SSL | `Disabled` | LT_SSL | -| --api-keys | Enable API keys database for per-client rate limits when --req-limit is reached | `Don't use API keys` | LT_API_KEYS | -| --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 | +| Argument | Description | Default Setting | Env. name | +| ----------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------- | ------------------------------ | +| --debug | Enable debug environment | `Disabled` | LT_DEBUG | +| --ssl | Whether to enable SSL | `Disabled` | LT_SSL | +| --api-keys | Enable API keys database for per-client rate limits when --req-limit is reached | `Don't use API keys` | LT_API_KEYS | +| --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-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 | -| --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 | -| --update-models | Update language models at startup | `Only on if no models found` | LT_UPDATE_MODELS | -| --metrics | Enable the /metrics endpoint for exporting [Prometheus](https://prometheus.io/) usage metrics | `Disabled` | LT_METRICS | +| --suggestions | Allow user suggestions | `Disabled` | LT_SUGGESTIONS | +| --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 | +| --update-models | Update language models at startup | `Only on if no models found` | LT_UPDATE_MODELS | +| --metrics | Enable the /metrics endpoint for exporting [Prometheus](https://prometheus.io/) usage metrics | `Disabled` | LT_METRICS | ### Configuration Parameters @@ -428,7 +429,7 @@ This is a list of public LibreTranslate instances, some require an API key. If y | ----------------------------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------- | | [libretranslate.com](https://libretranslate.com) | :heavy_check_mark: | [ [Get API Key](https://portal.libretranslate.com) ] [ [Service Status](https://status.libretranslate.com/) ] | | [translate.flossboxin.org.in](https://translate.flossboxin.org.in/) | | [ [Contact/eMail](mailto:dev@flossboxin.org.in) ] | -| [lt.blitzw.in](https://lt.blitzw.in/) | | hosted by blitzw.in. uses an open source javascript-based captcha to fight bots! | +| [lt.blitzw.in](https://lt.blitzw.in/) | | | ## TOR/i2p Mirrors @@ -759,4 +760,4 @@ This work is largely possible thanks to [Argos Translate](https://github.com/arg ## Trademark -See [Trademark Guidelines](https://github.com/LibreTranslate/LibreTranslate/blob/main/TRADEMARK.md) +See [Trademark Guidelines](https://github.com/LibreTranslate/LibreTranslate/blob/main/TRADEMARK.md) \ No newline at end of file diff --git a/VERSION b/VERSION index bd8bf88..943f9cb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.7.0 +1.7.1 diff --git a/libretranslate/flood.py b/libretranslate/flood.py index 63cd392..3f87c9b 100644 --- a/libretranslate/flood.py +++ b/libretranslate/flood.py @@ -45,3 +45,16 @@ def is_banned(request_ip): # More than X offences? return active and s.get_hash_int("banned", request_ip) >= threshold + +def fingerprint_mismatch(request_ip, fingerprint): + if not isinstance(fingerprint, str) or fingerprint == "": + return True + + s = get_storage() + k = f"fingerprint:{request_ip}" + expected = s.get_str(k) + if expected == "": + s.set_str(k, fingerprint, ex=300) + return False + else: + return fingerprint != expected \ No newline at end of file diff --git a/libretranslate/secret.py b/libretranslate/secret.py index c8f278a..fdf818d 100644 --- a/libretranslate/secret.py +++ b/libretranslate/secret.py @@ -108,7 +108,7 @@ def get_emoji(): return random.choice(["😂", "ðŸĪŠ", "😜", "ðŸĪĢ", "ðŸ˜đ", "🐒", "🙈", "ðŸĪĄ", "ðŸĨļ", "😆", "ðŸĨī", "ðŸļ", "ðŸĪ", "🐒🙊", "👀", "ðŸ’Đ", "ðŸĪŊ", "😛", "ðŸĪĨ", "ðŸ‘ŧ"]) def setup(args): - if args.api_keys and args.require_api_key_secret: + if args.require_api_key_secret: s = get_storage() if not s.exists("secret_0"):