From 69aada79b67970c4fc2598be944d1d796b0c5783 Mon Sep 17 00:00:00 2001
From: kaiyou <pierre@jaury.eu>
Date: Mon, 21 Sep 2020 23:04:13 +0200
Subject: [PATCH] Add the first Synapse action

---
 hiboo/application/base.py                     |  2 +-
 hiboo/application/social.py                   | 35 ++++++++++++++++++-
 .../templates/application_synapse/rooms.html  | 31 ++++++++++++++++
 hiboo/service/templates/service_details.html  |  4 +--
 hiboo/service/views.py                        |  2 +-
 requirements.txt                              |  1 +
 6 files changed, 70 insertions(+), 5 deletions(-)
 create mode 100644 hiboo/application/templates/application_synapse/rooms.html

diff --git a/hiboo/application/base.py b/hiboo/application/base.py
index ba1deea7..5a4744a1 100644
--- a/hiboo/application/base.py
+++ b/hiboo/application/base.py
@@ -40,7 +40,7 @@ def action(label, profile=False, quick=False):
         def __set_name__(self, owner, name):
             if "actions" not in owner.__dict__:
                 owner.actions = dict()
-            owner.actions[name] = (label, profile, quick)
+            owner.actions[name] = (label, profile, quick, self.function)
             setattr(owner, name, self.function)
     return Register
 
diff --git a/hiboo/application/social.py b/hiboo/application/social.py
index dd1a50f6..f08973bb 100644
--- a/hiboo/application/social.py
+++ b/hiboo/application/social.py
@@ -2,6 +2,10 @@ from hiboo.application import register, base
 from wtforms import validators, fields
 from flask_babel import lazy_gettext as _
 
+import flask
+import flask_wtf
+import axon.cli
+
 
 @register("mastodon")
 class MastodonApplication(base.SAMLApplication):
@@ -40,11 +44,17 @@ class SynapseApplication(base.SAMLApplication):
 
     class Form(base.BaseForm):
         application_uri = fields.StringField(_("Synapse homeserver URL"), [validators.URL(require_tld=False)])
+        admin_token = fields.PasswordField(_("Synapse administrator token"))
         submit = fields.SubmitField(_('Submit'))
 
+    class SearchForm(flask_wtf.FlaskForm):
+        keyword = fields.StringField(_("Search keyword"))
+        submit = fields.SubmitField(_("Search"))
+
     def populate_service(self, form, service):
         service.config.update({
             "application_uri": form.application_uri.data,
+            "admin_token": form.admin_token.data,
             "acs": form.application_uri.data + "/_matrix/saml2/authn_response",
             "entityid": form.application_uri.data + "/_matrix/saml2/metadata.xml",
             "sign_mode": "response"
@@ -54,9 +64,32 @@ class SynapseApplication(base.SAMLApplication):
     def populate_form(self, service, form):
         form.process(
             obj=service,
-            application_uri=service.config.get("application_uri")
+            application_uri=service.config.get("application_uri"),
+            admin_token=service.config.get("admin_token")
         )
 
+    def get_axon(self, service):
+        """ Return an axon instance for the homeserver
+        """
+        return axon.api.Client(dict(
+            url=service.config.get("application_uri"),
+            token=service.config.get("admin_token")
+        ))
+
+    @base.action("Search rooms")
+    def search_rooms(self, service):
+        """ Search by keyword among server rooms, including non-published
+        rooms
+        """
+        form = SynapseApplication.SearchForm()
+        if form.validate_on_submit():
+            client = self.get_axon(service)
+            results = client.list_rooms(False, search_term=form.keyword.data)
+        else:
+            results = []
+        return flask.render_template(
+            "application_synapse/rooms.html", form=form, results=results)
+
 
 @register("writefreely")
 class WriteFreelyApplication(base.OIDCApplication):
diff --git a/hiboo/application/templates/application_synapse/rooms.html b/hiboo/application/templates/application_synapse/rooms.html
new file mode 100644
index 00000000..b26ff674
--- /dev/null
+++ b/hiboo/application/templates/application_synapse/rooms.html
@@ -0,0 +1,31 @@
+{% import "macros.html" as macros %}
+{{ macros.form(form) }}
+{% if results %}
+<div class="row">
+    <div class="col-xs-12">
+      <div class="box">
+        <div class="box-body table-responsive no-padding">
+          <table class="table table-hover">
+            <tr>
+              <th>{% trans %}RoomID{% endtrans %}</th>
+              <th>{% trans %}Alias{% endtrans %}</th>
+              <th>{% trans %}Name{% endtrans %}</th>
+              <th>{% trans %}Members (local){% endtrans %}</th>
+              <th>{% trans %}Properties{% endtrans %}</th>
+            </tr>
+            {% for room in results["rooms"] %}
+            <tr>
+              <td>{{ room["room_id"] }}</td>
+              <td>{{ room["canonical_alias"] }}</td>
+              <td>{{ room["name"] }}</td>
+              <td>{{ room["joined_members"] }} ({{ room["joined_local_members"] }})</td>
+              <td>{{ room["join_rules"] }}, {{ room["history_visibility"] }}</td>
+            </tr>
+            {% endfor %}
+          </table>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+{% endif %}
\ No newline at end of file
diff --git a/hiboo/service/templates/service_details.html b/hiboo/service/templates/service_details.html
index 19ca15c2..06c4d27d 100644
--- a/hiboo/service/templates/service_details.html
+++ b/hiboo/service/templates/service_details.html
@@ -40,7 +40,7 @@
       </div>
       <div class="box-body">
         <dl class="dl-horizontal">
-          {% for action, (label, profile, _) in application.actions.items() %}
+          {% for action, (label, profile, _, function) in application.actions.items() %}
           {% if not profile %}
           <dt><a href="{{ url_for(".action", service_uuid=service.uuid, action=action) }}">{{ label }}</a></dt>
           <dd>{{ function.__doc__ }}</dd>
@@ -62,7 +62,7 @@
 {% endblock %}
 
 {% block actions %}
-{% for action, (label, profile, quick) in application.actions.items() %}
+{% for action, (label, profile, quick, function) in application.actions.items() %}
 {% if quick and not profile %}
 <a href="{{ url_for(".action", service_uuid=service.uuid, action=action) }}" class="btn btn-info">{{ label }}</a>
 {% endif %}
diff --git a/hiboo/service/views.py b/hiboo/service/views.py
index e5e97b53..beb241bb 100644
--- a/hiboo/service/views.py
+++ b/hiboo/service/views.py
@@ -84,7 +84,7 @@ def delete(service_uuid):
 def action(service_uuid, action):
     service = models.Service.query.get(service_uuid) or flask.abort(404)
     app = service.application or flask.abort(404)
-    label, profile, quick = app.actions.get(action) or flask.abort(404)
+    label, profile, quick, function = app.actions.get(action) or flask.abort(404)
     if profile:
         flask.abort(404)
     result = getattr(app, action)(service)
diff --git a/requirements.txt b/requirements.txt
index a7a855b2..43dea1d9 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -22,3 +22,4 @@ psycopg2
 jwcrypto
 argon2_cffi
 terminaltables
+git+https://forge.tedomum.net/tedomum/axon.git
\ No newline at end of file
-- 
GitLab