HewlettPackard / jupyterhub-samlauthenticator

jupyterhub-samlauthenticator
MIT License
36 stars 25 forks source link

Return object from authenticate #64

Open 0nebody opened 2 years ago

0nebody commented 2 years ago

Since version 0.8 we can return an object or string from the authenticate function. Currently we return the username or None. Returning an object will enable us to do more with role based access.

Example:

{
    "name": "tom",
    "auth_state": {
        "roles": [ "role1", "role2" ]
    }
}

Reference:

  1. https://github.com/jupyterhub/jupyterhub/blob/main/jupyterhub/auth.py#L558-L584
0nebody commented 2 years ago

I have submitted a pull request for this #65. Writing tests for this is a little hard so I might need some help generating the responses.

Below is an example of how this can be utilised. I haven't included it in the documentation as it isn't specific to this authenticator. This example overrides the spawn options presented to a user based on the roles they authenticated with.

async def custom_options_form(spawner):
    username = spawner.user.name
    auth_state = await spawner.user.get_auth_state()
    user_roles = auth_state['roles']

    # Optional: add default profile
    spawner.profile_list = []
    role_profiles = [
        {
            'display_name': "Admin Notebook",
            'description': "Jupyter Notebook for Admins",
            'slug': "admin",
            'kubespawner_override': {
                'image': 'jupyterhub/singleuser:latest',
                'cpu_limit': 1,
                'mem_limit': "200M"
            },
            'allowed_roles': ["jupyterhub-admin"]
        },
        {
            'display_name': "MAT101 Notebook",
            'description': "Jupyter Notebook for MAT101",
            'slug': "MAT101",
            'kubespawner_override': {
                'mem_guarantee': "100M",
                'mem_limit': "200M"
            },
            'allowed_roles': ["MAT101", "MAT101-admin"]
        }
    ]

    for profile in role_profiles:
        if any(elem in profile['allowed_roles'] for elem in user_roles):
            spawner.log.info( f"Access options added for {username} matching {profile['allowed_roles']}.")
            del profile['allowed_roles']
            spawner.profile_list.extend([profile])

    return spawner._options_form_default()

c.KubeSpawner.options_form = custom_options_form

Reference:

  1. https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html
distortedsignal commented 2 years ago

Rad PR. I'll let you know when I'm able to get to writing the tests.

I might make a PR against your branch. I'll let you know.