1
0
mirror of https://github.com/LibreTranslate/LibreTranslate.git synced 2024-12-18 08:27:03 +02:00

Merge pull request #215 from fushinari/api-key-access

app: Fail when giving invalid API keys
This commit is contained in:
Piero Toffanin 2022-02-20 11:29:40 -05:00 committed by GitHub
commit a85b645550
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 26 additions and 10 deletions

View File

@ -3,18 +3,20 @@ import os
import tempfile import tempfile
import uuid import uuid
from functools import wraps from functools import wraps
from html import unescape
import argostranslatefiles import argostranslatefiles
from argostranslatefiles import get_supported_formats from argostranslatefiles import get_supported_formats
from flask import Flask, abort, jsonify, render_template, request, url_for, send_file from flask import (Flask, abort, jsonify, render_template, request, send_file,
url_for)
from flask_swagger import swagger from flask_swagger import swagger
from flask_swagger_ui import get_swaggerui_blueprint from flask_swagger_ui import get_swaggerui_blueprint
from translatehtml import translate_html from translatehtml import translate_html
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
from html import unescape
from app import flood, remove_translated_files, security from app import flood, remove_translated_files, security
from app.language import detect_languages, transliterate from app.language import detect_languages, transliterate
from .api_keys import Database from .api_keys import Database
from .suggestions import Database as SuggestionsDatabase from .suggestions import Database as SuggestionsDatabase
@ -140,7 +142,6 @@ def create_app(args):
else: else:
frontend_argos_language_target = languages[0] frontend_argos_language_target = languages[0]
api_keys_db = None api_keys_db = None
if args.req_limit > 0 or args.api_keys or args.daily_req_limit > 0: if args.req_limit > 0 or args.api_keys or args.daily_req_limit > 0:
@ -174,11 +175,19 @@ def create_app(args):
if flood.has_violation(ip): if flood.has_violation(ip):
flood.decrease(ip) flood.decrease(ip)
if args.api_keys and args.require_api_key_origin: if args.api_keys:
ak = get_req_api_key() ak = get_req_api_key()
if ( if (
api_keys_db.lookup(ak) is None and request.headers.get("Origin") != args.require_api_key_origin ak and api_keys_db.lookup(ak) is None
):
abort(
403,
description="Invalid API key",
)
elif (
args.require_api_key_origin
and api_keys_db.lookup(ak) is None
and request.headers.get("Origin") != args.require_api_key_origin
): ):
abort( abort(
403, 403,

View File

@ -2,16 +2,19 @@ import os
_prefix = 'LT_' _prefix = 'LT_'
def _get_value_str(name, default_value): def _get_value_str(name, default_value):
env_value = os.environ.get(name) env_value = os.environ.get(name)
return default_value if env_value is None else env_value return default_value if env_value is None else env_value
def _get_value_int(name, default_value): def _get_value_int(name, default_value):
try: try:
return int(os.environ[name]) return int(os.environ[name])
except: except:
return default_value return default_value
def _get_value_bool(name, default_value): def _get_value_bool(name, default_value):
env_value = os.environ.get(name) env_value = os.environ.get(name)
if env_value in ['FALSE', 'False', 'false', '0']: if env_value in ['FALSE', 'False', 'false', '0']:
@ -20,6 +23,7 @@ def _get_value_bool(name, default_value):
return True return True
return default_value return default_value
def _get_value(name, default_value, value_type): def _get_value(name, default_value, value_type):
env_name = _prefix + name env_name = _prefix + name
if value_type == 'str': if value_type == 'str':
@ -30,6 +34,7 @@ def _get_value(name, default_value, value_type):
return _get_value_bool(env_name, default_value) return _get_value_bool(env_name, default_value)
return default_value return default_value
_default_options_objects = [ _default_options_objects = [
{ {
'name': 'HOST', 'name': 'HOST',
@ -114,7 +119,7 @@ _default_options_objects = [
{ {
'name': 'SUGGESTIONS', 'name': 'SUGGESTIONS',
'default_value': False, 'default_value': False,
'value_type': 'bool' 'value_type': 'bool'
}, },
{ {
'name': 'DISABLE_FILES_TRANSLATION', 'name': 'DISABLE_FILES_TRANSLATION',
@ -129,4 +134,4 @@ _default_options_objects = [
] ]
DEFAULT_ARGUMENTS = { obj['name']:_get_value(**obj) for obj in _default_options_objects} DEFAULT_ARGUMENTS = {obj['name']: _get_value(**obj) for obj in _default_options_objects}

View File

@ -22,6 +22,7 @@ def forgive_banned():
for ip in clear_list: for ip in clear_list:
del banned[ip] del banned[ip]
def setup(violations_threshold=100): def setup(violations_threshold=100):
global active global active
global threshold global threshold

View File

@ -1,6 +1,6 @@
import argparse import argparse
import sys
import operator import operator
import sys
from app.app import create_app from app.app import create_app
from app.default_values import DEFAULT_ARGUMENTS as DEFARGS from app.default_values import DEFAULT_ARGUMENTS as DEFARGS

View File

@ -1,8 +1,10 @@
import os import os
class SuspiciousFileOperation(Exception): class SuspiciousFileOperation(Exception):
pass pass
def path_traversal_check(unsafe_path, known_safe_path): def path_traversal_check(unsafe_path, known_safe_path):
known_safe_path = os.path.abspath(known_safe_path) known_safe_path = os.path.abspath(known_safe_path)
unsafe_path = os.path.abspath(unsafe_path) unsafe_path = os.path.abspath(unsafe_path)

View File

@ -1,5 +1,4 @@
import sqlite3 import sqlite3
import uuid
from expiringdict import ExpiringDict from expiringdict import ExpiringDict