=========================================== 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: .. image:: /how_to/_images/users_fields.png :align: center :alt: 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 :doc:`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 :doc:`Roles ` We 'll have to sycronize this roles in the future. .. image:: /how_to/_images/roles_lookup_list.png :align: center :alt: roles_lookup_list.png In the :doc:`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 :doc:`View Form Dialog ` and :doc:`Edit Form Dialog ` In the User server module we define the following :doc:`on_apply ` event handler: .. code-block:: py 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 :doc:`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. .. code-block:: js 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 :doc:`on_login ` event handler in the task server module: .. code-block:: py 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 :doc:`Parameters `