signups: Move logic for realm admin notification to corporate app.

As we would like to send similar notifications for other billing
state changes (for all BillingSession types), it makes sense to
move the logic for creating and sending these admin realm internal
messages to the BillingSession framework in the corporate app.

In the case that a channel with the specified name does not exist,
we now send direct messages to the admin realm administrators with
the channel, topic and message so that the information is not lost
and so that the channel for these messages can be created.
This commit is contained in:
Lauryn Menard 2024-11-04 19:00:48 +01:00 committed by Tim Abbott
parent 9a40319bfc
commit 3ebc507ddb
3 changed files with 41 additions and 40 deletions

View File

@ -54,9 +54,10 @@ from zerver.lib.send_email import (
from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime
from zerver.lib.url_encoding import append_url_query_string from zerver.lib.url_encoding import append_url_query_string
from zerver.lib.utils import assert_is_not_none from zerver.lib.utils import assert_is_not_none
from zerver.models import Realm, RealmAuditLog, UserProfile from zerver.models import Realm, RealmAuditLog, Stream, UserProfile
from zerver.models.realm_audit_logs import AuditLogEventType from zerver.models.realm_audit_logs import AuditLogEventType
from zerver.models.realms import get_org_type_display_name, get_realm from zerver.models.realms import get_org_type_display_name, get_realm
from zerver.models.streams import get_stream
from zerver.models.users import get_system_bot from zerver.models.users import get_system_bot
from zilencer.lib.remote_counts import MissingDataError from zilencer.lib.remote_counts import MissingDataError
from zilencer.models import ( from zilencer.models import (
@ -3843,6 +3844,31 @@ class BillingSession(ABC):
return last_ledger return last_ledger
def send_support_admin_realm_internal_message(
self, channel_name: str, topic: str, message: str
) -> None:
from zerver.actions.message_send import (
internal_send_private_message,
internal_send_stream_message,
)
admin_realm = get_realm(settings.SYSTEM_BOT_REALM)
sender = get_system_bot(settings.NOTIFICATION_BOT, admin_realm.id)
try:
channel = get_stream(channel_name, admin_realm)
internal_send_stream_message(
sender,
channel,
topic,
message,
)
except Stream.DoesNotExist: # nocoverage
direct_message = (
f":red_circle: Channel named '{channel_name}' doesn't exist.\n\n{topic}:\n{message}"
)
for user in admin_realm.get_human_admin_users():
internal_send_private_message(sender, user, direct_message)
class RealmBillingSession(BillingSession): class RealmBillingSession(BillingSession):
def __init__( def __init__(
@ -4212,6 +4238,14 @@ class RealmBillingSession(BillingSession):
# anything weird. # anything weird.
pass pass
def send_realm_created_internal_admin_message(self) -> None:
channel = "signups"
topic = "new organizations"
support_url = self.support_url()
organization_type = get_org_type_display_name(self.realm.org_type)
message = f"[{self.realm.name}]({support_url}) ([{self.realm.display_subdomain}]({self.realm.url})). Organization type: {organization_type}"
self.send_support_admin_realm_internal_message(channel, topic, message)
class RemoteRealmBillingSession(BillingSession): class RemoteRealmBillingSession(BillingSession):
def __init__( def __init__(

View File

@ -9,7 +9,6 @@ from django.utils.translation import gettext as _
from django.utils.translation import override as override_language from django.utils.translation import override as override_language
from confirmation import settings as confirmation_settings from confirmation import settings as confirmation_settings
from zerver.actions.message_send import internal_send_stream_message
from zerver.actions.realm_settings import ( from zerver.actions.realm_settings import (
do_add_deactivated_redirect, do_add_deactivated_redirect,
do_change_realm_plan_type, do_change_realm_plan_type,
@ -19,7 +18,7 @@ from zerver.lib.bulk_create import create_users
from zerver.lib.push_notifications import sends_notifications_directly from zerver.lib.push_notifications import sends_notifications_directly
from zerver.lib.remote_server import maybe_enqueue_audit_log_upload from zerver.lib.remote_server import maybe_enqueue_audit_log_upload
from zerver.lib.server_initialization import create_internal_realm, server_initialized from zerver.lib.server_initialization import create_internal_realm, server_initialized
from zerver.lib.streams import ensure_stream, get_signups_stream from zerver.lib.streams import ensure_stream
from zerver.lib.user_groups import ( from zerver.lib.user_groups import (
create_system_user_groups_for_realm, create_system_user_groups_for_realm,
get_role_based_system_groups_dict, get_role_based_system_groups_dict,
@ -32,19 +31,12 @@ from zerver.models import (
RealmAuditLog, RealmAuditLog,
RealmAuthenticationMethod, RealmAuthenticationMethod,
RealmUserDefault, RealmUserDefault,
Stream,
UserProfile, UserProfile,
) )
from zerver.models.groups import SystemGroups from zerver.models.groups import SystemGroups
from zerver.models.presence import PresenceSequence from zerver.models.presence import PresenceSequence
from zerver.models.realm_audit_logs import AuditLogEventType from zerver.models.realm_audit_logs import AuditLogEventType
from zerver.models.realms import ( from zerver.models.realms import CommonPolicyEnum, InviteToRealmPolicyEnum
CommonPolicyEnum,
InviteToRealmPolicyEnum,
get_org_type_display_name,
get_realm,
)
from zerver.models.users import get_system_bot
from zproject.backends import all_default_backend_names from zproject.backends import all_default_backend_names
@ -369,32 +361,12 @@ def do_create_realm(
prereg_realm.created_realm = realm prereg_realm.created_realm = realm
prereg_realm.save(update_fields=["status", "created_realm"]) prereg_realm.save(update_fields=["status", "created_realm"])
# Send a notification to the admin realm when a new organization registers.
if settings.CORPORATE_ENABLED: if settings.CORPORATE_ENABLED:
from corporate.lib.support import get_realm_support_url # Send a notification to the admin realm when a new organization registers.
from corporate.lib.stripe import RealmBillingSession
admin_realm = get_realm(settings.SYSTEM_BOT_REALM) billing_session = RealmBillingSession(user=None, realm=realm)
sender = get_system_bot(settings.NOTIFICATION_BOT, admin_realm.id) billing_session.send_realm_created_internal_admin_message()
support_url = get_realm_support_url(realm)
organization_type = get_org_type_display_name(realm.org_type)
message = f"[{realm.name}]({support_url}) ([{realm.display_subdomain}]({realm.url})). Organization type: {organization_type}"
topic_name = "new organizations"
try:
signups_stream = get_signups_stream(admin_realm)
internal_send_stream_message(
sender,
signups_stream,
topic_name,
message,
)
except Stream.DoesNotExist: # nocoverage
# If the signups stream hasn't been created in the admin
# realm, don't auto-create it to send to it; just do nothing.
pass
setup_realm_internal_bots(realm) setup_realm_internal_bots(realm)
return realm return realm

View File

@ -835,11 +835,6 @@ def get_stream_by_narrow_operand_access_unchecked(operand: str | int, realm: Rea
return get_stream_by_id_in_realm(operand, realm) return get_stream_by_id_in_realm(operand, realm)
def get_signups_stream(realm: Realm) -> Stream:
# This one-liner helps us work around a lint rule.
return get_stream("signups", realm)
def ensure_stream( def ensure_stream(
realm: Realm, realm: Realm,
stream_name: str, stream_name: str,