How to use Click's context and callbacks to limit the number of times a user tries tries to login

Viewed 67

I'm trying to setup a CLI with Python using click. I need to limit the number of times a user is able to attempt to log in.

I've been trying to use the context to keep a counter of the login attempts but to no avail.

import click

def validate_password(ctx, param, password):
    """func to check password validity"""

@click.command()
@click.password_option(confirmation_prompt=False, callback=validate_password)
def log_admin(password):
    click.echo("Successful authentication.")

The thing is, the callback can be used to check the validity of the password : if it's well formatted or matches against the proper hash.

But I can't manage to create a counter which would stop the user prompt when reaching a certain value. The callback for validation example shows this.

What can I do to ensure a user does not try to authenticate more than a certain amount of times?

1 Answers

For the curious, I ended up doing something hackish and probably wrong but it seems to work.

import click
import ftp_auth
from cryptography.exceptions import InvalidKey


class Authentication:
    COUNTER = 3

    @staticmethod
    @click.command()
    @click.password_option(confirmation_prompt=False)
    def log_admin(password):
        if Authentication.COUNTER <= 0:
            raise click.ClickException(
                message="Too many authentication attempts.")
        password = password.encode("utf-8")
        try:
            ftp_auth.verify_password(password)  # Checking against correct hash
        except InvalidKey:  # Password hashes not matching
            click.echo("Incorrect password.")
            Authentication.COUNTER -= 1
            Authentication.log_admin()
        else:
            click.echo("Successful authentication.")


if __name__ == '__main__':
    Authentication.log_admin()
Related