Tryton flask - user login


(Markus Bala) #1

hi,

i am creating a web for warehouse handy terminal. how to implement login using tryton user?

currently there is a setting TRYTON_USER, so any edit, update delete happen to only one user.
so it cause audit trail.

my solution as below:
User = tryton.pool.get(‘res.user’)
parameters = {}
parameters[‘password’] = ‘userpwd’
user_id = User.get_login(‘user1’, parameters)
–> using user_id to overwrite create_uid, update_uid whenever add & update.

may i know, there is more clean solution?


(Nicolas Évrard) #2

tryton-flask defines an transaction decorator which has a user parameter that can be a user ID or a callable. This callable could use some information from the request to compute the user that initiated it.


(Markus Bala) #3

may i know how to put the user parameter to transaction decrator during runtime?

example; in flask config TRYTON_USER=0 aka root. then I log in uding user1 with id =2.
how am I put id=2 to the decorator?
@tryton.transaction(user=2) --> how to set in runtime?


(Nicolas Évrard) #4

As I said: the transaction decorator accept a callable for the user parameter.
So something like:


def always_two():
     return 2

@tryton.transaction(user=always_two)
def foo():
    …

The tricky part is the function, you could use some session management in flask, or use tryton to do it, I don’t know.


(Cédric Krier) #5

But flask-tryton is not really the best option to interact with Tryton’s user. It was design with in mind the web_user module.
If you want to make a workflow tailored application, it is probably better to use User Application — trytond 5.1 documentation


(Markus Bala) #6

i was consider using user application. however, curent project is using rf terminal in warehouse.

so, it is not dedicated user per one handy terminal.
that why, i need to implement login function.


(Markus Bala) #7

oh i see… it can use function as parameter.
i will try it… thank


(Markus Bala) #8

Just some update, I have some work around. So to post for help:
Session management which I am using flask-login.
Write the tryton.transaction inside a function.

from flask_login import current_user, login_required

@bp.route('/', methods=['GET', 'POST'])
@bp.route('/index', methods=['GET', 'POST'])
@login_required
def write():
    @tryton.transaction(user=current_user.get_id(), readonly=False)
    def write_action():
        Party = tryton.pool.get('party.party')


        party, = Party.search([('id', '=', 2)])
        Party.write([party], {'name': 'I am a supplier '})

        return user
    return write_action()

(Cédric Krier) #9

I’m pretty sure you can write:

from flask_login import current_user, login_required

@bp.route('/', methods=['GET', 'POST'])
@bp.route('/index', methods=['GET', 'POST'])
@login_required
@tryton.transaction(user=current_user.get_id)
def write():
    Party = tryton.pool.get('party.party')
    party, = Party.search([('id', '=', 2)])
    if request.method == 'POST':
        Party.write([party], {'name': 'I am a supplier '})

(Markus Bala) #10

Hi @ced,

Eh… Later I try again and let you know the result

Last night, I had tried. But the “current_user” value was still None.

best regards


(Cédric Krier) #11

Notice that it is the get_id function that is passed and not the call result.


(Markus Bala) #12

Hi @ced,
Sorry for reply you late, the solution propose is not working. Because the current_user still in nonetype.

In the end, I used “g” app context for to this purpose.

from flask import g
from flask_login import current_user, login_required
from app.inventory import bp

def get_id():
     if 'uid' not in g:
         g.uid = current_user.get_id()
     return g.uid
	 
@bp.route('/lot_register/<record("stock.move"):move>', methods=['GET', 'POST'])
@login_required
@tryton.transaction(user=get_id)
def lot_register(move):
    title = _('Create Lot')
    back_url = g.back_url
    ....

(Cédric Krier) #13

Indeed current_user is a LocalProxy to _get_user method. So it is not possible to have a reference to the get_id method. I guess this could work:

@tryton.transaction(user=lambda current_user.get_id())

(Markus Bala) #14

Hi @ced,

thank, it is worked and it clearer than my solution.

Just to correction for the syntax:
@tryton.transaction(user=lambda:current_user.get_id())