From 42876969b99b6bad146b44a734e8d4a1a14d6835 Mon Sep 17 00:00:00 2001
From: Kegan Dougal <kegan@matrix.org>
Date: Wed, 28 Jan 2015 11:59:38 +0000
Subject: Add basic application_services SQL, and hook up parts of the
 appservice store to read from it.

---
 synapse/storage/schema/application_services.sql | 32 +++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 synapse/storage/schema/application_services.sql

(limited to 'synapse/storage/schema/application_services.sql')

diff --git a/synapse/storage/schema/application_services.sql b/synapse/storage/schema/application_services.sql
new file mode 100644
index 0000000000..6d245fc807
--- /dev/null
+++ b/synapse/storage/schema/application_services.sql
@@ -0,0 +1,32 @@
+/* Copyright 2015 OpenMarket Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+CREATE TABLE IF NOT EXISTS application_services(
+    id INTEGER PRIMARY KEY AUTOINCREMENT,
+    url TEXT,
+    token TEXT,
+    UNIQUE(token) ON CONFLICT ROLLBACK
+);
+
+CREATE TABLE IF NOT EXISTS application_services_regex(
+    id INTEGER PRIMARY KEY AUTOINCREMENT,
+    as_id INTEGER NOT NULL,
+    namespace INTEGER,  /* enum[room_id|room_alias|user_id] */
+    regex TEXT,
+    FOREIGN KEY(as_id) REFERENCES application_services(id)
+);
+
+
+
-- 
cgit 1.5.1


From 27091f146a0ebdbfe1ae7c5cd30de51515cfbebc Mon Sep 17 00:00:00 2001
From: Kegan Dougal <kegan@matrix.org>
Date: Thu, 5 Feb 2015 10:08:12 +0000
Subject: Add hs_token column and generate a different token f.e application
 service.

---
 synapse/appservice/__init__.py                  |  6 ++++--
 synapse/appservice/api.py                       |  8 ++++----
 synapse/handlers/appservice.py                  |  9 ++++++---
 synapse/rest/appservice/v1/register.py          |  4 ++--
 synapse/storage/appservice.py                   | 17 ++++++++++++-----
 synapse/storage/schema/application_services.sql |  1 +
 tests/storage/test_appservice.py                | 10 ++++++----
 7 files changed, 35 insertions(+), 20 deletions(-)

(limited to 'synapse/storage/schema/application_services.sql')

diff --git a/synapse/appservice/__init__.py b/synapse/appservice/__init__.py
index 0c7f58574e..f7baf578f0 100644
--- a/synapse/appservice/__init__.py
+++ b/synapse/appservice/__init__.py
@@ -34,11 +34,13 @@ class ApplicationService(object):
     # values.
     NS_LIST = [NS_USERS, NS_ALIASES, NS_ROOMS]
 
-    def __init__(self, token, url=None, namespaces=None, txn_id=None):
+    def __init__(self, token, url=None, namespaces=None, hs_token=None,
+                 txn_id=None):
         self.token = token
         self.url = url
+        self.hs_token = hs_token
         self.namespaces = self._check_namespaces(namespaces)
-        self.txn_id = None
+        self.txn_id = txn_id
 
     def _check_namespaces(self, namespaces):
         # Sanity check that it is of the form:
diff --git a/synapse/appservice/api.py b/synapse/appservice/api.py
index fbf4abc526..29bb35d61b 100644
--- a/synapse/appservice/api.py
+++ b/synapse/appservice/api.py
@@ -30,7 +30,6 @@ class ApplicationServiceApi(SimpleHttpClient):
 
     def __init__(self,  hs):
         super(ApplicationServiceApi, self).__init__(hs)
-        self.hs_token = "_hs_token_"  # TODO extract hs token
 
     @defer.inlineCallbacks
     def query_user(self, service, user_id):
@@ -38,7 +37,7 @@ class ApplicationServiceApi(SimpleHttpClient):
         response = None
         try:
             response = yield self.get_json(uri, {
-                "access_token": self.hs_token
+                "access_token": service.hs_token
             })
             if response:  # just an empty json object
                 defer.returnValue(True)
@@ -54,7 +53,7 @@ class ApplicationServiceApi(SimpleHttpClient):
         response = None
         try:
             response = yield self.get_json(uri, {
-                "access_token": self.hs_token
+                "access_token": service.hs_token
             })
             if response:  # just an empty json object
                 defer.returnValue(True)
@@ -76,9 +75,10 @@ class ApplicationServiceApi(SimpleHttpClient):
                     "events": events
                 },
                 {
-                    "access_token": self.hs_token
+                    "access_token": service.hs_token
                 })
             if response:  # just an empty json object
+                # TODO: Mark txn as sent successfully
                 defer.returnValue(True)
         except CodeMessageException as e:
             logger.warning("push_bulk to %s received %s", uri, e.code)
