68 lines
2.4 KiB
Python
Executable File
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)
|