Skip to content

Commit

Permalink
Add missing hooks to permission checks (#1773)
Browse files Browse the repository at this point in the history
* Add permission hook for checking private threads access

* Add hooks for see and browse category

* Add hook for private threads queryset filter and generate dev docs
  • Loading branch information
rafalp authored Jul 28, 2024
1 parent f4aaea5 commit a10734d
Show file tree
Hide file tree
Showing 21 changed files with 955 additions and 33 deletions.
112 changes: 112 additions & 0 deletions dev-docs/plugins/hooks/check-browse-category-permission-hook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# `check_browse_category_permission_hook`

This hook wraps the standard function that Misago uses to check if the user has permission to browse a category. It also checks if the user can see the category. It raises Django's `Http404` if they can't see it or `PermissionDenied` with an error message if they can't browse it.


## Location

This hook can be imported from `misago.permissions.hooks`:

```python
from misago.permissions.hooks import check_browse_category_permission_hook
```


## Filter

```python
def custom_check_browse_category_permission_filter(
action: CheckBrowseCategoryPermissionHookAction,
permissions: 'UserPermissionsProxy',
category: Category,
can_delay: bool=False,
) -> None:
...
```

A function implemented by a plugin that can be registered in this hook.


### Arguments

#### `action: CheckBrowseCategoryPermissionHookAction`

A standard Misago function used to check if the user has permission to browse a category. It also checks if the user can see the category. It raises Django's `Http404` if they can't see it or `PermissionDenied` with an error message if they can't browse it.

Browse the [action](#action) section for details.


#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


#### `can_delay: Bool = False`

A `bool` that specifies if this check can be delayed. If the category can be seen by the user but they have no permission to browse it, and both `can_delay` and `category.delay_browse_check` are `True`, a `PermissionDenied` error will not be raised.


## Action

```python
def check_browse_category_permission_action(
permissions: 'UserPermissionsProxy',
category: Category,
can_delay: bool=False,
) -> None:
...
```

A standard Misago function used to check if the user has permission to browse a category. It also checks if the user can see the category. It raises Django's `Http404` if they can't see it or `PermissionDenied` with an error message if they can't browse it.


### Arguments

#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


#### `can_delay: Bool = False`

A `bool` that specifies if this check can be delayed. If the category can be seen by the user but they have no permission to browse it, and both `can_delay` and `category.delay_browse_check` are `True`, a `PermissionDenied` error will not be raised.


## Example

The code below implements a custom filter function that blocks a user from browsing a specified category if there is a custom flag set on their account.

```python
from django.core.exceptions import PermissionDenied
from django.utils.translation import pgettext
from misago.categories.models import Category
from misago.permissions.hooks import check_browse_category_permission_hook
from misago.permissions.proxy import UserPermissionsProxy

@check_browse_category_permission_hook.append_filter
def check_user_can_browse_category(
action,
permissions: UserPermissionsProxy,
category: Category,
) -> None:
# Run standard permission checks
action(permissions, category)

if category.id in permissions.user.plugin_data.get("banned_categories", []):
raise PermissionDenied(
pgettext(
"category permission error",
"Site admin has removed your access to this category."
)
)
```
84 changes: 84 additions & 0 deletions dev-docs/plugins/hooks/check-private-threads-permission-hook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# `check_private_threads_permission_hook`

This hook wraps the standard function that Misago uses to check if the user has a permission to access private threads feature. Raises Django's `PermissionDenied` with an error message if they don't.


## Location

This hook can be imported from `misago.permissions.hooks`:

```python
from misago.permissions.hooks import check_private_threads_permission_hook
```


## Filter

```python
def custom_check_private_threads_permission_filter(
action: CheckPrivateThreadsPermissionHookAction,
permissions: 'UserPermissionsProxy',
) -> None:
...
```

A function implemented by a plugin that can be registered in this hook.


### Arguments

#### `action: CheckPrivateThreadsPermissionHookAction`

A standard Misago function used to check if the user has a permission to access private threads feature. Raises Django's `PermissionDenied` with an error message if they don't.

See the [action](#action) section for details.


#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


## Action

```python
def check_private_threads_permission_action(permissions: 'UserPermissionsProxy') -> None:
...
```

A standard Misago function used to check if the user has a permission to access private threads feature. Raises Django's `PermissionDenied` with an error message if they don't.


### Arguments

#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


## Example

The code below implements a custom filter function that blocks user from using private threads if there's a custom flag set on their account.

```python
from django.core.exceptions import PermissionDenied
from django.utils.translation import pgettext
from misago.permissions.hooks import check_private_threads_permission_hook
from misago.permissions.proxy import UserPermissionsProxy

@check_private_threads_permission_hook.append_filter
def check_user_is_banned_from_private_threads(
action,
permissions: UserPermissionsProxy,
) -> None:
# Run standard permission checks
action(permissions)

if permissions.user.plugin_data.get("ban_private_threads"):
raise PermissionDenied(
pgettext(
"private threads permission error",
"Site admin has removed your access to private threads."
)
)
```
99 changes: 99 additions & 0 deletions dev-docs/plugins/hooks/check-see-category-permission-hook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# `check_see_category_permission_hook`

This hook wraps the standard function that Misago uses to check if the user has a permission to see a category. Raises Django's `Http404` error if they don't.


## Location

This hook can be imported from `misago.permissions.hooks`:

```python
from misago.permissions.hooks import check_see_category_permission_hook
```


## Filter

```python
def custom_check_see_category_permission_filter(
action: CheckSeeCategoryPermissionHookAction,
permissions: 'UserPermissionsProxy',
category: Category,
) -> None:
...
```

A function implemented by a plugin that can be registered in this hook.


### Arguments

#### `action: CheckSeeCategoryPermissionHookAction`

A standard Misago function used to check if the user has a permission to see a category. Raises Django's `Http404` error if they don't.

See the [action](#action) section for details.


#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


## Action

```python
def check_see_category_permission_action(
permissions: 'UserPermissionsProxy', category: Category
) -> None:
...
```

A standard Misago function used to check if the user has a permission to see a category. Raises Django's `Http404` error if they don't.


### Arguments

#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


## Example

The code below implements a custom filter function that blocks a user from seeing a specified category if there is a custom flag set on their account.

```python
from django.core.exceptions import PermissionDenied
from django.utils.translation import pgettext
from misago.categories.models import Category
from misago.permissions.hooks import check_see_category_permission_hook
from misago.permissions.proxy import UserPermissionsProxy

@check_see_category_permission_hook.append_filter
def check_user_can_see_category(
action,
permissions: UserPermissionsProxy,
category: Category,
) -> None:
# Run standard permission checks
action(permissions, category)

if category.id in permissions.user.plugin_data.get("banned_categories", []):
raise PermissionDenied(
pgettext(
"category permission error",
"Site admin has removed your access to this category."
)
)
```
Loading

0 comments on commit a10734d

Please sign in to comment.