diff --git a/synapse/handlers/appservice.py b/synapse/handlers/appservice.py
index 2b2761682f..7b0599c71e 100644
--- a/synapse/handlers/appservice.py
+++ b/synapse/handlers/appservice.py
@@ -19,6 +19,7 @@ from ._base import BaseHandler
 from synapse.api.errors import Codes, StoreError, SynapseError
 from synapse.appservice import ApplicationService
 from synapse.appservice.api import ApplicationServiceApi
+import synapse.util.stringutils as stringutils
 
 import logging
 
@@ -53,10 +54,9 @@ class ApplicationServicesHandler(object):
                 errcode=Codes.FORBIDDEN
             )
         logger.info("Updating application service info...")
+        app_service.hs_token = self._generate_hs_token()
         yield self.store.update_app_service(app_service)
-
-        logger.info("Sending ping to %s...", app_service.url)
-        yield self.appservice_api.push(app_service, "pinger")
+        defer.returnValue(app_service)
 
     def unregister(self, token):
         logger.info("Unregister as_token=%s", token)
@@ -136,3 +136,6 @@ class ApplicationServicesHandler(object):
         # Fork off pushes to these services - XXX First cut, best effort
         for service in services:
             self.appservice_api.push(service, event)
+
+    def _generate_hs_token(self):
+        return stringutils.random_string(18)
diff --git a/synapse/rest/appservice/v1/register.py b/synapse/rest/appservice/v1/register.py
index e374d538e7..d3d5aef220 100644
--- a/synapse/rest/appservice/v1/register.py
+++ b/synapse/rest/appservice/v1/register.py
@@ -61,8 +61,8 @@ class RegisterRestServlet(AppServiceRestServlet):
 
         app_service = ApplicationService(as_token, as_url, namespaces)
 
