edwh-auth-rbac


Nameedwh-auth-rbac JSON
Version 0.8.1 PyPI version JSON
download
home_pageNone
SummaryRecursive Memberships and Permissions for the Education Warehouse Authentication System
upload_time2025-10-07 12:41:25
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseNone
keywords edwh omgeving whitelabel
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # edwh-auth-rbac

Role-Based Access Control (RBAC) library with recursive memberships for Python applications.

## Overview

This library implements a comprehensive RBAC system that supports:
- Users, groups, and items as identities
- Recursive group memberships (groups can contain other groups)
- Time-bound permissions with start/end dates
- Wildcard permissions (* for all privileges, all identities, or all targets)
- Password hashing with HMAC-SHA512 and per-entry random salts

## Mental Model

The system is built around three core concepts:

1. **Identities**: Users (people), Groups (collections), and Items (resources)
2. **Memberships**: Direct relationships between identities (who belongs to what)
3. **Permissions**: Granted privileges on targets with time constraints

## Key Features

- Recursive membership resolution through database views
- Efficient permission checking using JOINs with recursive membership views
- Flexible identity lookup by email, ID, UUID, or name
- Secure password storage with constant-time validation

## Installation

```bash
pip install edwh-auth-rbac
```

## Basic Usage
This requires a setup like the demo, see below for details, but this is how you would mostly use it in every day use: 

```python
from pydal import DAL
from edwh_auth_rbac import AuthRbac

# Initialize database
db = DAL('sqlite://storage.sqlite')

# Initialize RBAC
rbac = AuthRbac(db)
rbac.define_model(allowed_types=['user', 'group', 'item'], migrate=True)
```

### Creating Users and Groups

```python
# Create a group
admin_group = rbac.add_group(
    email="admin@example.com",
    name="Administrators",
    member_of=[]
)

# Create a user
user = rbac.add_user(
    email="john@example.com",
    firstname="John",
    fullname="John Doe",
    password="secure_password",
    member_of=[admin_group['object_id']]  # Add user to admin group
)
```

### Adding Permissions

```python
# Grant read permission to a user on a resource
rbac.add_permission(
    identity_key=user['object_id'],
    target_oid="document_123",
    privilege="read"
)

# Grant write permission to a group (affects all members)
rbac.add_permission(
    identity_key=admin_group['object_id'],
    target_oid="document_123",
    privilege="write"
)
```

### Checking Permissions

```python
# Check if user has permission
has_read = rbac.has_permission(
    identity_key=user['object_id'],
    target_oid="document_123",
    privilege="read"
)

print(f"User has read permission: {has_read}")
```

## Advanced Features

### Recursive Group Memberships

Groups can contain other groups, creating a hierarchy:

```python
# Create nested groups
root_group = rbac.add_group(email="root@example.com", name="Root", member_of=[])
middle_group = rbac.add_group(email="middle@example.com", name="Middle", member_of=[root_group['object_id']])
leaf_group = rbac.add_group(email="leaf@example.com", name="Leaf", member_of=[middle_group['object_id']])

# Add user to leaf group
user = rbac.add_user(
    email="user@example.com",
    firstname="User",
    fullname="Test User",
    password="password",
    member_of=[leaf_group['object_id']]
)

# User now has permissions granted to any of the parent groups
```

### Time-Bound Permissions

Permissions can be granted for specific time periods:

```python
import datetime as dt

rbac.add_permission(
    identity_key=user['object_id'],
    target_oid="document_123",
    privilege="read",
    starts=dt.datetime(2023, 1, 1),
    ends=dt.datetime(2023, 12, 31)
)
```

## Edge Cases and Assumptions

- **Circular group memberships** are prevented by the recursive view logic
- **Non-existent targets** in permissions are allowed (flexible resource modeling)
- **Time-bound permissions** with precise datetime validation
- **Wildcard permissions** that grant broad access rights (using "*")
- **Case-insensitive email handling**
- **Automatic cleanup** of related records when identities are removed
- Passwords are stored securely with HMAC-SHA512 and per-entry random salts
- Group names can be used as lookup keys for groups
- Email addresses needn't be unique across different identity types

### Setup demo database
For your own application, you'd probably want to use your own migration tool or use ours. But you'd have a list
of migrations where you will want to include these from the `src/edwh_auth_rbac/migrations.py` file

