Scoutr

Latest version: v2.1.1

Safety actively analyzes 627763 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 2 of 2

2.0.0

This is a major, major, major code refactor with **multiple breaking changes**. The codebase has been refactored to be much cleaner and more extensible for multiple NoSQL backend providers. It brings it up to the same level of support as the [Go version](https://github.com/MichaelPalmer1/scoutr-go).

New Features

- Added GCP Firestore (`FirestoreAPI`) and MongoDB (`MongoAPI`) support
- `sentry_sdk` is now mocked if the package is not installed
- For OIDC-focused deployments, the `Config` object accepts parameters to specify the name of the OIDC headers to pull user and group information from. Note that `MongoAPI` uses a `MongoConfig` class instead of the `Config` class.
- Ability to use [operators](https://geskunkworks.github.io/scoutr/reference/filtering/#supported-operators) on user filter fields (now rebranded as read filters)
- More granular filtering per action

Changes

- **BREAKING:** Primary key of the group table is changing (see below)
- **BREAKING:** Renamed and moved `scoutr.dynamo.DynamoAPI.value_in_list` to `scoutr.utils.value_in_set`. It now expects a `set` as input instead of a `list`
- **BREAKING:** `DynamoAPI` constructor expects a `Config` instance as input instead of a series of parameters
- **BREAKING:** Deleted `scoutr.dynamo.DynamoAPI`. It is replaced by `scoutr.providers.aws.DynamoAPI`.
- **BREAKING:** Moved `scoutr.api_gateway` to `scoutr.helpers.api_gateway`
- **BREAKING:** Moved `scoutr.flask` to `scoutr.helpers.flask`
- **BREAKING:** Renamed `filter_fields` to `read_filters`
- Modified how multiple filters targeting the same field are combined together (see below)

Group Table

- **BREAKING:** The primary key used in the groups table has been changed from `group_id` to `id` to remain consistent with the auth table. **This may require the underlying table to be recreated.**

Validation

- An additional argument `required_fields` is now available on `CREATE` operations. Validation will be performed using the `validation` object like before. If a field in the `validation` object does not exist in the request body, that validation is skipped
- Each validation function runs in a separate thread to improve performance

Error output

In the event of any validation failures on creates/updates, an error dictionary will be returned that maps the failed key to the error message:

json
{
"errors": {
"date": "Date must be formatted as YYYY-MM-DD",
"id": "Id is not valid",
"name": "Name is not valid"
}
}


If there is a single error otherwise, the response will be the same as before:

json
{
"error": "User is not authorized"
}


Filtering

- Added `create_filters`, `update_filters`, and `delete_filters` to allow for more granular filtering based on the action being performed by the user.

- `FilterField` objects now support an `operator` where you can specify a specific operation to perform. The supported operations are the same as the [operators](https://geskunkworks.github.io/scoutr/reference/filtering/#supported-operators) used in filtering (i.e. `eq`, `ne`, `in`, `not in`, etc.)

json
{
"field": "type",
"operator": "ne",
"value": "Test"
}


Filter Merging

The way that filters are merged together has changed. Now, for all filters that target the same `key`, those filters will be run together with an `OR` operation. Then, those filters will be combined with filters for other keys using an `AND` operation. For example:

jsonc
{
"read_filters": [
// Inherited from group1
{
"field": "product",
"operator": "contains",
"value": "ABC"
},
// Inherited from group2
{
"field": "product",
"operator": "ne",
"value": "ABCDEF"
},
// Inherited from group3
{
"field": "status",
"value": "Active"
}
]
}


Previously, this would have generated a query expression that would return no results because the two `product` filters would be conflicting:

sql
status = "Active" AND product CONTAINS "ABC" AND product != "ABCDEF"


However, using the new filter merging methodology, the generated query will be:

sql
status = "Active" AND (
product CONTAINS "ABC" OR product != "ABCDEF"
)


Granular Filtering

Create Filters

When performing a `CREATE` action, the filtering is applied as follows:

1. Ensure user has permission to set the fields they have included in the body. This checks against the values in `exclude_fields`. If any matches are found, an exception is thrown.
2. Run field validation
3. Run `create_filters`. If the filter criteria fails, the request will be denied with an Unauthorized error.

Update Filters

When performing an `UPDATE` action, the filtering is applied as follows:

1. Use the `update_filters` to determine if the user has permissions to access the item. If no item is found (i.e. it does not exist or user does not have permissions to access the item), then a Not Found error will be thrown.
2. Use `update_fields_permitted`, `update_fields_restricted`, and `exclude_fields` to determine if the user has permissions to update the fields they specified in the request body. If either of these criteria fail, an Unauthorized exception will be thrown
3. Run `update_filters` against the existing item merged together with the user’s desired updates. If the filter criteria fails, the request will be denied with an Unauthorized error.
4. Run field validation as before.

Example

User permissions:

json
{
"update_filters": [
{
"field": "product",
"operator": "eq",
"value": "a"
}
]
}


Record in the database:

json
{
"product": "a",
"approved": false
}


If a user tried to perform the below update:

json
{
"product": "b",
"approved": true
}


This update would be denied because the `update_filters` do not permit the user to modify the `product` key to any value that is not equal to “a”. However, this update would be permitted:

json
{
"approved": true,
"reason": "approved by user"
}


Similarly, if the user wanted to update the below record:

json
{
"product": "b",
"approved": false
}


This would be denied because they do not have permissions to update an item where the `product` key is not equal to “a”.

Delete Filters

When performing a `DELETE` action, the filtering is applied as follows:

1. Use the `delete_filters` to determine if the user has permissions to delete the item. If no item is found (i.e. it does not exist or the user does not have permissions to delete it), then the request will be denied with a Bad Request error.

1.2.2

- Fix a bug with creation filters on `create`

1.2.1

Add a `list_table_set` operation to list unique values that are in a set of values instead of a string.

1.2.0

Adds support for a `notin` operation for filtering and enables the usage of multi value query strings so users can perform multiple filters against a single column.

1.1.4

Page 2 of 2

© 2024 Safety CLI Cybersecurity Inc. All Rights Reserved.