-        yield self.handler.register(app_service)
-        hs_token = "_not_implemented_yet"  # TODO: Pull this from self.hs?
+        app_service = yield self.handler.register(app_service)
+        hs_token = app_service.hs_token
 
         defer.returnValue((200, {
           "hs_token": hs_token
diff --git a/synapse/storage/appservice.py b/synapse/storage/appservice.py
index b64416de28..3c8bf9ad0d 100644
--- a/synapse/storage/appservice.py
+++ b/synapse/storage/appservice.py
@@ -60,6 +60,7 @@ class ApplicationServiceStore(SQLBaseStore):
             if service.token == token:
                 service.url = None
                 service.namespaces = None
+                service.hs_token = None
 
     def _unregister_app_service_txn(self, txn, token):
         # kill the url to prevent pushes
@@ -100,6 +101,9 @@ class ApplicationServiceStore(SQLBaseStore):
         if not service.token or not service.url:
             raise StoreError(400, "Token and url must be specified.")
 
+        if not service.hs_token:
+            raise StoreError(500, "No HS token")
+
         yield self.runInteraction(
             "update_app_service",
             self._update_app_service_txn,
@@ -126,8 +130,8 @@ class ApplicationServiceStore(SQLBaseStore):
             return False
 
         txn.execute(
-            "UPDATE application_services SET url=? WHERE id=?",
-            (service.url, as_id,)
+            "UPDATE application_services SET url=?, hs_token=? WHERE id=?",
+            (service.url, service.hs_token, as_id,)
         )
         # cleanup regex
         txn.execute(
@@ -196,6 +200,7 @@ class ApplicationServiceStore(SQLBaseStore):
         #     'namespace': enum,
         #     'as_id': 0,
         #     'token': "something",
+        #     'hs_token': "otherthing",
         #     'id': 0
         #   }
         # ]
@@ -208,6 +213,7 @@ class ApplicationServiceStore(SQLBaseStore):
                 services[as_token] = {
                     "url": res["url"],
                     "token": as_token,
+                    "hs_token": res["hs_token"],
                     "namespaces": {
                         ApplicationService.NS_USERS: [],
                         ApplicationService.NS_ALIASES: [],
@@ -230,8 +236,9 @@ class ApplicationServiceStore(SQLBaseStore):
         for service in services.values():
             logger.info("Found application service: %s", service)
             self.cache.services.append(ApplicationService(
-                service["token"],
-                service["url"],
-                service["namespaces"]
+                token=service["token"],
+                url=service["url"],
+                namespaces=service["namespaces"],
+                hs_token=service["hs_token"]
             ))
 
diff --git a/synapse/storage/schema/application_services.sql b/synapse/storage/schema/application_services.sql
index 6d245fc807..03b5a10c8a 100644
--- a/synapse/storage/schema/application_services.sql
+++ b/synapse/storage/schema/application_services.sql
@@ -17,6 +17,7 @@ CREATE TABLE IF NOT EXISTS application_services(
     id INTEGER PRIMARY KEY AUTOINCREMENT,
     url TEXT,
     token TEXT,
+    hs_token TEXT,
     UNIQUE(token) ON CONFLICT ROLLBACK
 );
 
diff --git a/tests/storage/test_appservice.py b/tests/storage/test_appservice.py
index 56fdda377c..b9ecfb3384 100644
--- a/tests/storage/test_appservice.py
+++ b/tests/storage/test_appservice.py
@@ -46,13 +46,15 @@ class ApplicationServiceStoreTestCase(unittest.TestCase):
     @defer.inlineCallbacks
     def test_update_and_retrieval_of_service(self):
         url = "https://matrix.org/appservices/foobar"
+        hs_token = "hstok"
         user_regex = ["@foobar_.*:matrix.org"]
         alias_regex = ["#foobar_.*:matrix.org"]
         room_regex = []
-        service = ApplicationService(url=url, token=self.as_token, namespaces={
-            ApplicationService.NS_USERS: user_regex,
-            ApplicationService.NS_ALIASES: alias_regex,
-            ApplicationService.NS_ROOMS: room_regex
+        service = ApplicationService(
+            url=url, hs_token=hs_token, token=self.as_token, namespaces={
+                ApplicationService.NS_USERS: user_regex,
+                ApplicationService.NS_ALIASES: alias_regex,
+                ApplicationService.NS_ROOMS: room_regex
         })
         yield self.store.update_app_service(service)
 
-- 
cgit 1.5.1


From ac3183caaa66b750996d90c0ac9ed430f623909c Mon Sep 17 00:00:00 2001
From: Kegan Dougal <kegan@matrix.org>
Date: Mon, 9 Feb 2015 12:03:37 +0000
Subject: Register a user account for the AS when the AS registers. Add
 'sender' column to AS table.

---
 synapse/appservice/__init__.py                  | 3 ++-
 synapse/handlers/appservice.py                  | 8 +++++++-
 synapse/storage/appservice.py                   | 5 +++--
 synapse/storage/schema/application_services.sql | 1 +
 synapse/storage/schema/delta/v14.sql            | 1 +
 5 files changed, 14 insertions(+), 4 deletions(-)

(limited to 'synapse/storage/schema/application_services.sql')

diff --git a/synapse/appservice/__init__.py b/synapse/appservice/__init__.py
index 46d46a5a48..fb9bfffe5d 100644
--- a/synapse/appservice/__init__.py
+++ b/synapse/appservice/__init__.py
@@ -35,10 +35,11 @@ class ApplicationService(object):
     NS_LIST = [NS_USERS, NS_ALIASES, NS_ROOMS]
 
     def __init__(self, token, url=None, namespaces=None, hs_token=None,
-                 txn_id=None):
+                 sender=None, txn_id=None):
         self.token = token
         self.url = url
         self.hs_token = hs_token
+        self.sender = sender
         self.namespaces = self._check_namespaces(namespaces)
         self.txn_id = txn_id
 
diff --git a/synapse/handlers/appservice.py b/synapse/handlers/appservice.py
index fa810b9a98..5071a12eb1 100644
--- a/synapse/handlers/appservice.py
+++ b/synapse/handlers/appservice.py
@@ -52,8 +52,14 @@ class ApplicationServicesHandler(object):
                 "Consult the home server admin.",
                 errcode=Codes.FORBIDDEN
             )
-        logger.info("Updating application service info...")
+
         app_service.hs_token = self._generate_hs_token()
+
+        # create a sender for this application service which is used when
+        # creating rooms, etc..
+        account = yield self.hs.get_handlers().registration_handler.register()
+        app_service.sender = account[0]
+
         yield self.store.update_app_service(app_service)
         defer.returnValue(app_service)
 
diff --git a/synapse/storage/appservice.py b/synapse/storage/appservice.py
index 3c8bf9ad0d..eef77e737e 100644
--- a/synapse/storage/appservice.py
+++ b/synapse/storage/appservice.py
@@ -130,8 +130,9 @@ class ApplicationServiceStore(SQLBaseStore):
             return False
 
         txn.execute(
-            "UPDATE application_services SET url=?, hs_token=? WHERE id=?",
-            (service.url, service.hs_token, as_id,)
+            "UPDATE application_services SET url=?, hs_token=?, sender=? "
+            "WHERE id=?",
+            (service.url, service.hs_token, service.sender, as_id,)
         )
         # cleanup regex
         txn.execute(
diff --git a/synapse/storage/schema/application_services.sql b/synapse/storage/schema/application_services.sql
index 03b5a10c8a..e491ad5aec 100644
--- a/synapse/storage/schema/application_services.sql
+++ b/synapse/storage/schema/application_services.sql
@@ -18,6 +18,7 @@ CREATE TABLE IF NOT EXISTS application_services(
     url TEXT,
     token TEXT,
     hs_token TEXT,
+    sender TEXT,
     UNIQUE(token) ON CONFLICT ROLLBACK
 );
 
diff --git a/synapse/storage/schema/delta/v14.sql b/synapse/storage/schema/delta/v14.sql
index 03b5a10c8a..e491ad5aec 100644
--- a/synapse/storage/schema/delta/v14.sql
+++ b/synapse/storage/schema/delta/v14.sql
@@ -18,6 +18,7 @@ CREATE TABLE IF NOT EXISTS application_services(
     url TEXT,
     token TEXT,
     hs_token TEXT,
+    sender TEXT,
     UNIQUE(token) ON CONFLICT ROLLBACK
 );
 
-- 
cgit 1.5.1