Prepare the migration:
```bash
cd your-demo-folder
mkdir flags
export MIGRATE_URI=sqlite://storage.sqlite
export FLAG_LOCATION=./flags
```
Execute the migration: 
```bash
$ migrate src/edwh_auth_rbac/migrations.py 
testing migrate lock file with the current version
Using lock file:  flags/migrate-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.complete
Using argument src/edwh_auth_rbac/migrations.py as a reference to the migrations file.
importing migrations from src/edwh_auth_rbac/migrations.py
starting migrate hook
2 migrations discovered
table not found, starting database restore
RECOVER: attempting recovery from a backup
RECOVER_DATABASE_FROM_BACKEND started 
RECOVER: /data/database_to_restore.NOTFOUND not found. Starting from scratch.
test: rbac_tables
run:  rbac_tables
ran:  rbac_tables successfully (0.01s wall, 0.00s CPU)
test: rbac_views
run:  rbac_views
ran:  rbac_views successfully (0.00s wall, 0.00s CPU)
migration completed successfully, marking success.
```

### Execute the example.py demo: 
```bash
$ python3 example.py 
=== Creating Users and Groups and Documents ===
Created document item: {'object_id': '208247a1-cf2f-4f4e-a0c9-3edc813a78b6', 'email': 'document@example.com', 'name': 'Test Document'}
Created admin group: {'object_id': '481c6a16-672f-43b7-ad71-2b1830a3dc09', 'email': 'admin@example.com', 'name': 'Administrators'}
Created user: {'object_id': 'c797b2da-47b4-42a4-ab1d-2c0b6150555f', 'email': 'john@example.com', 'firstname': 'John', 'fullname': 'John Doe'}

=== Adding Permissions ===
Granted read permission to user on document_123
Granted write permission to admin group on document_123

=== Checking Permissions ===
User has read permission: True
User has write permission: True

=== Example completed successfully! ===
```

## Database Schema

The library creates the following tables:
- `identity`: Core identity records with object_id, type, and credentials
- `membership`: Direct membership relationships between identities
- `permission`: Time-bound privilege grants from identity to target
- `recursive_memberships`: View showing all indirect memberships
- `recursive_members`: View showing all indirect members

## API Reference

