remote_billing_page: Deny login for server / remote realm.

If server has plan, deny login for realm.
If realm has plan, deny login for server.

Co-authored-by: Aman Agrawal <amanagr@zulip.com>
Co-authored-by: Alya Abbott <alya@zulip.com>
This commit is contained in:
Alya Abbott 2023-12-14 14:25:12 -08:00 committed by GitHub
parent 8965f011fb
commit ba80084ea7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 113 additions and 0 deletions

View File

@ -5,6 +5,7 @@ from urllib.parse import urlsplit, urlunsplit
from django.conf import settings
from django.core import signing
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Exists, OuterRef
from django.http import HttpRequest, HttpResponse, HttpResponseNotAllowed, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
@ -35,6 +36,11 @@ from corporate.lib.stripe import (
RemoteRealmBillingSession,
RemoteServerBillingSession,
)
from corporate.models import (
CustomerPlan,
get_current_plan_by_customer,
get_customer_by_remote_server,
)
from zerver.lib.exceptions import (
JsonableError,
MissingRemoteRealmError,
@ -190,6 +196,19 @@ def remote_realm_billing_finalize_login(
# pretty recently. (And we generally don't delete these at all.)
raise AssertionError
# Redirect to error page if server is on an active plan
server_customer = get_customer_by_remote_server(remote_server)
if server_customer is not None:
server_plan = get_current_plan_by_customer(server_customer)
if server_plan is not None:
return render(
request,
"corporate/remote_realm_login_error_for_server_on_active_plan.html",
context={
"server_plan_name": server_plan.name,
},
)
user_dict = identity_dict["user"]
user_email = user_dict["user_email"]
@ -592,6 +611,21 @@ def remote_billing_legacy_server_confirm_login(
)
def has_live_plan_for_any_remote_realm_on_server(server: RemoteZulipServer) -> bool:
has_plan_with_status_lt_live_threshold = CustomerPlan.objects.filter(
customer__remote_realm__server=server,
status__lt=CustomerPlan.LIVE_STATUS_THRESHOLD,
customer__remote_realm=OuterRef("pk"),
)
return (
RemoteRealm.objects.filter(server=server)
.annotate(has_plan=Exists(has_plan_with_status_lt_live_threshold))
.filter(has_plan=True)
.exists()
)
@self_hosting_management_endpoint
@typed_endpoint
def remote_billing_legacy_server_from_login_confirmation_link(
@ -658,6 +692,12 @@ def remote_billing_legacy_server_from_login_confirmation_link(
# don't need a pretty error.
raise JsonableError(_("You must accept the Terms of Service to proceed."))
if has_live_plan_for_any_remote_realm_on_server(remote_server):
return render(
request,
"corporate/remote_server_login_error_for_any_realm_on_active_plan.html",
)
if remote_billing_user is None:
assert full_name is not None
assert settings.TERMS_OF_SERVICE_VERSION is not None

View File

@ -0,0 +1,39 @@
{% extends "zerver/portico.html" %}
{% block title %}
<title>{{ _("Plan management not available") }} | Zulip</title>
{% endblock %}
{% block portico_class_name %}error{% endblock %}
{% block portico_content %}
<div class="error_page">
<div class="container">
<div class="row-fluid">
<img src="{{ static('images/errors/400art.svg') }}" alt=""/>
<div class="errorbox">
<div class="errorcontent">
<h1 class="lead">{{ _("Plan management not available") }}</h1>
<p>
{% trans %} Plan management is not available for this
organization, because your Zulip server is already on a
{{ server_plan_name }} plan, which covers all
organizations on this server. Follow the <a
href="https://zulip.com/help/self-hosted-billing#manage-billing">log
in instructions</a>
for <b>All older versions</b>
of the Zulip server to manage your plan.
{% endtrans %}
</p>
<p>
{% trans %} To move the plan from the server to this
organization, or for other questions, <a href="mailto:{{
support_email }}">contact support</a>.
{% endtrans %}
</p>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,34 @@
{% extends "zerver/portico.html" %}
{% block title %}
<title>{{ _("Plan management not available") }} | Zulip</title>
{% endblock %}
{% block portico_class_name %}error{% endblock %}
{% block portico_content %}
<div class="error_page">
<div class="container">
<div class="row-fluid">
<img src="{{ static('images/errors/400art.svg') }}" alt=""/>
<div class="errorbox">
<div class="errorcontent">
<h1 class="lead">{{ _("Plan management not available") }}</h1>
<p>
{% trans %}
Plan management for this server is not available because at least one organization
hosted on this server already has an active plan.
{% endtrans %}
</p>
<p>
{% trans %}
<a href="https://zulip.com/help/self-hosted-billing#manage-billing">Log in</a> to plan management for your
organization instead, or <a href='mailto:{{ support_email }}'>contact support</a> with any questions.
{% endtrans %}
</p>
</div>
</div>
</div>
</div>
</div>
{% endblock %}