    async def auth_to_user(self, authenticated, user=None):
        """Persist data from .authenticate() or .refresh_user() to the User database

        Args:
            authenticated(dict): return data from .authenticate or .refresh_user
            user(User, optional): the User object to refresh, if refreshing
        Return:
            user(User): the constructed User object
        """
        if isinstance(authenticated, str):
            authenticated = {'name': authenticated}
        username = authenticated['name']
        auth_state = authenticated.get('auth_state')
        admin = authenticated.get('admin')
        refreshing = user is not None

        if user and username != user.name:
            raise ValueError(f"Username doesn't match! {username} != {user.name}")

        if user is None:
            user = self.find_user(username)
            new_user = user is None
            if new_user:
                user = self.user_from_username(username)
                await maybe_future(self.authenticator.add_user(user))
        # Only set `admin` if the authenticator returned an explicit value.
        if admin is not None and admin != user.admin:
            user.admin = admin
        # always ensure default roles ('user', 'admin' if admin) are assigned
        # after a successful login
        roles.assign_default_roles(self.db, entity=user)

        # apply authenticator-managed groups
        if self.authenticator.manage_groups:
            if "groups" not in authenticated:
                # to use manage_groups, group membership must always be specified
                # Authenticators that don't support this feature will omit it,
                # which should fail here rather than silently not implement the requested behavior
                auth_cls = self.authenticator.__class__.__name__
                raise ValueError(
                    f"Authenticator.manage_groups is enabled, but auth_model for {username} specifies no groups."
                    f" Does {auth_cls} support manage_groups=True?"
                )
            group_names = authenticated["groups"]
            if group_names is not None:
                user.sync_groups(group_names)
        # apply authenticator-managed roles
        if self.authenticator.manage_roles:
            auth_roles = authenticated.get("roles")
            if auth_roles is not None:
                user.sync_roles(auth_roles)
        # always set auth_state and commit,
        # because there could be key-rotation or clearing of previous values
        # going on.
        if not self.authenticator.enable_auth_state:
            # auth_state is not enabled. Force None.
            auth_state = None

        await user.save_auth_state(auth_state)

        return user
Persist data from .authenticate() or .refresh_user() to the User database

Args:
authenticated(dict): return data from .authenticate or .refresh_user
user(User, optional): the User object to refresh, if refreshing
Return:
user(User): the constructed User object
jupyterhub/handlers/base.py