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
|