summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--synapse/api/constants.py1
-rw-r--r--synapse/rest/client/v1/login.py19
2 files changed, 18 insertions, 2 deletions
diff --git a/synapse/api/constants.py b/synapse/api/constants.py
index 6a6d32c302..43e5b6cc00 100644
--- a/synapse/api/constants.py
+++ b/synapse/api/constants.py
@@ -57,6 +57,7 @@ class JoinRules(object):
 
 class LoginType(object):
     PASSWORD = "m.login.password"
+    APPSERVICE = "uk.half-shot.unstable.login.appservice"
     EMAIL_IDENTITY = "m.login.email.identity"
     MSISDN = "m.login.msisdn"
     RECAPTCHA = "m.login.recaptcha"
diff --git a/synapse/rest/client/v1/login.py b/synapse/rest/client/v1/login.py
index a14618ac84..e8b5fc9a4e 100644
--- a/synapse/rest/client/v1/login.py
+++ b/synapse/rest/client/v1/login.py
@@ -16,8 +16,10 @@
 import logging
 from typing import Awaitable, Callable, Dict, Optional
 
+from synapse.api.constants import LoginType
 from synapse.api.errors import Codes, LoginError, SynapseError
 from synapse.api.ratelimiting import Ratelimiter
+from synapse.appservice import ApplicationService
 from synapse.handlers.auth import (
     convert_client_dict_legacy_fields_to_identifier,
     login_id_phone_to_thirdparty,
@@ -61,6 +63,8 @@ class LoginRestServlet(RestServlet):
         self.cas_enabled = hs.config.cas_enabled
         self.oidc_enabled = hs.config.oidc_enabled
 
+        self.auth = hs.get_auth()
+
         self.auth_handler = self.hs.get_auth_handler()
         self.registration_handler = hs.get_registration_handler()
         self.handlers = hs.get_handlers()
@@ -116,6 +120,11 @@ class LoginRestServlet(RestServlet):
         self._address_ratelimiter.ratelimit(request.getClientIP())
 
         login_submission = parse_json_object_from_request(request)
+
+        appservice = None
+        if self.auth.has_access_token(request):
+            appservice = self.auth.get_appservice_by_req(request)
+
         try:
             if self.jwt_enabled and (
                 login_submission["type"] == LoginRestServlet.JWT_TYPE
@@ -125,7 +134,7 @@ class LoginRestServlet(RestServlet):
             elif login_submission["type"] == LoginRestServlet.TOKEN_TYPE:
                 result = await self._do_token_login(login_submission)
             else:
-                result = await self._do_other_login(login_submission)
+                result = await self._do_other_login(login_submission, appservice)
         except KeyError:
             raise SynapseError(400, "Missing JSON keys.")
 
@@ -134,7 +143,9 @@ class LoginRestServlet(RestServlet):
             result["well_known"] = well_known_data
         return 200, result
 
-    async def _do_other_login(self, login_submission: JsonDict) -> Dict[str, str]:
+    async def _do_other_login(
+        self, login_submission: JsonDict, appservice: ApplicationService
+    ) -> Dict[str, str]:
         """Handle non-token/saml/jwt logins
 
         Args:
@@ -229,6 +240,10 @@ class LoginRestServlet(RestServlet):
         else:
             qualified_user_id = UserID(identifier["user"], self.hs.hostname).to_string()
 
+        if login_submission["type"] == LoginType.APPSERVICE and appservice is not None:
+            result = await self._complete_login(qualified_user_id, login_submission)
+            return result
+
         # Check if we've hit the failed ratelimit (but don't update it)
         self._failed_attempts_ratelimiter.ratelimit(
             qualified_user_id.lower(), update=False