Hone logo
Hone
Problems

Implementing Role-Based Access Control (RBAC) in Python

Role-Based Access Control (RBAC) is a crucial security paradigm for managing user permissions. This challenge asks you to implement a basic RBAC system in Python, allowing you to define roles with specific permissions and then assign users to those roles. This is a common requirement in web applications and other systems where access control is necessary.

Problem Description

You need to design and implement a system that manages user roles and permissions. The system should allow you to:

  1. Define Roles: Create roles (e.g., "admin", "editor", "viewer") and associate each role with a set of permissions (e.g., "create_post", "edit_post", "view_post").
  2. Assign Users to Roles: Assign users to one or more roles.
  3. Check Permissions: Given a user and a specific action (permission), determine whether the user is authorized to perform that action.

The core of the system should be a class called RBACManager. This class should have methods for defining roles, assigning users to roles, and checking permissions.

Key Requirements:

  • The system should be extensible to handle new roles and permissions easily.
  • The permission checking logic should be clear and concise.
  • The system should handle cases where a user has multiple roles.
  • The system should handle cases where a user has no roles assigned.

Expected Behavior:

  • When checking permissions, the system should return True if the user has the required permission through any of their assigned roles, and False otherwise.
  • The system should not raise errors if a role or permission does not exist. Instead, it should return False when checking permissions for non-existent roles or permissions.

Edge Cases to Consider:

  • User with no roles assigned.
  • Role with no permissions assigned.
  • Permission that doesn't exist.
  • User assigned to multiple roles, some with overlapping permissions.
  • Case-insensitive permission checking (optional, but good practice).

Examples

Example 1:

Input:
roles = {
    "admin": ["create_post", "edit_post", "view_post", "delete_post"],
    "editor": ["edit_post", "view_post"],
    "viewer": ["view_post"]
}
user_roles = {
    "user1": ["admin", "editor"],
    "user2": ["viewer"]
}

rbac = RBACManager(roles)
rbac.assign_user_roles(user_roles)

print(rbac.check_permission("user1", "create_post"))
print(rbac.check_permission("user1", "delete_post"))
print(rbac.check_permission("user2", "edit_post"))
print(rbac.check_permission("user3", "view_post")) # user3 has no roles

Output:

True
True
False
False

Explanation: "user1" is an admin and an editor, so they have "create_post" and "delete_post" permissions. "user2" is a viewer, so they only have "view_post" permission. "user3" has no roles, so they have no permissions.

Example 2:

Input:
roles = {
    "admin": ["create_post", "edit_post", "view_post"],
    "editor": ["edit_post", "view_post"],
    "viewer": ["view_post"]
}
user_roles = {
    "user1": ["admin"],
    "user2": ["editor"],
    "user3": ["viewer"]
}

rbac = RBACManager(roles)
rbac.assign_user_roles(user_roles)

print(rbac.check_permission("user1", "view_post"))
print(rbac.check_permission("user2", "create_post"))
print(rbac.check_permission("user3", "edit_post"))

Output:

True
False
False

Explanation: "user1" has "view_post" permission as an admin. "user2" does not have "create_post" permission. "user3" does not have "edit_post" permission.

Constraints

  • The number of roles will be between 1 and 100.
  • The number of permissions per role will be between 0 and 20.
  • The number of users will be between 1 and 50.
  • Role and permission names will be strings of length between 1 and 32 characters.
  • User names will be strings of length between 1 and 32 characters.
  • The permission checking operation should complete in O(n) time, where n is the number of roles the user has.

Notes

  • Consider using dictionaries to represent roles and permissions for efficient lookups.
  • Think about how to handle the case where a user has multiple roles. You'll need to iterate through their roles and check permissions.
  • You can choose to implement case-insensitive permission checking for added flexibility. If you do, ensure that the comparison is consistent.
  • Focus on creating a clean and well-documented solution. The code should be easy to understand and maintain.
  • Error handling is not explicitly required for this challenge, but consider how you might handle invalid input in a real-world application.
Loading editor...
python