# Django Ninja Shield
A powerful and flexible permissions control package for Django Ninja. This package allows you to easily manage and combine permissions for your Django Ninja API endpoints using a clean and intuitive syntax.
## Features
- 🛡️ Simple permission decorators for Django Ninja endpoints
- ⚡ Combine permissions using logical operations (AND, OR, NOT)
- 🔒 Built on top of Django's permission system
- 🚀 Type-safe with full typing support
## Installation
You can install the package using pip:
```bash
pip install django-ninja-shield
```
Or if you're using Poetry:
```bash
poetry add django-ninja-shield
```
## Basic Usage
Here's a simple example of how to use django-ninja-shield:
```python
from django_ninja_shield import requires_permissions
from ninja import Router
router = Router()
@router.get("/articles")
@requires_permissions("articles.view_article")
def get_articles(request):
return {"message": "You have permission to view articles"}
```
## Advanced Usage
### Combining Permissions
You can combine multiple permissions using logical operators:
```python
from django_ninja_shield import requires_permissions, P
router = Router()
# Using AND operator
@router.post("/articles")
@requires_permissions(P("articles.add_article") & P("articles.change_article"))
def create_article(request):
return {"message": "You have permission to create articles"}
# Using OR operator
@router.get("/dashboard")
@requires_permissions(P("admin.view_dashboard") | P("staff.view_dashboard"))
def view_dashboard(request):
return {"message": "You have permission to view the dashboard"}
# Using NOT operator
@router.get("/public")
@requires_permissions(~P("articles.is_restricted"))
def public_view(request):
return {"message": "This is a public view"}
```
### Complex Permission Combinations
You can create complex permission rules by combining multiple operations:
```python
from django_ninja_shield import requires_permissions, P, IsAdmin, IsUseruser, IsStaff, IsActive
@router.put("/articles/{article_id}")
@requires_permissions(
(P("articles.change_article") & P("articles.view_article")) |
IsAdmin() # or: IsStaff(), IsSuperuser, IsActive
)
def update_article(request, article_id: int):
return {"message": f"Article {article_id} updated"}
```
## Response Format
When permission is denied, the API returns a 403 Forbidden response with the following format:
```json
{
"detail": "Permission denied"
}
```
## Requirements
- Python ≥ 3.10
- Django ≥ 4.0.0
## License
This project is licensed under the MIT License.
Raw data
{
"_id": null,
"home_page": "https://github.com/medram/django-ninja-shield",
"name": "django-ninja-shield",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.10",
"maintainer_email": null,
"keywords": "django, django-ninja, permissions, shield, ninja permissions",
"author": "medram",
"author_email": "mramouchy@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/5d/a0/d4f6482a7ff3bfc4ed25feaa57c62338b17e4d09abd3169c0cbade2caae1/django_ninja_shield-0.0.5.tar.gz",
"platform": null,
"description": "# Django Ninja Shield\n\nA powerful and flexible permissions control package for Django Ninja. This package allows you to easily manage and combine permissions for your Django Ninja API endpoints using a clean and intuitive syntax.\n\n## Features\n\n- \ud83d\udee1\ufe0f Simple permission decorators for Django Ninja endpoints\n- \u26a1 Combine permissions using logical operations (AND, OR, NOT)\n- \ud83d\udd12 Built on top of Django's permission system\n- \ud83d\ude80 Type-safe with full typing support\n\n## Installation\n\nYou can install the package using pip:\n\n```bash\npip install django-ninja-shield\n```\n\nOr if you're using Poetry:\n\n```bash\npoetry add django-ninja-shield\n```\n\n## Basic Usage\n\nHere's a simple example of how to use django-ninja-shield:\n\n```python\nfrom django_ninja_shield import requires_permissions\nfrom ninja import Router\n\nrouter = Router()\n\n@router.get(\"/articles\")\n@requires_permissions(\"articles.view_article\")\ndef get_articles(request):\n return {\"message\": \"You have permission to view articles\"}\n```\n\n## Advanced Usage\n\n### Combining Permissions\n\nYou can combine multiple permissions using logical operators:\n\n```python\nfrom django_ninja_shield import requires_permissions, P\n\nrouter = Router()\n\n# Using AND operator\n@router.post(\"/articles\")\n@requires_permissions(P(\"articles.add_article\") & P(\"articles.change_article\"))\ndef create_article(request):\n return {\"message\": \"You have permission to create articles\"}\n\n# Using OR operator\n@router.get(\"/dashboard\")\n@requires_permissions(P(\"admin.view_dashboard\") | P(\"staff.view_dashboard\"))\ndef view_dashboard(request):\n return {\"message\": \"You have permission to view the dashboard\"}\n\n# Using NOT operator\n@router.get(\"/public\")\n@requires_permissions(~P(\"articles.is_restricted\"))\ndef public_view(request):\n return {\"message\": \"This is a public view\"}\n```\n\n### Complex Permission Combinations\n\nYou can create complex permission rules by combining multiple operations:\n\n```python\nfrom django_ninja_shield import requires_permissions, P, IsAdmin, IsUseruser, IsStaff, IsActive\n\n@router.put(\"/articles/{article_id}\")\n@requires_permissions(\n (P(\"articles.change_article\") & P(\"articles.view_article\")) |\n IsAdmin() # or: IsStaff(), IsSuperuser, IsActive\n)\ndef update_article(request, article_id: int):\n return {\"message\": f\"Article {article_id} updated\"}\n```\n\n## Response Format\n\nWhen permission is denied, the API returns a 403 Forbidden response with the following format:\n\n```json\n{\n \"detail\": \"Permission denied\"\n}\n```\n\n## Requirements\n\n- Python \u2265 3.10\n- Django \u2265 4.0.0\n\n## License\n\nThis project is licensed under the MIT License.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A python package to control permissions for django ninja.",
"version": "0.0.5",
"project_urls": {
"Documentation": "https://github.com/medram/django-ninja-shield",
"Homepage": "https://github.com/medram/django-ninja-shield",
"Repository": "https://github.com/medram/django-ninja-shield"
},
"split_keywords": [
"django",
" django-ninja",
" permissions",
" shield",
" ninja permissions"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b15adec0676191a97c1558acab85872ef03f57015e894230274eeea2b98cbfa2",
"md5": "85238f0eb3f57ad857430a2da1a2da67",
"sha256": "43ecabc02c274c75aa50ca2d5f7bf3ed137d9f63b83a819d0fc96567d2bbd807"
},
"downloads": -1,
"filename": "django_ninja_shield-0.0.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "85238f0eb3f57ad857430a2da1a2da67",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.10",
"size": 5010,
"upload_time": "2025-03-03T11:54:28",
"upload_time_iso_8601": "2025-03-03T11:54:28.237939Z",
"url": "https://files.pythonhosted.org/packages/b1/5a/dec0676191a97c1558acab85872ef03f57015e894230274eeea2b98cbfa2/django_ninja_shield-0.0.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5da0d4f6482a7ff3bfc4ed25feaa57c62338b17e4d09abd3169c0cbade2caae1",
"md5": "00dc228bb03193a3bb73b37246f51152",
"sha256": "f9c99e55a9328a52fe175175b60bd912399ba1da65caba03ffbdec673bb7889b"
},
"downloads": -1,
"filename": "django_ninja_shield-0.0.5.tar.gz",
"has_sig": false,
"md5_digest": "00dc228bb03193a3bb73b37246f51152",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.10",
"size": 3580,
"upload_time": "2025-03-03T11:54:29",
"upload_time_iso_8601": "2025-03-03T11:54:29.342945Z",
"url": "https://files.pythonhosted.org/packages/5d/a0/d4f6482a7ff3bfc4ed25feaa57c62338b17e4d09abd3169c0cbade2caae1/django_ninja_shield-0.0.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-03-03 11:54:29",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "medram",
"github_project": "django-ninja-shield",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "django-ninja-shield"
}