Skip to content

Commit

Permalink
feat(task-processor): Add recurring task to clean password reset (#3153)
Browse files Browse the repository at this point in the history
  • Loading branch information
gagantrivedi committed Dec 20, 2023
1 parent 9178604 commit 6898253
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 51 deletions.
8 changes: 8 additions & 0 deletions api/custom_auth/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.apps import AppConfig


class CustomAuthAppConfig(AppConfig):
name = "custom_auth"

def ready(self) -> None:
from custom_auth import tasks # noqa F401
17 changes: 17 additions & 0 deletions api/custom_auth/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from datetime import timedelta

from django.conf import settings
from django.utils import timezone

from custom_auth.models import UserPasswordResetRequest
from task_processor.decorators import register_recurring_task


@register_recurring_task(
run_every=timedelta(seconds=settings.PASSWORD_RESET_EMAIL_COOLDOWN),
)
def clean_up_user_password_reset_request():
UserPasswordResetRequest.objects.filter(
requested_at__lt=timezone.now()
- timedelta(seconds=settings.PASSWORD_RESET_EMAIL_COOLDOWN)
).delete()
2 changes: 1 addition & 1 deletion api/scripts/run-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function run_task_processor() {
if [[ -n "$ANALYTICS_DATABASE_URL" || -n "$DJANGO_DB_NAME_ANALYTICS" ]]; then
python manage.py waitfordb --waitfor 30 --migrations --database analytics
fi
python manage.py runprocessor --sleepintervalms 500
RUN_BY_PROCESSOR=1 python manage.py runprocessor --sleepintervalms 500
}
function migrate_identities(){
python manage.py migrate_to_edge "$1"
Expand Down
23 changes: 0 additions & 23 deletions api/task_processor/management/commands/runprocessor.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import logging
import os
import signal
import time
import typing
from argparse import ArgumentParser
from datetime import timedelta
from importlib import reload

from django.core.management import BaseCommand
from django.utils import timezone

from sse import tasks as sse_tasks
from task_processor import tasks as processor_tasks
from task_processor.task_registry import registered_tasks
from task_processor.thread_monitoring import (
clear_unhealthy_threads,
Expand All @@ -21,30 +17,11 @@

logger = logging.getLogger(__name__)

TASKS_MODULES_TO_RELOAD = [processor_tasks, sse_tasks]


class Command(BaseCommand):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# The `register_recurring_task` decorator is executed in the global scope,
# meaning it will run whenever the code is executed, including when running
# `manage.py` commands such as `migrate` or `showmigrations`. However, this
# decorator saves the task to the database, which is not desired unless it is
# being run by processor, and to indicate the we set this `RUN_BY_PROCESSOR`
# environment variable.
os.environ["RUN_BY_PROCESSOR"] = "True"

# Since all the apps are loaded before the command is initialised,
# we need to reload some of those modules(that contains recurring tasks)
# to ensure the tasks are registered correctly
# e.g the tasks module is loaded by the ready method in TaskProcessorConfig
# which is run before the command is initialised

for module in TASKS_MODULES_TO_RELOAD:
reload(module)

signal.signal(signal.SIGINT, self._exit_gracefully)
signal.signal(signal.SIGTERM, self._exit_gracefully)

Expand Down
35 changes: 35 additions & 0 deletions api/tests/unit/custom_auth/test_tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from datetime import timedelta

from django.utils import timezone
from pytest_django.fixtures import SettingsWrapper

from custom_auth.models import UserPasswordResetRequest
from custom_auth.tasks import clean_up_user_password_reset_request
from users.models import FFAdminUser


def test_clean_up_user_password_reset_request(
settings: SettingsWrapper, test_user: FFAdminUser, freezer
):
# Given
settings.PASSWORD_RESET_EMAIL_COOLDOWN = 10
now = timezone.now()

# A user password reset request should be deleted
UserPasswordResetRequest.objects.create(user=test_user)

freezer.move_to(now + timedelta(seconds=11))

# A user password reset request should not be deleted
new_user_password_reset_request = UserPasswordResetRequest.objects.create(
user=test_user
)
# When
clean_up_user_password_reset_request()

# Then
assert UserPasswordResetRequest.objects.count() == 1
assert (
UserPasswordResetRequest.objects.first().id
== new_user_password_reset_request.id
)
27 changes: 0 additions & 27 deletions api/tests/unit/sse/test_tasks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import os
from datetime import datetime
from typing import Callable
from unittest import mock
from unittest.mock import call

import pytest
Expand All @@ -17,10 +15,6 @@
send_environment_update_message_for_project,
update_sse_usage,
)
from task_processor.management.commands.runprocessor import (
Command as RunProcessorCommand,
)
from task_processor.models import RecurringTask


def test_send_environment_update_message_for_project_make_correct_request(
Expand Down Expand Up @@ -144,24 +138,3 @@ def test_track_sse_usage(
bucket=influxdb_bucket,
record=mocked_influx_point().field().tag().tag().tag().time(),
)


@mock.patch.dict(os.environ, {})
@pytest.mark.django_db
def test_track_sse_usage_is_installed_correctly(
settings: SettingsWrapper,
):
# Given
settings.AWS_SSE_LOGS_BUCKET_NAME = "test_bucket"

# When
# Initialising the command should save the task to the database
RunProcessorCommand()

# Then
assert (
RecurringTask.objects.filter(
task_identifier=f"tasks.{update_sse_usage.__name__}"
).exists()
is True
)

3 comments on commit 6898253

@vercel
Copy link

@vercel vercel bot commented on 6898253 Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 6898253 Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 6898253 Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs – ./docs

docs.flagsmith.com
docs-flagsmith.vercel.app
docs.bullet-train.io
docs-git-main-flagsmith.vercel.app

Please sign in to comment.