Skip to main content

A library to apply JSON patches with rule-based access control.

Project description

python-json-patch-rules

Json Patch Rules is a Python library designed to facilitate the application of JSON patch operations while enforcing customizable validation rules. This library ensures that updates to JSON objects adhere to predefined permissions, making it ideal for systems that require granular access control.

Features

  • Rule-Based Validation: Define rules that specify which paths in a JSON object are allowed to be updated.
  • Wildcard Support: Use wildcards to specify rules for dynamic keys and array indices.
  • Data Integrity: Ensure that only permitted paths can be updated, preserving the integrity of the JSON structure.

Installation

Install Json Patch Rules using pip:

pip install python-json-patch-rules

API

Rule Description
{*} Implicit set - allows to set new attributes but not remove them.
!{*} Implicit set - denies the ability to set new attributes.
[0] Implicit set - allows replacing index "0" with any value (string, object, int, etc).
[0]|replace Allows replacing index "0" with any value (string, object, int, etc).
[*]|unique Allows replacing an array but denies if there are duplicated items (works only for arrays of strings).
user Allows setting value to user property (must be an object at root level).
!user Denies setting value to user property (must be an object at root level).
[0].title Allows setting new value for properties (in this case title).
[0].nested.foo Allows setting new value for property nested but will fail if not object type.
user.contacts[0].phone Allows setting user contacts but only if array index 0 and only property phone.
user.contacts[0].label Allows setting user contacts but only if array index 0 and only property label.
user.contacts[*].label Allows setting property label to any index inside contacts array.
bar.key1.b Allows to set "foo.key1.b" only.
!bar.key1.b Denies to set "foo.key1.b" only.

Expanded Example Scenario

Let's imagine a more complex JSON structure representing a user profile, including nested objects for personal details, permissions, and an array of contact methods.

from json_patch_rules import patch_rules

# Define a complex JSON object
data = {
    "user": {
        "name": "John Doe",
        "email": "john@example.com",
        "permissions": {
            "edit": True,
            "delete": False
        },
        "contacts": [
            {"type": "home", "number": "1234567890", "label": "Home Phone"},
            {"type": "work", "number": "0987654321", "label": "Work Phone"}
        ]
    }
}

# Define rules to specify allowed updates
rules = [
    "!user.permissions.delete",       # Denies deletion of the delete permission under user permissions
    "user.name",                      # Allows replacing the name attribute under user
    "user.contacts[0].number",        # Allows replacing the phone number in the first contact
    "user.contacts[*].label",         # Allows updating label for any contact in the contacts array
]

# Initialize patch rules
patch = patch_rules(rules)

# Define new data to apply
new_data = {
    "user": {
        "name": "Jane Doe",
        "permissions": {
            "edit": False,
            "delete": True  # This update will be denied by the rule
        },
        "contacts": [
            {"number": "1111111111"},  # Allowed update
            {"label": "Emergency Phone"}  # Allowed update
        ]
    }
}

# Apply the patch
result = patch.apply(data, new_data)

# Output the updated JSON object
print("Patched Data:", result.data) # patched data
print("Denied Paths:", result.denied_paths) # Denied Paths: ['user.permissions.edit', 'user.permissions.delete']
print("Successed Paths:", result.successed_paths) # Successed Paths: ['user.name', 'user.contacts[0].number', 'user.contacts[1].label']

Explaining the Code

Initializing the Json Patch Rules Library

  • Importing the Library:
    from json_patch_rules import patch_rules
    
    This line imports the patch_rules function from the Json Patch Rules library, making it available to use in the script.

Defining the Data Structure

  • JSON Data (data):
    data = {
        "user": {
            "name": "John Doe",
            "email": "john@example.com",
            "permissions": {
                "edit": True,
                "delete": False
            },
            "contacts": [
                {"type": "home", "number": "1234567890", "label": "Home Phone"},
                {"type": "work", "number": "0987654321", "label": "Work Phone"}
            ]
        }
    }
    
    This JSON object represents a structured user profile with personal details, permissions, and contacts. Each contact is detailed with a type, number, and label.

Setting Up the Rules

  • Rules Definition (rules):
    rules = [
        "!user.permissions.delete",
        "user.name",
        "user.contacts[0].number",
        "user.contacts[*].label",
    ]
    
    Here, we define a list of strings where each string is a rule that governs how the JSON data can be updated:
    • "!user.permissions.delete" denies any changes to the delete permission.
    • "user.name" allows changes to the user's name.
    • "user.contacts[0].number" allows changes to the number of the first contact.
    • "user.contacts[*].label" allows changes to the label of any contact in the contacts array.

Initializing Patch Rules

  • Patch Initialization (patch):
    patch = patch_rules(rules)
    
    This creates a new instance of patch rules using the defined rules. This instance will be used to apply changes to the JSON data according to the specified rules.

Defining New Data for Updates

  • New Data (new_data):
    new_data = {
        "user": {
            "name": "Jane Doe",
            "permissions": {
                "edit": False,
                "delete": True
            },
            "contacts": [
                {"number": "1111111111"},
                {"label": "Emergency Phone"}
            ]
        }
    }
    
    Specifies the proposed changes, including updates to the user's name, permissions, and contact details. According to the rules, the change to the delete permission will be denied.

Applying the Patch

  • Applying the Patch (result):
    result = patch.apply(data, new_data)
    
    The apply method is called on the patch object with the original data and the new data. It processes each change against the established rules, applying allowed updates and blocking prohibited ones.

Result Analysis

  • Output Results:
    print("Patched Data:", result.data)
    print("Denied Paths:", result.denied_paths)
    print("Successed Paths:", result.successed_paths)
    
    After applying the patch, this section prints the updated JSON data, paths of denied updates, and paths of successful updates. This feedback helps validate that the Json Patch Rules library is effectively controlling data modifications according to the defined rules.

The result object will contain details about the operation, including which paths were updated successfully and which were denied.

Contributing

Contributions are welcome! Please feel free to submit pull requests, report bugs, and suggest features.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python_json_patch_rules-0.3.2.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

python_json_patch_rules-0.3.2-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file python_json_patch_rules-0.3.2.tar.gz.

File metadata

File hashes

Hashes for python_json_patch_rules-0.3.2.tar.gz
Algorithm Hash digest
SHA256 e0f60b7916bcafe2e6c51c11f4afa13b848a54bc4878d6f9a016bb8e5033e818
MD5 fbfcc0b9274ffdb75c53430f0988551b
BLAKE2b-256 360227c6a40957d2dbc77a49d279d6b3561d67cb3c128b01976dd08a82401bcd

See more details on using hashes here.

File details

Details for the file python_json_patch_rules-0.3.2-py3-none-any.whl.

File metadata

File hashes

Hashes for python_json_patch_rules-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4d828e12c1909fa8bb32354477d02ba7b8a80fa7432953434656802c7911ecb8
MD5 1c81b11ae22e0989953d1736882c4312
BLAKE2b-256 aefdd2f9e5aea0ab0064d14c69394ba375feabde0c0494adb0b9429fcc6c09e7

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page