Add ability for ASes to login

pull/8320/head
Will Hunt 2020-09-15 17:22:13 +01:00
parent 576bc37d31
commit 9743a552de
2 changed files with 18 additions and 2 deletions

View File

@ -57,6 +57,7 @@ class JoinRules:
class LoginType: class LoginType:
PASSWORD = "m.login.password" PASSWORD = "m.login.password"
APPSERVICE = "uk.half-shot.unstable.login.appservice"
EMAIL_IDENTITY = "m.login.email.identity" EMAIL_IDENTITY = "m.login.email.identity"
MSISDN = "m.login.msisdn" MSISDN = "m.login.msisdn"
RECAPTCHA = "m.login.recaptcha" RECAPTCHA = "m.login.recaptcha"

View File

@ -16,8 +16,10 @@
import logging import logging
from typing import Awaitable, Callable, Dict, Optional from typing import Awaitable, Callable, Dict, Optional
from synapse.api.constants import LoginType
from synapse.api.errors import Codes, LoginError, SynapseError from synapse.api.errors import Codes, LoginError, SynapseError
from synapse.api.ratelimiting import Ratelimiter from synapse.api.ratelimiting import Ratelimiter
from synapse.appservice import ApplicationService
from synapse.handlers.auth import ( from synapse.handlers.auth import (
convert_client_dict_legacy_fields_to_identifier, convert_client_dict_legacy_fields_to_identifier,
login_id_phone_to_thirdparty, login_id_phone_to_thirdparty,
@ -61,6 +63,8 @@ class LoginRestServlet(RestServlet):
self.cas_enabled = hs.config.cas_enabled self.cas_enabled = hs.config.cas_enabled
self.oidc_enabled = hs.config.oidc_enabled self.oidc_enabled = hs.config.oidc_enabled
self.auth = hs.get_auth()
self.auth_handler = self.hs.get_auth_handler() self.auth_handler = self.hs.get_auth_handler()
self.registration_handler = hs.get_registration_handler() self.registration_handler = hs.get_registration_handler()
self.handlers = hs.get_handlers() self.handlers = hs.get_handlers()
@ -116,6 +120,11 @@ class LoginRestServlet(RestServlet):
self._address_ratelimiter.ratelimit(request.getClientIP()) self._address_ratelimiter.ratelimit(request.getClientIP())
login_submission = parse_json_object_from_request(request) 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: try:
if self.jwt_enabled and ( if self.jwt_enabled and (
login_submission["type"] == LoginRestServlet.JWT_TYPE login_submission["type"] == LoginRestServlet.JWT_TYPE
@ -125,7 +134,7 @@ class LoginRestServlet(RestServlet):
elif login_submission["type"] == LoginRestServlet.TOKEN_TYPE: elif login_submission["type"] == LoginRestServlet.TOKEN_TYPE:
result = await self._do_token_login(login_submission) result = await self._do_token_login(login_submission)
else: else:
result = await self._do_other_login(login_submission) result = await self._do_other_login(login_submission, appservice)
except KeyError: except KeyError:
raise SynapseError(400, "Missing JSON keys.") raise SynapseError(400, "Missing JSON keys.")
@ -134,7 +143,9 @@ class LoginRestServlet(RestServlet):
result["well_known"] = well_known_data result["well_known"] = well_known_data
return 200, result 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 """Handle non-token/saml/jwt logins
Args: Args:
@ -229,6 +240,10 @@ class LoginRestServlet(RestServlet):
else: else:
qualified_user_id = UserID(identifier["user"], self.hs.hostname).to_string() 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) # Check if we've hit the failed ratelimit (but don't update it)
self._failed_attempts_ratelimiter.ratelimit( self._failed_attempts_ratelimiter.ratelimit(
qualified_user_id.lower(), update=False qualified_user_id.lower(), update=False