-
-
Notifications
You must be signed in to change notification settings - Fork 527
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Commit WIP post reply code and new permissions
- Loading branch information
Showing
9 changed files
with
505 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
misago/permissions/hooks/check_post_in_closed_thread_permission.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
from typing import TYPE_CHECKING, Protocol | ||
|
||
from ...plugins.hooks import FilterHook | ||
from ...threads.models import Thread | ||
|
||
if TYPE_CHECKING: | ||
from ..proxy import UserPermissionsProxy | ||
|
||
|
||
class CheckPostInClosedThreadPermissionHookAction(Protocol): | ||
""" | ||
A standard Misago function used to check if the user has permission to | ||
post in a closed thread. It raises Django's `PermissionDenied` with an | ||
error message if thread is closed and they can't post in it. | ||
# Arguments | ||
## `user_permissions: UserPermissionsProxy` | ||
A proxy object with the current user's permissions. | ||
## `thread: Thread` | ||
A thread to check permissions for. | ||
""" | ||
|
||
def __call__( | ||
self, | ||
permissions: "UserPermissionsProxy", | ||
thread: Thread, | ||
) -> None: ... | ||
|
||
|
||
class CheckPostInClosedThreadPermissionHookFilter(Protocol): | ||
""" | ||
A function implemented by a plugin that can be registered in this hook. | ||
# Arguments | ||
## `action: CheckPostInClosedThreadPermissionHookAction` | ||
A standard Misago function used to check if the user has permission to | ||
post in a closed thread. It raises Django's `PermissionDenied` with an | ||
error message if thread is closed and they can't post in it. | ||
See the [action](#action) section for details. | ||
## `user_permissions: UserPermissionsProxy` | ||
A proxy object with the current user's permissions. | ||
## `thread: Thread` | ||
A thread to check permissions for. | ||
""" | ||
|
||
def __call__( | ||
self, | ||
action: CheckPostInClosedThreadPermissionHookAction, | ||
permissions: "UserPermissionsProxy", | ||
thread: Thread, | ||
) -> None: ... | ||
|
||
|
||
class CheckPostInClosedThreadPermissionHook( | ||
FilterHook[ | ||
CheckPostInClosedThreadPermissionHookAction, | ||
CheckPostInClosedThreadPermissionHookFilter, | ||
] | ||
): | ||
""" | ||
This hook wraps the standard function that Misago uses to check if the user | ||
has permission to post in a closed thread. It raises Django's `PermissionDenied` | ||
with an error message if thread is closed and they can't post in it. | ||
# Example | ||
The code below implements a custom filter function that permits a user to | ||
post in the specific thread if they have a custom flag set on their account. | ||
```python | ||
from misago.permissions.hooks import check_post_in_closed_thread_permission_hook | ||
from misago.permissions.proxy import UserPermissionsProxy | ||
from misago.threads.models import Thread | ||
@check_post_in_closed_thread_permission_hook.append_filter | ||
def check_user_can_post_in_closed_thread( | ||
action, | ||
permissions: UserPermissionsProxy, | ||
thread: Thread, | ||
) -> None: | ||
user = permissions.user | ||
if user.is_authenticated: | ||
post_in_closed_categories = ( | ||
user.plugin_data.get("post_in_closed_threads") or [] | ||
) | ||
else: | ||
post_in_closed_categories = None | ||
if ( | ||
not post_in_closed_categories | ||
or thread.id not in post_in_closed_categories | ||
): | ||
action(permissions, thread) | ||
``` | ||
""" | ||
|
||
__slots__ = FilterHook.__slots__ | ||
|
||
def __call__( | ||
self, | ||
action: CheckPostInClosedThreadPermissionHookAction, | ||
permissions: "UserPermissionsProxy", | ||
thread: Thread, | ||
) -> None: | ||
return super().__call__(action, permissions, thread) | ||
|
||
|
||
check_post_in_closed_thread_permission_hook = CheckPostInClosedThreadPermissionHook() |
130 changes: 130 additions & 0 deletions
130
misago/permissions/hooks/check_reply_thread_permission.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
from typing import TYPE_CHECKING, Protocol | ||
|
||
from ...categories.models import Category | ||
from ...plugins.hooks import FilterHook | ||
from ...threads.models import Thread | ||
|
||
if TYPE_CHECKING: | ||
from ..proxy import UserPermissionsProxy | ||
|
||
|
||
class CheckReplyThreadPermissionHookAction(Protocol): | ||
""" | ||
A standard Misago function used to check if the user has permission to | ||
reply to a thread. It raises Django's `PermissionDenied` with an | ||
error message if they can't reply to it. | ||
# Arguments | ||
## `user_permissions: UserPermissionsProxy` | ||
A proxy object with the current user's permissions. | ||
## `category: Category` | ||
A category to check permissions for. | ||
## `thread: Thread` | ||
A thread to check permissions for. | ||
""" | ||
|
||
def __call__( | ||
self, | ||
permissions: "UserPermissionsProxy", | ||
category: Category, | ||
thread: Thread, | ||
) -> None: ... | ||
|
||
|
||
class CheckReplyThreadPermissionHookFilter(Protocol): | ||
""" | ||
A function implemented by a plugin that can be registered in this hook. | ||
# Arguments | ||
## `action: CheckReplyThreadPermissionHookAction` | ||
A standard Misago function used to check if the user has permission to | ||
reply to a thread. It raises Django's `PermissionDenied` with an | ||
error message if they can't reply to it. | ||
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. | ||
## `thread: Thread` | ||
A thread to check permissions for. | ||
""" | ||
|
||
def __call__( | ||
self, | ||
action: CheckReplyThreadPermissionHookAction, | ||
permissions: "UserPermissionsProxy", | ||
category: Category, | ||
thread: Thread, | ||
) -> None: ... | ||
|
||
|
||
class CheckReplyThreadPermissionHook( | ||
FilterHook[ | ||
CheckReplyThreadPermissionHookAction, | ||
CheckReplyThreadPermissionHookFilter, | ||
] | ||
): | ||
""" | ||
This hook wraps the standard function that Misago uses to check if the user | ||
has permission to reply to a thread. It raises Django's `PermissionDenied` | ||
with an error message if they can't post in it. | ||
# Example | ||
The code below implements a custom filter function that prevents a user from | ||
replying to a thread if they are thread's starter, but only in categories | ||
with a plugin flag. | ||
```python | ||
from django.core.exceptions import PermissionDenied | ||
from misago.categories.models import Category | ||
from misago.permissions.hooks import check_reply_thread_permission_hook | ||
from misago.permissions.proxy import UserPermissionsProxy | ||
from misago.threads.models import Thread | ||
@check_reply_thread_permission_hook.append_filter | ||
def check_user_can_post_in_closed_thread( | ||
action, | ||
permissions: UserPermissionsProxy, | ||
category: Category, | ||
thread: Thread, | ||
) -> None: | ||
user = permissions.user | ||
if ( | ||
category.plugin_data.get("block_starters") | ||
and user.is_authenticated and user.id == thread.starter_id | ||
): | ||
raise PermissionDenied("You can't reply to threads you've started.") | ||
action(permissions, category, thread) | ||
``` | ||
""" | ||
|
||
__slots__ = FilterHook.__slots__ | ||
|
||
def __call__( | ||
self, | ||
action: CheckReplyThreadPermissionHookAction, | ||
permissions: "UserPermissionsProxy", | ||
category: Category, | ||
thread: Thread, | ||
) -> None: | ||
return super().__call__(action, permissions, category, thread) | ||
|
||
|
||
check_reply_thread_permission_hook = CheckReplyThreadPermissionHook() |
Oops, something went wrong.