mirror of https://github.com/zulip/zulip.git
support: Add basic support endpoint for remote servers.
This commit is contained in:
parent
2ed1465b04
commit
f71e2c8247
|
@ -25,6 +25,54 @@ from zerver.models import (
|
|||
if TYPE_CHECKING:
|
||||
from django.test.client import _MonkeyPatchedWSGIResponse as TestHttpResponse
|
||||
|
||||
import uuid
|
||||
|
||||
from zilencer.models import RemoteZulipServer
|
||||
|
||||
|
||||
class TestRemoteServerSupportEndpoint(ZulipTestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
# Set up some initial example data.
|
||||
for i in range(20):
|
||||
hostname = f"zulip-{i}.example.com"
|
||||
RemoteZulipServer.objects.create(
|
||||
hostname=hostname, contact_email=f"admin@{hostname}", plan_type=1, uuid=uuid.uuid4()
|
||||
)
|
||||
|
||||
def test_search(self) -> None:
|
||||
self.login("cordelia")
|
||||
|
||||
result = self.client_get("/activity/remote/support")
|
||||
self.assertEqual(result.status_code, 302)
|
||||
self.assertEqual(result["Location"], "/login/")
|
||||
|
||||
# Iago is the user with the appropriate permissions to access this page.
|
||||
self.login("iago")
|
||||
assert self.example_user("iago").is_staff
|
||||
|
||||
result = self.client_get("/activity/remote/support")
|
||||
self.assert_in_success_response(
|
||||
[
|
||||
'input type="text" name="q" class="input-xxlarge search-query" placeholder="hostname or contact email"'
|
||||
],
|
||||
result,
|
||||
)
|
||||
|
||||
result = self.client_get("/activity/remote/support", {"q": "zulip-1.example.com"})
|
||||
self.assert_in_success_response(["<h3>zulip-1.example.com</h3>"], result)
|
||||
self.assert_not_in_success_response(["<h3>zulip-2.example.com</h3>"], result)
|
||||
|
||||
result = self.client_get("/activity/remote/support", {"q": "example.com"})
|
||||
for i in range(20):
|
||||
self.assert_in_success_response([f"<h3>zulip-{i}.example.com</h3>"], result)
|
||||
|
||||
result = self.client_get("/activity/remote/support", {"q": "admin@zulip-2.example.com"})
|
||||
self.assert_in_success_response(["<h3>zulip-2.example.com</h3>"], result)
|
||||
self.assert_in_success_response(["<b>Contact email</b>: admin@zulip-2.example.com"], result)
|
||||
self.assert_not_in_success_response(["<h3>zulip-1.example.com</h3>"], result)
|
||||
|
||||
|
||||
class TestSupportEndpoint(ZulipTestCase):
|
||||
def test_search(self) -> None:
|
||||
|
|
|
@ -21,7 +21,7 @@ from analytics.views.stats import (
|
|||
stats_for_remote_installation,
|
||||
stats_for_remote_realm,
|
||||
)
|
||||
from analytics.views.support import support
|
||||
from analytics.views.support import remote_servers_support, support
|
||||
from analytics.views.user_activity import get_user_activity
|
||||
from zerver.lib.rest import rest_path
|
||||
|
||||
|
@ -30,6 +30,7 @@ i18n_urlpatterns: List[Union[URLPattern, URLResolver]] = [
|
|||
path("activity", get_installation_activity),
|
||||
path("activity/remote", get_remote_server_activity),
|
||||
path("activity/support", support, name="support"),
|
||||
path("activity/remote/support", remote_servers_support, name="remote_servers_support"),
|
||||
path("realm_activity/<realm_str>/", get_realm_activity),
|
||||
path("user_activity/<user_profile_id>/", get_user_activity),
|
||||
path("stats/realm/<realm_str>/", stats_for_realm),
|
||||
|
|
|
@ -17,6 +17,7 @@ from django.utils.timesince import timesince
|
|||
from django.utils.timezone import now as timezone_now
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from analytics.views.activity_common import remote_installation_stats_link
|
||||
from confirmation.models import Confirmation, confirmation_url
|
||||
from confirmation.settings import STATUS_USED
|
||||
from zerver.actions.create_realm import do_change_realm_subdomain
|
||||
|
@ -48,6 +49,9 @@ from zerver.models import (
|
|||
)
|
||||
from zerver.views.invite import get_invitee_emails_set
|
||||
|
||||
if settings.ZILENCER_ENABLED:
|
||||
from zilencer.models import RemoteZulipServer
|
||||
|
||||
if settings.BILLING_ENABLED:
|
||||
from corporate.lib.stripe import approve_sponsorship as do_approve_sponsorship
|
||||
from corporate.lib.stripe import (
|
||||
|
@ -406,3 +410,44 @@ def support(
|
|||
)
|
||||
|
||||
return render(request, "analytics/support.html", context=context)
|
||||
|
||||
|
||||
def get_remote_servers_for_support(
|
||||
email_to_search: Optional[str], hostname_to_search: Optional[str]
|
||||
) -> List["RemoteZulipServer"]:
|
||||
if not email_to_search and not hostname_to_search:
|
||||
return []
|
||||
|
||||
remote_servers_query = RemoteZulipServer.objects.order_by("id")
|
||||
if email_to_search:
|
||||
remote_servers_query = remote_servers_query.filter(contact_email__iexact=email_to_search)
|
||||
elif hostname_to_search:
|
||||
remote_servers_query = remote_servers_query.filter(hostname__icontains=hostname_to_search)
|
||||
|
||||
return list(remote_servers_query)
|
||||
|
||||
|
||||
@require_server_admin
|
||||
@has_request_variables
|
||||
def remote_servers_support(
|
||||
request: HttpRequest, query: Optional[str] = REQ("q", default=None)
|
||||
) -> HttpResponse:
|
||||
email_to_search = None
|
||||
hostname_to_search = None
|
||||
if query:
|
||||
if "@" in query:
|
||||
email_to_search = query
|
||||
else:
|
||||
hostname_to_search = query
|
||||
|
||||
remote_servers = get_remote_servers_for_support(
|
||||
email_to_search=email_to_search, hostname_to_search=hostname_to_search
|
||||
)
|
||||
return render(
|
||||
request,
|
||||
"analytics/remote_server_support.html",
|
||||
context=dict(
|
||||
remote_servers=remote_servers,
|
||||
remote_installation_stats_link=remote_installation_stats_link,
|
||||
),
|
||||
)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
{% extends "zerver/base.html" %}
|
||||
{% set entrypoint = "support" %}
|
||||
|
||||
{# Remote servers. #}
|
||||
|
||||
{% block title %}
|
||||
<title>Remote servers</title>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<br />
|
||||
<form>
|
||||
<center>
|
||||
<input type="text" name="q" class="input-xxlarge search-query" placeholder="hostname or contact email" value="{{ request.GET.get('q', '') }}" autofocus />
|
||||
<button type="submit" class="btn btn-default support-search-button">Search</button>
|
||||
</center>
|
||||
</form>
|
||||
|
||||
<div id="remote-server-query-results">
|
||||
{% for remote_server in remote_servers %}
|
||||
<div class="support-query-result">
|
||||
<span class="label">remote server</span>
|
||||
<h3>{{ remote_server.hostname }}</h3>
|
||||
<b>Contact email</b>: {{ remote_server.contact_email }}<br />
|
||||
<b>Last updated</b>: {{ remote_server.last_updated|timesince }} ago<br />
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -548,6 +548,7 @@ html_rules: List["Rule"] = [
|
|||
},
|
||||
"exclude": {
|
||||
"templates/analytics/support.html",
|
||||
"templates/analytics/remote_server_support.html",
|
||||
# We have URL template and Pygments language name as placeholders
|
||||
# in the below template which we don't want to be translatable.
|
||||
"web/templates/settings/playground_settings_admin.hbs",
|
||||
|
|
Loading…
Reference in New Issue