معرفی شرکت ها


drf-confidential-1.0.1


Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر

توضیحات

Handle sensitive fields for django rest framework
ویژگی مقدار
سیستم عامل -
نام فایل drf-confidential-1.0.1
نام drf-confidential
نسخه کتابخانه 1.0.1
نگهدارنده []
ایمیل نگهدارنده []
نویسنده Liquan Yang
ایمیل نویسنده yang.liquan87@gmail.com
آدرس صفحه اصلی https://github.com/resurrexi/drf-confidential
آدرس اینترنتی https://pypi.org/project/drf-confidential/
مجوز MIT
# drf-confidential [![Build Status](https://travis-ci.org/resurrexi/drf-confidential.svg?branch=master)](https://travis-ci.org/resurrexi/drf-confidential) [![codecov](https://codecov.io/gh/resurrexi/drf-confidential/branch/master/graph/badge.svg)](https://codecov.io/gh/resurrexi/drf-confidential) **drf-confidential** is a package to help you control how a model's sensitive data is shared across your API. ## Installation ```bash pip install drf-confidential ``` ## Motivation Imagine you have the following models declared as: ```python from django.contrib.auth.models import AbstractUser from django.db import models class Profile(AbstractUser): email = models.EmailField(unique=True) employee_profile = models.OneToOneField( "Employee", null=True, on_delete=models.PROTECT, related_name='login_account' ) class Employee(models.Model): first_name = models.CharField(max_length=64) last_name = models.CharField(max_length=64) address_1 = models.CharField(max_length=256) address_2 = models.CharField(max_length=256, blank=True) country = models.CharField(max_length=64) city = models.CharField(max_length=64) phone_number = models.CharField(max_length=16) ``` Every field except for `first_name` and `last_name` in the `Employee` model is considered sensitive data. This means that only the `Profile` user with the linked `employee_profile`, or a user with elevated privileges (e.g. an admin or HR staff), can access those fields. Unfortunately, there is no simple way to control permissions down to the field level in DRF. Enter **drf-confidential**. ## drf-confidential in action Let's suppose there are 2 users: * *amazhong* is just a regular user without elevated privileges * *googe* is a staff/admin with elevated privileges ### What happens when they make a GET request on the `Employee` list endpoint? <table> <thead> <tr><td colspan="2">GET /api/employees/</td></tr> </thead> <tbody> <tr><td>amazhong</td><td>googe</td></tr> <tr> <td> ```json 200 OK { "count": 2, "next": null, "previous": null, "results": [ { "id": 1, "first_name": "Ama", "last_name": "Zhong", "address_1": "440 Terry Ave N", "address_2": "", "country": "US", "city": "Seattle", "phone_number": "+12062661000" }, { "id": 2, "first_name": "Goo", "last_name": "Ge" } ] } ``` </td> <td> ```json 200 OK { "count": 2, "next": null, "previous": null, "results": [ { "id": 1, "first_name": "Ama", "last_name": "Zhong", "address_1": "440 Terry Ave N", "address_2": "", "country": "US", "city": "Seattle", "phone_number": "+12062661000" }, { "id": 2, "first_name": "Goo", "last_name": "Ge", "address_1": "1600 Amphitheatre Pkwy", "address_2": "", "country": "US", "city": "Mountain View", "phone_number": "+16502530000" } ] } ``` </td> </tr> </tbody> </table> ### What about GET requests at the detail level? <table> <thead> <tr><td colspan="2">GET /api/employees/1/</td></tr> </thead> <tbody> <tr><td>amazhong</td><td>googe</td></tr> <tr> <td> ```json 200 OK { "id": 1, "first_name": "Ama", "last_name": "Zhong", "address_1": "440 Terry Ave N", "address_2": "", "country": "US", "city": "Seattle", "phone_number": "+12062661000" } ``` </td> <td> ```json 200 OK { "id": 1, "first_name": "Ama", "last_name": "Zhong", "address_1": "440 Terry Ave N", "address_2": "", "country": "US", "city": "Seattle", "phone_number": "+12062661000" } ``` </td> </tr> </tbody> </table> <table> <thead> <tr><td colspan="2">GET /api/employees/2/</td></tr> </thead> <tbody> <tr><td>amazhong</td><td>googe</td></tr> <tr> <td> ```json 200 OK { "id": 2, "first_name": "Goo", "last_name": "Ge" } ``` </td> <td> ```json 200 OK { "id": 2, "first_name": "Goo", "last_name": "Ge", "address_1": "1600 Amphitheatre Pkwy", "address_2": "", "country": "US", "city": "Mountain View", "phone_number": "+16502530000" } ``` </td> </tr> </tbody> </table> ### What about create? <table> <thead> <tr><td colspan="2"> POST /api/employees/ ```json { "first_name": "Ah", "last_name": "Poh", "address_1": "One Apple Park Way", "address_2": "", "country": "US", "city": "Cupertino", "phone_number": "+14089961010" } ``` </td></tr> </thead> <tbody> <tr><td>amazhong</td><td>googe</td></tr> <tr> <td> ```json 403 FORBIDDEN ``` </td> <td> ```json 201 CREATED { "id": 3, "first_name": "Ah", "last_name": "Poh", "address_1": "One Apple Park Way", "address_2": "", "country": "US", "city": "Cupertino", "phone_number": "+14089961010" } ``` </td> </tr> </tbody> </table> ### And update? <table> <thead> <tr><td colspan="2"> PATCH /api/employees/1/ ```json { "address_1": "123 New Drive", "phone_number": "+13214567890" } ``` </td></tr> </thead> <tbody> <tr><td>amazhong</td><td>googe</td></tr> <tr> <td> ```json 200 OK { "id": 1, "first_name": "Ama", "last_name": "Zhong", "address_1": "123 New Drive", "address_2": "", "country": "US", "city": "Seattle", "phone_number": "+13214567890" } ``` </td> <td> ```json 200 OK { "id": 1, "first_name": "Ama", "last_name": "Zhong", "address_1": "123 New Drive", "address_2": "", "country": "US", "city": "Seattle", "phone_number": "+13214567890" } ``` </td> </tr> </tbody> </table> <table> <thead> <tr><td colspan="2"> PATCH /api/employees/2/ ```json { "address_1": "123 New Drive", "phone_number": "+13214567890" } ``` </td></tr> </thead> <tbody> <tr><td>amazhong</td><td>googe</td></tr> <tr> <td> ```json 403 FORBIDDEN ``` </td> <td> ```json 200 OK { "id": 2, "first_name": "Goo", "last_name": "Ge", "address_1": "123 New Drive", "address_2": "", "country": "US", "city": "Mountain View", "phone_number": "+13214567890" } ``` </td> </tr> </tbody> </table> ### And delete? <table> <thead> <tr><td colspan="2">DELETE /api/employees/1/</td></tr> </thead> <tbody> <tr><td>amazhong</td><td>googe</td></tr> <tr> <td> ```json 204 NO CONTENT ``` </td> <td> ```json 204 NO CONTENT ``` </td> </tr> </tbody> </table> <table> <thead> <tr><td colspan="2">DELETE /api/employees/2/</td></tr> </thead> <tbody> <tr><td>amazhong</td><td>googe</td></tr> <tr> <td> ```json 403 FORBIDDEN ``` </td> <td> ```json 204 NO CONTENT ``` </td> </tr> </tbody> </table> ## Basic usage ### Step 1 Create a confidential permission on your model and `python manage.py migrate`. ```python class Employee(models.Model): ... # fields defined earlier above class Meta: permissions = ( ("view_sensitive_employee", "Can view employees' sensitive data"), ) ``` ### Step 2 Add the `ConfidentialFieldsMixin` to your serializer and define your `confidential_fields` and `user_relation` lookup. ```python from rest_framework import serializers from drf_confidential.mixins import ConfidentialFieldsMixin class EmployeeSerializer(ConfidentialFieldsMixin, serializers.ModelSerializer): class Meta: model = Employee fields = "__all__" confidential_fields = ( "address_1", "address_2", "country", "city", "phone_number", ) user_relation = "login_account" ``` `ConfidentialFieldsMixin` is configured to look for cases where either the request user is the model instance, the request user owns the model instance, the request user has a relation to the model instance, or the request user has the elevated permissions. The `confidential_fields` meta attribute specifies which fields are considered sensitive. The `user_relation` lookup specifies the relation of the model to the user model. In the [model definitions above](#Motivation), the relation to the `Profile` model from the `Employee` model is through the back-reference, `login_account`. ### Step 3 Add the `ConfidentialFieldsPermission` as a permission class to the viewset. ```python from rest_framework.viewsets import ModelViewSet from drf_confidential.permissions import ConfidentialFieldsPermission class EmployeeViewSet(ModelViewSet): serializer_class = EmployeeSerializer queryset = Employee.objects.all() permission_classes = [ ... # your default permissions, e.g. IsAuthenticated ConfidentialFieldsPermission ] ``` The permission follows the logic that a user must have either elevated permissions, have ownership, or have a relation to the model instance if they want to `update`, `partial_update`, or `delete`. For `create`, only users with elevated permissions are allowed. For `retrieve` and `list`, all users are allowed.


نیازمندی

مقدار نام
<3.0 django
>=3.11.0,<4.0.0 djangorestframework


زبان مورد نیاز

مقدار نام
>=3.7,<4.0 Python


نحوه نصب


نصب پکیج whl drf-confidential-1.0.1:

    pip install drf-confidential-1.0.1.whl


نصب پکیج tar.gz drf-confidential-1.0.1:

    pip install drf-confidential-1.0.1.tar.gz