Home > Mobile >  Gramex - DBAuth Login only when user is active
Gramex - DBAuth Login only when user is active

Time:01-24

I am trying to implement a way by which I can check the value of an is_active column from user database before letting the user log in. So along with the password check, I also want to check if is_active column is True, only then the user must be able to login, otherwise I want restrict login and show an error that "The user is inactive"(even if the password is correct). I went through the Gramex documentation but could not find a way to configure this requirement.

Is there any way to implement this in DBAuth?

CodePudding user response:

You can copy the default auth.template.html locally as custom-login.html.

Then you can check if the user is already logged in (i.e. is_active) by checking handler.current_user. For example:

{% set is_active = handler.current_user %}
{% if not is_active %}
  <p>The user is inactive. You can't log in.</p>
{% else %}
  ... continue with default form
{% end %}

In your gramex.yaml, you could add template: $YAMLPATH/custom-login.html like this:

  login:
    pattern: /login/
    handler: DBAuth
    kwargs:
      url: $YAMLPATH/auth.xlsx
      user:
        column: user
      password:
        column: password
      template: $YAMLPATH/custom-login.html

NOTE: By only allowing logged-in users to log in, no user will be able to log in for the first time. So you'll need some mechanism to figure out how to let users log in for the first time.

CodePudding user response:

Revising the solution. The requirement to check if the is_active column in the database is true, and to prevent login before the fact, i.e. as a validation.

To enable this, create a subclass of DBAuth called ValidatedDBAuth:

import gramex.data
from tornado.gen import coroutine
from gramexenterprise.handlers import DBAuth
from gramex.config import variables

class ValidatedDBAuth(DBAuth):
    @coroutine
    def post(handler):
        user = handler.get_argument('user')
        is_active = gramex.data.filter(
            variables['CONNECTION_STRING'],
            table='user',
            args={'user': [user]}
        )['is_active'].iloc[0]
        if is_active:
            yield super().post()
        else:
            handler.redirect('/login/?msg=inactive')

Now use this instead of your DBAuth. For example:

url:
  login:
    pattern: /login/
    handler: mymodule.ValidatedDBAuth
    kwargs:
      ... # Same as for DBAuth
  • Related