Skip to content

Commit

Permalink
global: make moderation locking configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
slint committed Dec 12, 2024
1 parent 08589f9 commit 1a5ca73
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 6 deletions.
4 changes: 3 additions & 1 deletion invenio_users_resources/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,15 @@
USERS_RESOURCES_ADMINISTRATION_ENABLED = True
"""Enable the user administration"""

USERS_RESOURCES_USE_MODERATION_LOCK = True
"""Enable or disable using a per-user lock for moderation actions."""

USERS_RESOURCES_MODERATION_LOCK_DEFAULT_TIMEOUT = 30
"""Default timeout, in seconds, to lock a user when moderating."""

USERS_RESOURCES_MODERATION_LOCK_RENEWAL_TIMEOUT = 120
"""Renewal timeout, in seconds, to increase the lock time for a user when moderating."""


USERS_RESOURCES_DOMAINS_SEARCH = {
"sort": [
"bestmatch",
Expand Down
3 changes: 3 additions & 0 deletions invenio_users_resources/services/users/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ class UsersServiceConfig(RecordServiceConfig, ConfiguratorMixin):
# leaking account information.
search = UserSearchOptions

# Moderation lock
use_moderation_lock = FromConfig("USERS_RESOURCES_USE_MODERATION_LOCK", True)

# For admin user
search_all = FromConfigSearchOptions(
"USERS_RESOURCES_SEARCH",
Expand Down
14 changes: 11 additions & 3 deletions invenio_users_resources/services/users/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ def block(self, identity, id_, uow=None):
raise ValidationError("User is already blocked.")

# Throws if not acquired
ModerationMutex(id_).acquire()
self._acquire_moderation_lock(id_)

user.block()
uow.register(RecordCommitOp(user, indexer=self.indexer, index_refresh=True))

Expand All @@ -167,7 +168,8 @@ def restore(self, identity, id_, uow=None):
raise ValidationError("User is not blocked.")

# Throws if not acquired
ModerationMutex(id_).acquire()
self._acquire_moderation_lock(id_)

user.activate()
# User is blocked from now on, "after" actions are executed separately.
uow.register(RecordCommitOp(user, indexer=self.indexer, index_refresh=True))
Expand All @@ -178,6 +180,11 @@ def restore(self, identity, id_, uow=None):
)
return True

def _acquire_moderation_lock(self, user_id):
"""Acquire the moderation lock for a specific user."""
if self.config.use_moderation_lock:
ModerationMutex(user_id).acquire()

@unit_of_work()
def approve(self, identity, id_, uow=None):
"""Approves a user."""
Expand All @@ -192,7 +199,8 @@ def approve(self, identity, id_, uow=None):
raise ValidationError("User is already verified.")

# Throws if not acquired
ModerationMutex(id_).acquire()
self._acquire_moderation_lock(id_)

user.verify()
uow.register(RecordCommitOp(user, indexer=self.indexer, index_refresh=True))

Expand Down
8 changes: 6 additions & 2 deletions invenio_users_resources/services/users/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

"""Users service tasks."""

from contextlib import ExitStack

from celery import shared_task
from flask import current_app
from invenio_records_resources.services.uow import UnitOfWork
Expand Down Expand Up @@ -78,8 +80,10 @@ def execute_moderation_actions(user_id=None, action=None):
"""
actions = current_actions_registry.get(action, [])

with ModerationMutex(user_id) as lock:
lock.acquire_or_renew(renewal_timeout)
with ExitStack() as stack:
if current_users_service.config.use_moderation_lock:
lock = stack.enter_context(ModerationMutex(user_id))
lock.acquire_or_renew(renewal_timeout)

# Create a uow that is shared by all the callables
uow = UnitOfWork()
Expand Down

0 comments on commit 1a5ca73

Please sign in to comment.