Files
tradon/res/routes.py
2025-12-26 13:11:43 +00:00

68 lines
2.4 KiB
Python
Executable File

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import logging
import random
import time
from trytond.config import config
from trytond.protocols.wrappers import (
abort, allow_null_origin, with_pool, with_transaction)
from trytond.transaction import Transaction
from trytond.wsgi import app
logger = logging.getLogger(__name__)
@app.route('/<database_name>/user/application/', methods=['POST', 'DELETE'])
@allow_null_origin
@with_pool
@with_transaction(readonly=False)
def user_application(request, pool):
User = pool.get('res.user')
UserApplication = pool.get('res.user.application')
LoginAttempt = pool.get('res.user.login.attempt')
data = request.parsed_data
login = data.get('user')
if request.method == 'POST':
# Make time random to process and try to use the same path as much as
# possible to prevent guessing between valid and invalid requests.
Transaction().atexit(time.sleep, random.random())
users = User.search([
('login', '=', login),
])
if not users:
logger.info('User Application not found: %s', data.get('user'))
user_id = None
else:
user, = users
user_id = user.id
if UserApplication.count(user_id):
logger.info('User Application has already a request: %s', login)
user_id = None
data['user'] = user_id
data.pop('key', None)
data['state'] = 'requested'
application, = UserApplication.create([data])
key = application.key
UserApplication.delete(UserApplication.search([
('user', '=', None),
]))
return key
elif request.method == 'DELETE':
count = LoginAttempt.count(login)
if count > config.getint('session', 'max_attempt', default=5):
LoginAttempt.add(login)
abort(429)
Transaction().atexit(time.sleep, 2 ** count - 1)
applications = UserApplication.search([
('user.login', '=', login),
('key', '=', data.get('key')),
('application', '=', data.get('application')),
])
if applications:
UserApplication.delete(applications)
LoginAttempt.remove(login)
else:
LoginAttempt.add(login)