def get_server_api_key(self, server_uuid): # type: (Text) -> Text if server_uuid not in API_KEYS: API_KEYS[server_uuid] = get_remote_server_by_uuid( server_uuid).api_key return API_KEYS[server_uuid]
def validate_api_key(request: HttpRequest, role: Optional[str], api_key: str, allow_webhook_access: bool=False, client_name: Optional[str]=None) -> Union[UserProfile, "RemoteZulipServer"]: # Remove whitespace to protect users from trivial errors. api_key = api_key.strip() if role is not None: role = role.strip() # If `role` doesn't look like an email, it might be a uuid. if settings.ZILENCER_ENABLED and role is not None and '@' not in role: try: remote_server = get_remote_server_by_uuid(role) except RemoteZulipServer.DoesNotExist: raise InvalidZulipServerError(role) if api_key != remote_server.api_key: raise InvalidZulipServerKeyError(role) if get_subdomain(request) != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN: raise JsonableError(_("Invalid subdomain for push notifications bouncer")) request.user = remote_server remote_server.rate_limits = "" # Skip updating UserActivity, since remote_server isn't actually a UserProfile object. process_client(request, remote_server, skip_update_user_activity=True) return remote_server user_profile = access_user_by_api_key(request, api_key, email=role) if user_profile.is_incoming_webhook and not allow_webhook_access: raise JsonableError(_("This API is not available to incoming webhook bots.")) request.user = user_profile process_client(request, user_profile, client_name=client_name) return user_profile
def validate_api_key(request, role, api_key, is_webhook=False, client_name=None): # type: (HttpRequest, Optional[Text], Text, bool, Optional[Text]) -> Union[UserProfile, RemoteZulipServer] # Remove whitespace to protect users from trivial errors. api_key = api_key.strip() if role is not None: role = role.strip() if settings.ZILENCER_ENABLED and role is not None and is_remote_server(role): try: remote_server = get_remote_server_by_uuid(role) except RemoteZulipServer.DoesNotExist: raise JsonableError(_("Invalid Zulip server: %s") % (role,)) if api_key != remote_server.api_key: raise JsonableError(_("Invalid API key")) if not check_subdomain(get_subdomain(request), ""): raise JsonableError(_("This API key only works on the root subdomain")) request.user = remote_server request._email = "zulip-server:" + role remote_server.rate_limits = "" process_client(request, remote_server, remote_server_request=True) return remote_server user_profile = access_user_by_api_key(request, api_key, email=role) if user_profile.is_incoming_webhook and not is_webhook: raise JsonableError(_("This API is not available to incoming webhook bots.")) request.user = user_profile request._email = user_profile.email process_client(request, user_profile, client_name=client_name) return user_profile
def validate_api_key(request: HttpRequest, role: Optional[str], api_key: str, is_webhook: bool=False, client_name: Optional[str]=None) -> Union[UserProfile, RemoteZulipServer]: # Remove whitespace to protect users from trivial errors. api_key = api_key.strip() if role is not None: role = role.strip() if settings.ZILENCER_ENABLED and role is not None and is_remote_server(role): try: remote_server = get_remote_server_by_uuid(role) except RemoteZulipServer.DoesNotExist: raise InvalidZulipServerError(role) if api_key != remote_server.api_key: raise InvalidZulipServerKeyError(role) if get_subdomain(request) != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN: raise JsonableError(_("Invalid subdomain for push notifications bouncer")) request.user = remote_server request._email = "zulip-server:" + role remote_server.rate_limits = "" process_client(request, remote_server, remote_server_request=True) return remote_server user_profile = access_user_by_api_key(request, api_key, email=role) if user_profile.is_incoming_webhook and not is_webhook: raise JsonableError(_("This API is not available to incoming webhook bots.")) request.user = user_profile request._email = user_profile.email process_client(request, user_profile, client_name=client_name) return user_profile
def encode_uuid(self, uuid: str) -> str: """ identifier: Can be an email or a remote server uuid. """ if uuid in self.API_KEYS: api_key = self.API_KEYS[uuid] else: api_key = get_remote_server_by_uuid(uuid).api_key self.API_KEYS[uuid] = api_key return self.encode_credentials(uuid, api_key)
def validate_api_key(request, role, api_key, is_webhook=False): # type: (HttpRequest, Text, Text, bool) -> Union[UserProfile, RemoteZulipServer] # Remove whitespace to protect users from trivial errors. role, api_key = role.strip(), api_key.strip() if not is_remote_server(role): try: profile = get_user_profile_by_email( role) # type: Union[UserProfile, RemoteZulipServer] except UserProfile.DoesNotExist: raise JsonableError(_("Invalid user: %s") % (role, )) else: try: profile = get_remote_server_by_uuid(role) except RemoteZulipServer.DoesNotExist: raise JsonableError(_("Invalid Zulip server: %s") % (role, )) if api_key != profile.api_key: if len(api_key) != 32: reason = _("Incorrect API key length (keys should be 32 " "characters long) for role '%s'") else: reason = _("Invalid API key for role '%s'") raise JsonableError(reason % (role, )) # early exit for RemoteZulipServer instances if settings.ZILENCER_ENABLED and isinstance(profile, RemoteZulipServer): if not check_subdomain(get_subdomain(request), ""): raise JsonableError( _("This API key only works on the root subdomain")) return profile profile = cast(UserProfile, profile) # is UserProfile if not profile.is_active: raise JsonableError(_("Account not active")) if profile.is_incoming_webhook and not is_webhook: raise JsonableError(_("Account is not valid to post webhook messages")) if profile.realm.deactivated: raise JsonableError(_("Realm for account has been deactivated")) if (not check_subdomain(get_subdomain(request), profile.realm.subdomain) and # Allow access to localhost for Tornado not (settings.RUNNING_INSIDE_TORNADO and request.META["SERVER_NAME"] == "127.0.0.1" and request.META["REMOTE_ADDR"] == "127.0.0.1")): logging.warning( "User %s attempted to access API on wrong subdomain %s" % (profile.email, get_subdomain(request))) raise JsonableError(_("Account is not associated with this subdomain")) return profile
def validate_api_key(request, role, api_key, is_webhook=False): # type: (HttpRequest, Text, Text, bool) -> Union[UserProfile, RemoteZulipServer] # Remove whitespace to protect users from trivial errors. role, api_key = role.strip(), api_key.strip() if not is_remote_server(role): try: profile = get_user_profile_by_email(role) # type: Union[UserProfile, RemoteZulipServer] except UserProfile.DoesNotExist: raise JsonableError(_("Invalid user: %s") % (role,)) else: try: profile = get_remote_server_by_uuid(role) except RemoteZulipServer.DoesNotExist: raise JsonableError(_("Invalid Zulip server: %s") % (role,)) if api_key != profile.api_key: if len(api_key) != 32: reason = _("Incorrect API key length (keys should be 32 " "characters long) for role '%s'") else: reason = _("Invalid API key for role '%s'") raise JsonableError(reason % (role,)) # early exit for RemoteZulipServer instances if settings.ZILENCER_ENABLED and isinstance(profile, RemoteZulipServer): if not check_subdomain(get_subdomain(request), ""): raise JsonableError(_("This API key only works on the root subdomain")) return profile profile = cast(UserProfile, profile) # is UserProfile if not profile.is_active: raise JsonableError(_("Account not active")) if profile.is_incoming_webhook and not is_webhook: raise JsonableError(_("Account is not valid to post webhook messages")) if profile.realm.deactivated: raise JsonableError(_("Realm for account has been deactivated")) if (not check_subdomain(get_subdomain(request), profile.realm.subdomain) and # Allow access to localhost for Tornado not (settings.RUNNING_INSIDE_TORNADO and request.META["SERVER_NAME"] == "127.0.0.1" and request.META["REMOTE_ADDR"] == "127.0.0.1")): logging.warning("User %s attempted to access API on wrong subdomain %s" % ( profile.email, get_subdomain(request))) raise JsonableError(_("Account is not associated with this subdomain")) return profile
def encode_credentials(self, identifier: Text, realm: Text="zulip") -> Text: """ identifier: Can be an email or a remote server uuid. """ if identifier in API_KEYS: api_key = API_KEYS[identifier] else: if is_remote_server(identifier): api_key = get_remote_server_by_uuid(identifier).api_key else: api_key = get_user(identifier, get_realm(realm)).api_key API_KEYS[identifier] = api_key credentials = "%s:%s" % (identifier, api_key) return 'Basic ' + base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
def encode_credentials(self, identifier: str, realm: str = "zulip") -> str: """ identifier: Can be an email or a remote server uuid. """ if identifier in self.API_KEYS: api_key = self.API_KEYS[identifier] else: if is_remote_server(identifier): api_key = get_remote_server_by_uuid(identifier).api_key else: user = get_user_by_delivery_email(identifier, get_realm(realm)) api_key = get_api_key(user) self.API_KEYS[identifier] = api_key credentials = "%s:%s" % (identifier, api_key) return 'Basic ' + base64.b64encode( credentials.encode('utf-8')).decode('utf-8')
def api_auth(self, identifier): # type: (Text) -> Dict[str, Text] """ identifier: Can be an email or a remote server uuid. """ if identifier in API_KEYS: api_key = API_KEYS[identifier] else: if is_remote_server(identifier): api_key = get_remote_server_by_uuid(identifier).api_key else: api_key = get_user_profile_by_email(identifier).api_key API_KEYS[identifier] = api_key credentials = u"%s:%s" % (identifier, api_key) return { 'HTTP_AUTHORIZATION': u'Basic ' + base64.b64encode(credentials.encode('utf-8')).decode('utf-8') }
def api_auth(self, identifier): # type: (Text) -> Dict[str, Text] """ identifier: Can be an email or a remote server uuid. """ if identifier in API_KEYS: api_key = API_KEYS[identifier] else: if is_remote_server(identifier): api_key = get_remote_server_by_uuid(identifier).api_key else: api_key = get_user_profile_by_email(identifier).api_key API_KEYS[identifier] = api_key credentials = u"%s:%s" % (identifier, api_key) return { 'HTTP_AUTHORIZATION': u'Basic ' + base64.b64encode(credentials.encode('utf-8')).decode('utf-8') }
def api_auth(self, identifier: Text, realm: Text = "zulip") -> Dict[str, Text]: """ identifier: Can be an email or a remote server uuid. """ if identifier in API_KEYS: api_key = API_KEYS[identifier] else: if is_remote_server(identifier): api_key = get_remote_server_by_uuid(identifier).api_key else: api_key = get_user(identifier, get_realm(realm)).api_key API_KEYS[identifier] = api_key credentials = "%s:%s" % (identifier, api_key) return { 'HTTP_AUTHORIZATION': 'Basic ' + base64.b64encode(credentials.encode('utf-8')).decode('utf-8') }
def get_server_api_key(self, server_uuid): # type: (Text) -> Text if server_uuid not in API_KEYS: API_KEYS[server_uuid] = get_remote_server_by_uuid(server_uuid).api_key return API_KEYS[server_uuid]