For detailed API documentation, see the docstrings in the source code:
- `AuthRbac` class in `src/edwh_auth_rbac/rbac.py`
- Model functions in `src/edwh_auth_rbac/model.py`

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "edwh-auth-rbac",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "edwh, omgeving, whitelabel",
    "author": null,
    "author_email": "Remco Boerma <remco.b@educationwarehouse.nl>, Robin van der Noord <robin.vdn@educationwarehouse.nl>",
    "download_url": "https://files.pythonhosted.org/packages/8c/3e/1302a4b41f3976bc24eb5b21501e0e82669cd526afded082c991c038dba7/edwh_auth_rbac-0.8.1.tar.gz",
    "platform": null,
    "description": "# edwh-auth-rbac\n\nRole-Based Access Control (RBAC) library with recursive memberships for Python applications.\n\n## Overview\n\nThis library implements a comprehensive RBAC system that supports:\n- Users, groups, and items as identities\n- Recursive group memberships (groups can contain other groups)\n- Time-bound permissions with start/end dates\n- Wildcard permissions (* for all privileges, all identities, or all targets)\n- Password hashing with HMAC-SHA512 and per-entry random salts\n\n## Mental Model\n\nThe system is built around three core concepts:\n\n1. **Identities**: Users (people), Groups (collections), and Items (resources)\n2. **Memberships**: Direct relationships between identities (who belongs to what)\n3. **Permissions**: Granted privileges on targets with time constraints\n\n## Key Features\n\n- Recursive membership resolution through database views\n- Efficient permission checking using JOINs with recursive membership views\n- Flexible identity lookup by email, ID, UUID, or name\n- Secure password storage with constant-time validation\n\n## Installation\n\n```bash\npip install edwh-auth-rbac\n```\n\n## Basic Usage\nThis requires a setup like the demo, see below for details, but this is how you would mostly use it in every day use: \n\n```python\nfrom pydal import DAL\nfrom edwh_auth_rbac import AuthRbac\n\n# Initialize database\ndb = DAL('sqlite://storage.sqlite')\n\n# Initialize RBAC\nrbac = AuthRbac(db)\nrbac.define_model(allowed_types=['user', 'group', 'item'], migrate=True)\n```\n\n### Creating Users and Groups\n\n```python\n# Create a group\nadmin_group = rbac.add_group(\n    email=\"admin@example.com\",\n    name=\"Administrators\",\n    member_of=[]\n)\n\n# Create a user\nuser = rbac.add_user(\n    email=\"john@example.com\",\n    firstname=\"John\",\n    fullname=\"John Doe\",\n    password=\"secure_password\",\n    member_of=[admin_group['object_id']]  # Add user to admin group\n)\n```\n\n### Adding Permissions\n\n```python\n# Grant read permission to a user on a resource\nrbac.add_permission(\n    identity_key=user['object_id'],\n    target_oid=\"document_123\",\n    privilege=\"read\"\n)\n\n# Grant write permission to a group (affects all members)\nrbac.add_permission(\n    identity_key=admin_group['object_id'],\n    target_oid=\"document_123\",\n    privilege=\"write\"\n)\n```\n\n### Checking Permissions\n\n```python\n# Check if user has permission\nhas_read = rbac.has_permission(\n    identity_key=user['object_id'],\n    target_oid=\"document_123\",\n    privilege=\"read\"\n)\n\nprint(f\"User has read permission: {has_read}\")\n```\n\n## Advanced Features\n\n### Recursive Group Memberships\n\nGroups can contain other groups, creating a hierarchy:\n\n```python\n# Create nested groups\nroot_group = rbac.add_group(email=\"root@example.com\", name=\"Root\", member_of=[])\nmiddle_group = rbac.add_group(email=\"middle@example.com\", name=\"Middle\", member_of=[root_group['object_id']])\nleaf_group = rbac.add_group(email=\"leaf@example.com\", name=\"Leaf\", member_of=[middle_group['object_id']])\n\n# Add user to leaf group\nuser = rbac.add_user(\n    email=\"user@example.com\",\n    firstname=\"User\",\n    fullname=\"Test User\",\n    password=\"password\",\n    member_of=[leaf_group['object_id']]\n)\n\n# User now has permissions granted to any of the parent groups\n```\n\n### Time-Bound Permissions\n\nPermissions can be granted for specific time periods:\n\n```python\nimport datetime as dt\n\nrbac.add_permission(\n    identity_key=user['object_id'],\n    target_oid=\"document_123\",\n    privilege=\"read\",\n    starts=dt.datetime(2023, 1, 1),\n    ends=dt.datetime(2023, 12, 31)\n)\n```\n\n## Edge Cases and Assumptions\n\n- **Circular group memberships** are prevented by the recursive view logic\n- **Non-existent targets** in permissions are allowed (flexible resource modeling)\n- **Time-bound permissions** with precise datetime validation\n- **Wildcard permissions** that grant broad access rights (using \"*\")\n- **Case-insensitive email handling**\n- **Automatic cleanup** of related records when identities are removed\n- Passwords are stored securely with HMAC-SHA512 and per-entry random salts\n- Group names can be used as lookup keys for groups\n- Email addresses needn't be unique across different identity types\n\n### Setup demo database\nFor your own application, you'd probably want to use your own migration tool or use ours. But you'd have a list\nof migrations where you will want to include these from the `src/edwh_auth_rbac/migrations.py` file\n\nPrepare the migration:\n```bash\ncd your-demo-folder\nmkdir flags\nexport MIGRATE_URI=sqlite://storage.sqlite\nexport FLAG_LOCATION=./flags\n```\nExecute the migration: \n```bash\n$ migrate src/edwh_auth_rbac/migrations.py \ntesting migrate lock file with the current version\nUsing lock file:  flags/migrate-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.complete\nUsing argument src/edwh_auth_rbac/migrations.py as a reference to the migrations file.\nimporting migrations from src/edwh_auth_rbac/migrations.py\nstarting migrate hook\n2 migrations discovered\ntable not found, starting database restore\nRECOVER: attempting recovery from a backup\nRECOVER_DATABASE_FROM_BACKEND started \nRECOVER: /data/database_to_restore.NOTFOUND not found. Starting from scratch.\ntest: rbac_tables\nrun:  rbac_tables\nran:  rbac_tables successfully (0.01s wall, 0.00s CPU)\ntest: rbac_views\nrun:  rbac_views\nran:  rbac_views successfully (0.00s wall, 0.00s CPU)\nmigration completed successfully, marking success.\n```\n\n### Execute the example.py demo: \n```bash\n$ python3 example.py \n=== Creating Users and Groups and Documents ===\nCreated document item: {'object_id': '208247a1-cf2f-4f4e-a0c9-3edc813a78b6', 'email': 'document@example.com', 'name': 'Test Document'}\nCreated admin group: {'object_id': '481c6a16-672f-43b7-ad71-2b1830a3dc09', 'email': 'admin@example.com', 'name': 'Administrators'}\nCreated user: {'object_id': 'c797b2da-47b4-42a4-ab1d-2c0b6150555f', 'email': 'john@example.com', 'firstname': 'John', 'fullname': 'John Doe'}\n\n=== Adding Permissions ===\nGranted read permission to user on document_123\nGranted write permission to admin group on document_123\n\n=== Checking Permissions ===\nUser has read permission: True\nUser has write permission: True\n\n=== Example completed successfully! ===\n```\n\n## Database Schema\n\nThe library creates the following tables:\n- `identity`: Core identity records with object_id, type, and credentials\n- `membership`: Direct membership relationships between identities\n- `permission`: Time-bound privilege grants from identity to target\n- `recursive_memberships`: View showing all indirect memberships\n- `recursive_members`: View showing all indirect members\n\n## API Reference\n\nFor detailed API documentation, see the docstrings in the source code:\n- `AuthRbac` class in `src/edwh_auth_rbac/rbac.py`\n- Model functions in `src/edwh_auth_rbac/model.py`\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Recursive Memberships and Permissions for the Education Warehouse Authentication System",
    "version": "0.8.1",
    "project_urls": {
        "Documentation": "https://github.com/educationwarehouse/edwh-auth-rbac#readme",
        "Issues": "https://github.com/educationwarehouse/edwh-auth-rbac/issues",
        "Source": "https://github.com/educationwarehouse/edwh-auth-rbac"
    },
    "split_keywords": [
        "edwh",
        " omgeving",
        " whitelabel"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7d03efd8016521d6b6d3c4e6e94d3338843b0639b5f81ab3efb9cef43c0f56c4",
                "md5": "4f74ffc69fae59e055a1e17f10312ab6",
                "sha256": "afc36d0517c1b7c555924f6999471404d54e75c50604b7eb12c4aae35029787c"
            },
            "downloads": -1,
            "filename": "edwh_auth_rbac-0.8.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "4f74ffc69fae59e055a1e17f10312ab6",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 21335,
            "upload_time": "2025-10-07T12:41:23",
            "upload_time_iso_8601": "2025-10-07T12:41:23.746414Z",
            "url": "https://files.pythonhosted.org/packages/7d/03/efd8016521d6b6d3c4e6e94d3338843b0639b5f81ab3efb9cef43c0f56c4/edwh_auth_rbac-0.8.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8c3e1302a4b41f3976bc24eb5b21501e0e82669cd526afded082c991c038dba7",
                "md5": "d5bf036a365d757fe22a36398c55c911",
                "sha256": "acd9d778c1578bbbf60d66ce389eb7a87a2542aa3598a46ca54c3307f7f6a01b"
            },
            "downloads": -1,
            "filename": "edwh_auth_rbac-0.8.1.tar.gz",
            "has_sig": false,
            "md5_digest": "d5bf036a365d757fe22a36398c55c911",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 69380,
            "upload_time": "2025-10-07T12:41:25",
            "upload_time_iso_8601": "2025-10-07T12:41:25.123883Z",
            "url": "https://files.pythonhosted.org/packages/8c/3e/1302a4b41f3976bc24eb5b21501e0e82669cd526afded082c991c038dba7/edwh_auth_rbac-0.8.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-07 12:41:25",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "educationwarehouse",
    "github_project": "edwh-auth-rbac#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "edwh-auth-rbac"
}
        
Elapsed time: 2.99048s