# php-pdp-sdk
Policy decision point (PDP) sdk client for PHP application_family: php-monolith

### Generating Models for the ows-pdp client
We use openapitools/openapi-generator to generate models for interacting with relevant ows-pdp endpoints. To re-generate models using qa-ows-pdp.theorchard.io, run:

🚨 You will likely want to delete the src/Connectors/OwsPdp/Model dir before re-generating models!

```bash
bash ./generate_php_pdp_models.sh
```

You can review the full list of files that were autogenerated in src/Connectors/.openapi-generator/FILES.

If the generate_php_pdp_models script generates models which should be excluded (e.g. the model exposes RAP functionality), you can:

Discard all changes: git checkout -- . and remove all new files as well as any existing files you don't want.
Add the file path or wildcard to ignore to .openapi-generator-ignore
Re-run generate_php_pdp_models script
** Keep in mind this tooling does not remove files that are already committed. You have to do that manually. **

## Update composer.lock
After adding or updating php packages, you need to re-generate `composer.lock`.

```bash
docker compose run --rm --build composer-update
```


## Unit Tests & Linting
Build and run unit tests and linters:
```bash
docker compose run --rm --build unit-lint
```

## Fix (fixable) Style Issues Automatically
To automatically fix fixable style issues, run the format service. This will apply formatting fixes to all eligible files in the src/ folder:
```bash
docker compose run --rm --build format
```

## Usage

## ResourceGetter
ResourceGetter is an interface that provides a method for the PdpAuthorizationBackend to fetch the relevant attributes about a resource in your application.

## PdpAuthorizationBackend
The PdpAuthorizationBackend uses standard Permissions Platform conventions to check whether an identity is allowed to perform an action on a resource.
Instantiating the backend
```php
use PdpSdk\Backends\PdpAuthorizationBackend;
use PdpSdk\Connectors\OwsPdp\OwsPdpServiceClient;

$owsPdpClient = new OwsPdpServiceClient(
    new GuzzleClient(),
    $environment = 'qa',
    $sender = 'sender-service',
    $logger,
    $ssl = true
);

$backend = new PdpAuthorizationBackend(
    $owsPdpClient,
    $logger
);
```

## isAuthorized()
Checks whether the requester is authorized to perform an action on a given resource.
```php
$result = $backend->isAuthorized(
    action: 'view',
    resourceId: 123,
    resourceType: 'audience',
    resourceGetter: new MyResourceGetter(),
    raiseWhenUnauthorized: false,
    $arg1, $arg2 // passed directly to getAttributes(...)
);

echo $result ? "Authorized" : "Not authorized";
```

## getAuthorizedTenants()
Returns all tenants for which the requester is authorized to perform an action on a resource type.
```php
$tenants = $backend->getAuthorizedTenants(
    action: 'edit',
    resourceType: 'audience'
);
```

## isAuthorizedMany()
Used for dataloader/batch endpoints. Requires ready-made attributes via ResourceWithAttributes.


💥 When raise_when_unauthorized is True in the request parameters, an exception will be raised if there are any DENYs returned from PDP. If an exception is raised during the request, an UnauthorizedException will be raised from the SDK.

```php
use PdpSdk\Backends\Models\ResourceWithAttributes;

$resources = [
    new ResourceWithAttributes(
        resourceId: "123",
        attributes: [
            'tenant' => [
                'tenant_type' => 'audience',
                'tenant_uuid' => 'e055a30d-34de-450f-b1f2-1fa433ceb15a'
            ]
        ],
    ),
    new ResourceWithAttributes(
        resourceId: "456",
        attributes: [
            'tenant' => [
                'tenant_type' => 'audience',
                'tenant_uuid' => 'ec1fd7e2-9c95-4e09-a037-e924e0244283'
            ]
        ],
    ),
];

$response = $backend->isAuthorizedMany(
    action: 'view',
    resourceType: 'account',
    resourcesWithAttributes: $resources,
);
```
Alternatively, the default behavior (`raise_when_unauthorized` is `False`) is to return a list of the
authorization decisions. If an exception is raised, the default behavior is to return a 
`list of False booleans` the length of `resources_with_attributes`. The implication 
is that every individual authorization request is denied if there is an 
exception on the request itself.

| raise_when_unauthorized | Result from PDP         | Behavior in SDK  |
| --------                | -------                 | ------- |
| False (default)         | All ALLOWs              | List of True booleans |
| False (default)         | Some DENYs some ALLOWs  | List of True and False booleans |
| False (default)         | Exception               | List of all False booleans |
| True                    | All ALLOWs              | List of True booleans |
| True                    | Some DENYs some ALLOWs  | Unauthorized Exception |
| True                    | Exception               | Unauthorized Exception |

## isAuthorizedManyResourcesAndActions()
Use this when you must authorize multiple resources with different actions and/or resource types.

```php
use PdpSdk\Backends\Models\ResourceAction;

$resourceActions = [
    new ResourceAction(
        resourceId: '123',
        action: 'view',
        resourceType: 'account',
        attributes: [
            'tenant' => [
                'tenant_type' => 'account',
                'tenant_uuid' => 'e055a30d-34de-450f-b1f2-1fa433ceb15a'
            ]
        ]
    ),
    new ResourceAction(
        resourceId: '123',
        action: 'delete',
        resourceType: 'account',
        attributes: [
            'tenant' => [
                'tenant_type' => 'account',
                'tenant_uuid' => 'e055a30d-34de-450f-b1f2-1fa433ceb15a'
            ]
        ]
    ),
];

$response = $backend->isAuthorizedManyResourcesAndActions(
    resourceActions: $resourceActions
);
```
