mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 14:03:30 +00:00
worker: Remove SignupWorker and friends.
ZULIP_FRIENDS_LIST_ID and MAILCHIMP_API_KEY are not currently used in production. This removes the unused 'signups' queue and worker.
This commit is contained in:
committed by
Tim Abbott
parent
01658e39a9
commit
c2526844e9
@@ -77,7 +77,6 @@ class zulip::app_frontend_base {
|
|||||||
'missedmessage_emails',
|
'missedmessage_emails',
|
||||||
'missedmessage_mobile_notifications',
|
'missedmessage_mobile_notifications',
|
||||||
'outgoing_webhooks',
|
'outgoing_webhooks',
|
||||||
'signups',
|
|
||||||
'user_activity',
|
'user_activity',
|
||||||
'user_activity_interval',
|
'user_activity_interval',
|
||||||
'user_presence',
|
'user_presence',
|
||||||
|
|||||||
@@ -349,17 +349,6 @@ define service {
|
|||||||
contact_groups admins
|
contact_groups admins
|
||||||
}
|
}
|
||||||
|
|
||||||
define service {
|
|
||||||
use generic-service
|
|
||||||
service_description Check RabbitMQ signups consumers
|
|
||||||
check_command check_rabbitmq_consumers!signups
|
|
||||||
# Workaround weird checks 40s after first error causing alerts
|
|
||||||
# from a single failure because cron hasn't run again yet
|
|
||||||
max_check_attempts 3
|
|
||||||
hostgroup_name frontends
|
|
||||||
contact_groups admins
|
|
||||||
}
|
|
||||||
|
|
||||||
define service {
|
define service {
|
||||||
use generic-service
|
use generic-service
|
||||||
service_description Check RabbitMQ digest email consumers
|
service_description Check RabbitMQ digest email consumers
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ normal_queues = [
|
|||||||
'missedmessage_emails',
|
'missedmessage_emails',
|
||||||
'missedmessage_mobile_notifications',
|
'missedmessage_mobile_notifications',
|
||||||
'outgoing_webhooks',
|
'outgoing_webhooks',
|
||||||
'signups',
|
|
||||||
'user_activity',
|
'user_activity',
|
||||||
'user_activity_interval',
|
'user_activity_interval',
|
||||||
'user_presence',
|
'user_presence',
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
import argparse
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Any, Optional
|
|
||||||
|
|
||||||
import orjson
|
|
||||||
import requests
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
|
||||||
from django.utils.timezone import now as timezone_now
|
|
||||||
|
|
||||||
from zerver.models import UserProfile
|
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
|
||||||
help = """Add users to a MailChimp mailing list."""
|
|
||||||
|
|
||||||
def add_arguments(self, parser: argparse.ArgumentParser) -> None:
|
|
||||||
parser.add_argument('--api-key',
|
|
||||||
help='MailChimp API key.')
|
|
||||||
parser.add_argument('--list-id',
|
|
||||||
help='List ID of the MailChimp mailing list.')
|
|
||||||
parser.add_argument('--optin-time',
|
|
||||||
default=datetime.isoformat(timezone_now().replace(microsecond=0)),
|
|
||||||
help='Opt-in time of the users.')
|
|
||||||
|
|
||||||
def handle(self, *args: Any, **options: Optional[str]) -> None:
|
|
||||||
api_key = options['api_key']
|
|
||||||
if api_key is None:
|
|
||||||
try:
|
|
||||||
if settings.MAILCHIMP_API_KEY is None:
|
|
||||||
raise CommandError('MAILCHIMP_API_KEY is None. Check your server settings file.')
|
|
||||||
api_key = settings.MAILCHIMP_API_KEY
|
|
||||||
except AttributeError:
|
|
||||||
raise CommandError('Please supply a MailChimp API key to --api-key, or add a '
|
|
||||||
'MAILCHIMP_API_KEY to your server settings file.')
|
|
||||||
|
|
||||||
if options['list_id'] is None:
|
|
||||||
try:
|
|
||||||
if settings.ZULIP_FRIENDS_LIST_ID is None:
|
|
||||||
raise CommandError('ZULIP_FRIENDS_LIST_ID is None. Check your server settings file.')
|
|
||||||
options['list_id'] = settings.ZULIP_FRIENDS_LIST_ID
|
|
||||||
except AttributeError:
|
|
||||||
raise CommandError('Please supply a MailChimp List ID to --list-id, or add a '
|
|
||||||
'ZULIP_FRIENDS_LIST_ID to your server settings file.')
|
|
||||||
|
|
||||||
endpoint = "https://{}.api.mailchimp.com/3.0/lists/{}/members".format(
|
|
||||||
api_key.split('-')[1], options['list_id'],
|
|
||||||
)
|
|
||||||
|
|
||||||
for user in UserProfile.objects.filter(is_bot=False, is_active=True) \
|
|
||||||
.values('email', 'full_name', 'realm_id'):
|
|
||||||
data = {
|
|
||||||
'email_address': user['email'],
|
|
||||||
'list_id': options['list_id'],
|
|
||||||
'status': 'subscribed',
|
|
||||||
'merge_fields': {
|
|
||||||
'NAME': user['full_name'],
|
|
||||||
'REALM_ID': user['realm_id'],
|
|
||||||
'OPTIN_TIME': options['optin_time'],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
r = requests.post(endpoint, auth=('apikey', api_key), json=data, timeout=10)
|
|
||||||
if r.status_code == 400 and orjson.loads(r.content)['title'] == 'Member Exists':
|
|
||||||
print("{} is already a part of the list.".format(data['email_address']))
|
|
||||||
elif r.status_code >= 400:
|
|
||||||
print(r.text)
|
|
||||||
@@ -402,91 +402,6 @@ class WorkerTest(ZulipTestCase):
|
|||||||
|
|
||||||
self.assertEqual(data['failed_tries'], 1 + MAX_REQUEST_RETRIES)
|
self.assertEqual(data['failed_tries'], 1 + MAX_REQUEST_RETRIES)
|
||||||
|
|
||||||
def test_signups_worker_retries(self) -> None:
|
|
||||||
"""Tests the retry logic of signups queue."""
|
|
||||||
fake_client = self.FakeClient()
|
|
||||||
|
|
||||||
user_id = self.example_user('hamlet').id
|
|
||||||
data = {'user_id': user_id, 'id': 'test_missed'}
|
|
||||||
fake_client.enqueue('signups', data)
|
|
||||||
|
|
||||||
def fake_publish(queue_name: str, event: Dict[str, Any], processor: Optional[Callable[[Any], None]]) -> None:
|
|
||||||
fake_client.enqueue(queue_name, event)
|
|
||||||
|
|
||||||
fake_response = MagicMock()
|
|
||||||
fake_response.status_code = 400
|
|
||||||
fake_response.content = orjson.dumps({'title': ''})
|
|
||||||
with simulated_queue_client(lambda: fake_client):
|
|
||||||
worker = queue_processors.SignupWorker()
|
|
||||||
worker.setup()
|
|
||||||
with patch('zerver.worker.queue_processors.requests.post',
|
|
||||||
return_value=fake_response), \
|
|
||||||
mock_queue_publish('zerver.lib.queue.queue_json_publish',
|
|
||||||
side_effect=fake_publish), \
|
|
||||||
patch('logging.info'), \
|
|
||||||
self.settings(MAILCHIMP_API_KEY='one-two',
|
|
||||||
PRODUCTION=True,
|
|
||||||
ZULIP_FRIENDS_LIST_ID='id'):
|
|
||||||
worker.start()
|
|
||||||
|
|
||||||
self.assertEqual(data['failed_tries'], 1 + MAX_REQUEST_RETRIES)
|
|
||||||
|
|
||||||
def test_signups_worker_existing_member(self) -> None:
|
|
||||||
fake_client = self.FakeClient()
|
|
||||||
|
|
||||||
user_id = self.example_user('hamlet').id
|
|
||||||
data = {'user_id': user_id,
|
|
||||||
'id': 'test_missed',
|
|
||||||
'email_address': 'foo@bar.baz'}
|
|
||||||
fake_client.enqueue('signups', data)
|
|
||||||
|
|
||||||
fake_response = MagicMock()
|
|
||||||
fake_response.status_code = 400
|
|
||||||
fake_response.content = orjson.dumps({'title': 'Member Exists'})
|
|
||||||
with simulated_queue_client(lambda: fake_client):
|
|
||||||
worker = queue_processors.SignupWorker()
|
|
||||||
worker.setup()
|
|
||||||
with patch('zerver.worker.queue_processors.requests.post',
|
|
||||||
return_value=fake_response), \
|
|
||||||
self.settings(MAILCHIMP_API_KEY='one-two',
|
|
||||||
PRODUCTION=True,
|
|
||||||
ZULIP_FRIENDS_LIST_ID='id'), \
|
|
||||||
self.assertLogs(level='INFO') as info_logs:
|
|
||||||
with patch('logging.warning') as logging_warning_mock:
|
|
||||||
worker.start()
|
|
||||||
logging_warning_mock.assert_called_once_with(
|
|
||||||
"Attempted to sign up already existing email to list: %s",
|
|
||||||
"foo@bar.baz",
|
|
||||||
)
|
|
||||||
self.assertEqual(info_logs.output, [
|
|
||||||
'INFO:root:Processing signup for user 10 in realm zulip'
|
|
||||||
])
|
|
||||||
|
|
||||||
def test_signups_bad_request(self) -> None:
|
|
||||||
fake_client = self.FakeClient()
|
|
||||||
|
|
||||||
user_id = self.example_user('hamlet').id
|
|
||||||
data = {'user_id': user_id, 'id': 'test_missed'}
|
|
||||||
fake_client.enqueue('signups', data)
|
|
||||||
|
|
||||||
fake_response = MagicMock()
|
|
||||||
fake_response.status_code = 444 # Any non-400 bad request code.
|
|
||||||
fake_response.content = orjson.dumps({'title': 'Member Exists'})
|
|
||||||
with simulated_queue_client(lambda: fake_client):
|
|
||||||
worker = queue_processors.SignupWorker()
|
|
||||||
worker.setup()
|
|
||||||
with patch('zerver.worker.queue_processors.requests.post',
|
|
||||||
return_value=fake_response), \
|
|
||||||
self.settings(MAILCHIMP_API_KEY='one-two',
|
|
||||||
PRODUCTION=True,
|
|
||||||
ZULIP_FRIENDS_LIST_ID='id'), \
|
|
||||||
self.assertLogs(level='INFO') as info_logs:
|
|
||||||
worker.start()
|
|
||||||
fake_response.raise_for_status.assert_called_once()
|
|
||||||
self.assertEqual(info_logs.output, [
|
|
||||||
'INFO:root:Processing signup for user 10 in realm zulip'
|
|
||||||
])
|
|
||||||
|
|
||||||
def test_invites_worker(self) -> None:
|
def test_invites_worker(self) -> None:
|
||||||
fake_client = self.FakeClient()
|
fake_client = self.FakeClient()
|
||||||
inviter = self.example_user('iago')
|
inviter = self.example_user('iago')
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ from typing import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
import orjson
|
import orjson
|
||||||
import requests
|
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
@@ -370,32 +369,6 @@ class LoopQueueProcessingWorker(QueueProcessingWorker):
|
|||||||
"""In LoopQueueProcessingWorker, consume is used just for automated tests"""
|
"""In LoopQueueProcessingWorker, consume is used just for automated tests"""
|
||||||
self.consume_batch([event])
|
self.consume_batch([event])
|
||||||
|
|
||||||
@assign_queue('signups')
|
|
||||||
class SignupWorker(QueueProcessingWorker):
|
|
||||||
def consume(self, data: Dict[str, Any]) -> None:
|
|
||||||
# TODO: This is the only implementation with Dict cf Mapping; should we simplify?
|
|
||||||
user_profile = get_user_profile_by_id(data['user_id'])
|
|
||||||
logging.info(
|
|
||||||
"Processing signup for user %s in realm %s",
|
|
||||||
user_profile.id, user_profile.realm.string_id,
|
|
||||||
)
|
|
||||||
if settings.MAILCHIMP_API_KEY and settings.PRODUCTION:
|
|
||||||
endpoint = "https://{}.api.mailchimp.com/3.0/lists/{}/members".format(
|
|
||||||
settings.MAILCHIMP_API_KEY.split('-')[1], settings.ZULIP_FRIENDS_LIST_ID,
|
|
||||||
)
|
|
||||||
params = dict(data)
|
|
||||||
del params['user_id']
|
|
||||||
params['list_id'] = settings.ZULIP_FRIENDS_LIST_ID
|
|
||||||
params['status'] = 'subscribed'
|
|
||||||
r = requests.post(endpoint, auth=('apikey', settings.MAILCHIMP_API_KEY), json=params, timeout=10)
|
|
||||||
if r.status_code == 400 and orjson.loads(r.content)['title'] == 'Member Exists':
|
|
||||||
logging.warning("Attempted to sign up already existing email to list: %s",
|
|
||||||
data['email_address'])
|
|
||||||
elif r.status_code == 400:
|
|
||||||
retry_event(self.queue_name, data, lambda e: r.raise_for_status())
|
|
||||||
else:
|
|
||||||
r.raise_for_status()
|
|
||||||
|
|
||||||
@assign_queue('invites')
|
@assign_queue('invites')
|
||||||
class ConfirmationEmailWorker(QueueProcessingWorker):
|
class ConfirmationEmailWorker(QueueProcessingWorker):
|
||||||
def consume(self, data: Mapping[str, Any]) -> None:
|
def consume(self, data: Mapping[str, Any]) -> None:
|
||||||
|
|||||||
@@ -448,8 +448,6 @@ DROPBOX_APP_KEY = get_secret("dropbox_app_key")
|
|||||||
|
|
||||||
BIG_BLUE_BUTTON_SECRET = get_secret('big_blue_button_secret')
|
BIG_BLUE_BUTTON_SECRET = get_secret('big_blue_button_secret')
|
||||||
|
|
||||||
MAILCHIMP_API_KEY = get_secret("mailchimp_api_key")
|
|
||||||
|
|
||||||
# Twitter API credentials
|
# Twitter API credentials
|
||||||
# Secrecy not required because its only used for R/O requests.
|
# Secrecy not required because its only used for R/O requests.
|
||||||
# Please don't make us go over our rate limit.
|
# Please don't make us go over our rate limit.
|
||||||
|
|||||||
Reference in New Issue
Block a user