in lemur/auth/views.py [0:0]
def create_user_roles(profile: dict) -> list[str]:
"""
Generate a list of Lemur role names based on the provided user profile.
The function maps the user's roles from the identity provider to corresponding roles in Lemur,
creates roles dynamically based on the profile data, and assigns a unique role for each user.
:param profile: A dictionary containing user information, including roles/groups from the identity provider.
:return: A list of Lemur role names corresponding to the provided user profile.
"""
roles = []
# We default to pulling in "googleGroups" as that was historically hard coded
idp_groups_keys = current_app.config.get("IDP_GROUPS_KEYS", ["googleGroups"])
if isinstance(idp_groups_keys, str):
idp_groups_keys = [idp_groups_keys]
for idp_groups_key in idp_groups_keys:
if idp_groups_key not in profile:
current_app.logger.warning(
f"""'{idp_groups_key}' not sent by identity provider for user {profile["email"]}."""
)
continue
if not isinstance(profile[idp_groups_key], list) and all(isinstance(item, str) for item in profile[idp_groups_key]):
# Catch instances where roles are not a list of strings
current_app.logger.warning(
f"""'{idp_groups_key}' sent by identity provider for user {profile["email"]} is not a list of strings."""
)
continue
# Take a fixed set of groups/roles and map it to Lemur roles.
# If the IDP_GROUPS_TO_ROLES is empty or not set, nothing happens.
idp_group_to_role_map = current_app.config.get("IDP_ROLES_MAPPING", {})
matched_roles = [
idp_group_to_role_map[role] for role in profile.get(idp_groups_key, []) if role in idp_group_to_role_map
]
roles.extend(matched_roles)
# Automatically create and assign roles from the user profile.
if current_app.config.get("IDP_ASSIGN_ROLES_FROM_USER_GROUPS", True):
idp_roles_description = current_app.config.get("IDP_ROLES_DESCRIPTION",
f"Identity provider role from '{idp_groups_key}' (generated by Lemur)")
idp_roles_prefix = current_app.config.get("IDP_ROLES_PREFIX", "")
idp_roles_suffix = current_app.config.get("IDP_ROLES_SUFFIX", "")
for group in profile.get(idp_groups_key, []):
if group in ["admin", "operator", "read-only"] and current_app.config.get("IDP_PROTECT_BUILTINS", True):
current_app.logger.warning(
f"""Attempted to assign built in '{group}' to user {profile["email"]}. Group not assigned.""")
continue
# Check if the group matches naming conventions
if group.startswith(idp_roles_prefix) and group.endswith(idp_roles_suffix):
# Get the role from Lemur if it already exists
role = role_service.get_by_name(group)
if not role and current_app.config.get("IDP_CREATE_ROLES_FROM_USER_GROUPS", True):
current_app.logger.debug(
f"""Role '{group}' does not exist. Creating role from user {profile["email"]}""")
role = role_service.create(
group,
description=idp_roles_description,
third_party=True,
)
if role:
roles.append(role)
# Create a unique role for each user. This is a kludge in order to assign a specific user to a specific cert
# Defaults to enabled as this was previous/existing behavior
if current_app.config.get("IDP_CREATE_PER_USER_ROLE", True):
role = role_service.get_by_name(profile["email"])
if not role:
current_app.logger.debug(
f"""Role '{profile["email"]}' does not exist. Creating role from user {profile["email"]}""")
role = role_service.create(
profile["email"],
description="This is a user specific role",
third_party=True,
)
roles.append(role)
# every user is a <default> (ties user to a default role, the default configuration is operator)
if current_app.config.get("LEMUR_DEFAULT_ROLE"):
default = role_service.get_by_name(current_app.config["LEMUR_DEFAULT_ROLE"])
if not default:
default = role_service.create(
current_app.config["LEMUR_DEFAULT_ROLE"],
description="This is the default Lemur role.",
)
roles.append(default)
# Dedupe the roles
roles = list(set(roles))
return roles