# EdpAuthorization

EdpAuthorization is a Python library that provides a flexible authorization mechanism for your applications. It allows you to define authorization policies and check if a given principal is authorized to perform an action on a resource.

### [Full Documentation](https://edeploy.atlassian.net/wiki/spaces/PB/pages/3965288453/Controle+de+autoriza+o+das+aplica+es+do+Backoffice)

## Features

- **Pluggable Authorization Services**: EdpAuthorization comes with different authorization service implementations:
    - `CedarpyAuthorizationServiceImpl`: Uses the `cedarpy` library to evaluate authorization policies written in the Cedar language locally.
    - `CedarApiAuthorizationServiceImpl`: Connects to a remote Cedar-compatible API to evaluate authorization policies.
    - `VerifiedPermissionsAuthorizationServiceImpl`: Uses AWS Verified Permissions to evaluate authorization policies.
    - `NoAuthorizationServiceImpl`: A "no-op" implementation that grants all access.
- **Async-Safe Registry**: Uses `contextvars.ContextVar` for per-request state, working correctly with both sync threads and async frameworks (FastAPI, async Lambda).
- **Authorization Decision Logging**: All authorization decisions are logged with principal, action, and resource details via the `edpauthorization.service.AuthorizationService` logger.
- **Extensible**: You can create your own authorization service by subclassing `AuthorizationService`.
- **Typed Data Transfer Objects**: The library uses `TypedDict` to define the structure of authorization principals and requests, providing better static analysis and code completion.

## Installation

```bash
pip install edpauthorization
```

## Usage

### 1. Choose an Authorization Service

First, you need to choose and configure an authorization service.

#### `CedarpyAuthorizationServiceImpl`

This service uses the `cedarpy` library to evaluate Cedar policies locally.

```python
from edpauthorization.service.impl.cedarpy import CedarpyAuthorizationServiceImpl

authorization_service = CedarpyAuthorizationServiceImpl(permission_dir="/path/to/your/policies")
```

The policies are organized by `principal_type` and `resource_type`. For example, a policy for a `User` principal and a `product` resource would be located in `/path/to/your/policies/User/product/`.

#### `CedarApiAuthorizationServiceImpl`

This service connects to a remote Cedar-compatible API.

```python
from edpauthorization.service.impl.cedar.cedarapi import CedarApiAuthorizationServiceImpl

authorization_service = CedarApiAuthorizationServiceImpl(
    cedar_service_url="http://localhost:8080",
    schema_namespace="MyApp"
)
```

#### `VerifiedPermissionsAuthorizationServiceImpl`

This service uses AWS Verified Permissions.

```python
from edpauthorization.service.impl.cedar.aws import VerifiedPermissionsAuthorizationServiceImpl

authorization_service = VerifiedPermissionsAuthorizationServiceImpl(
    policy_store_id="your-policy-store-id",
    schema_namespace="MyApp"
)
```

### 2. Define your Authorization Principal and Request

```python
from edpauthorization.dto import AuthorizationPrincipal, AuthorizationAction

principal = AuthorizationPrincipal(
    id="user123",
    type="User",
    attributes={"roles": ["admin"]}
)

request = {
    "action_name": AuthorizationAction.VIEW,
    "resource_type": "product",
    "resource": {"id": "prod456", "owner": "user123"},
    "context": {}
}
```

### 3. Check for Authorization

```python
if authorization_service.is_authorized(principal, request):
    print("Access granted!")
else:
    print("Access denied!")
```

You can also check for multiple permissions at once:

```python
requests = [
    {"action_name": AuthorizationAction.VIEW, "resource_type": "product", "resource": {"id": "prod456"}, "context": {}},
    {"action_name": AuthorizationAction.EDIT, "resource_type": "product", "resource": {"id": "prod456"}, "context": {}}
]

if authorization_service.are_authorized(principal, requests):
    print("All actions are authorized.")
else:
    print("Some actions are not authorized.")
```

## Optional Dependencies

EdpAuthorization has optional dependencies for different features. You can install them as needed:

- `httpmessageprocessor`: For using processors (`SecureApiProcessor`, `SecureProcessorAdapter`), callback (`AuthorizationCallback`), and `@exec_map` exception mapping.
- `verified-permissions`: For using the `VerifiedPermissionsAuthorizationServiceImpl`.
- `api`: For using the `CedarApiAuthorizationServiceImpl`.
- `cedarpy`: For using the `CedarpyAuthorizationServiceImpl`.

You can install them using:

```bash
pip install "edpauthorization[httpmessageprocessor,verified-permissions,api,cedarpy]"
```

## Contributing

Contributions are welcome! Please feel free to submit a pull request.

## License

This project is licensed under the MIT License.
