    def add_user(self, user):
        """Hook called when a user is added to JupyterHub

        This is called:
         - When a user first authenticates, _after_ all allow and block checks have passed
         - When the hub restarts, for all users in the database (i.e. users previously allowed)
         - When a user is added to the database, either via configuration or REST API

        This method may be a coroutine.

        By default, this adds the user to the allowed_users set if
        allow_existing_users is true.

        Subclasses may do more extensive things, such as creating actual system users,
        but they should call super to ensure the allowed_users set is updated.

        Note that this should be idempotent, since it is called whenever the hub restarts
        for all users.

        .. versionchanged:: 5.0
           Now adds users to the allowed_users set if allow_all is False and allow_existing_users is True,
           instead of if allowed_users is not empty.

        Args:
            user (User): The User wrapper object
        """
        if not self.validate_username(user.name):
            raise ValueError(f"Invalid username: {user.name}")
        if self.allow_existing_users and not self.allow_all:
            self.allowed_users.add(user.name)
Hook called when a user is added to JupyterHub

This is called:
- When a user first authenticates, _after_ all allow and block checks have passed
- When the hub restarts, for all users in the database (i.e. users previously allowed)
- When a user is added to the database, either via configuration or REST API

This method may be a coroutine.

By default, this adds the user to the allowed_users set if
allow_existing_users is true.

Subclasses may do more extensive things, such as creating actual system users,
but they should call super to ensure the allowed_users set is updated.

Note that this should be idempotent, since it is called whenever the hub restarts
for all users.

.. versionchanged:: 5.0
Now adds users to the allowed_users set if allow_all is False and allow_existing_users is True,
instead of if allowed_users is not empty.

Args:
user (User): The User wrapper object
jupyterhub/auth.py