Jam.py documentation

How to authenticate from custom users table

By default, all user information is stored in a table in the admin.sqlite database. This table has a fixed structure that cannot be changed.

In this section, we describe how to authenticate a user using data from the custom users table.

First, we create an item group Authentication select it and add an item Users that has the following fields:

users_fields.png

We won’t store in the table the user password and use this field in the interface. We will store the password salted hash in the password_hash field.

We also created the lookup list “Roles” that we used in the “Roles” field definition.

We added to it the same roles (ids and names) as in the table Roles We ‘ll have to sycronize this roles in the future.

roles_lookup_list.png

In the Roles it is necessary to allow view the Users item only people that will be responsible for it

We removed password_hash field from field lists in the View Form Dialog and Edit Form Dialog

In the User server module we define the following on_apply event handler:

def on_apply(item, delta, params, connection):
    for d in delta:
        if not (d.rec_deleted() or d.rec_modified() and d.login.value == d.login.old_value):
            users = d.task.users.copy(handlers=False)
            users.set_where(login=d.login.value)
            users.open(fields=['login'])
            if users.rec_count:
                raise Exception('There is a user with this login - %s' % d.login.value)
        if d.password.value:
            d.edit();
            d.password_hash.value = delta.task.generate_password_hash(d.password.value)
            d.password.value = None
            d.post();

In this event handler we check if there is a users with the same login and raise the exception if such user exists, otherwise we generate hash using the generate_password_hash method of the task and set the password value to None.

In the client module we defined the following on_field_get_text event handler. It displays ‘******’ string insted of the password.

function on_field_get_text(field) {
    var item = field.owner;
    if (field.field_name === 'password') {
        if (item.id.value || field.value) {
            return '**********';
        }
    }
}

Finally, we define the on_login event handler in the task server module:

def on_login(task, form_data, info):
    users = task.users.copy(handlers=False)
    users.set_where(login=form_data['login'])
    users.open()
    if users.rec_count == 1:
        if task.check_password_hash(users.password_hash.value, form_data['password']):
            return {
                'user_id': users.id.value,
                'user_name': users.name.value,
                'role_id': users.role.value,
                'role_name': users.role.display_text
            }

Now we must add an admin to Users that has rights to work with users. After that we can set Safe mode in the project Parameters