示例#1
0
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
示例#2
0
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
示例#3
0
文件: forms.py 项目: christi3k/zulip
    def send_mail(self, subject_template_name, email_template_name,
                  context, from_email, to_email, html_email_template_name=None):
        # type: (str, str, Dict[str, Any], str, str, str) -> None
        """
        Currently we don't support accounts in multiple subdomains using
        a single email addresss. We override this function so that we do
        not send a reset link to an email address if the reset attempt is
        done on the subdomain which does not match user.realm.subdomain.

        Once we start supporting accounts with the same email in
        multiple subdomains, we may be able to delete or refactor this
        function.
        """
        user_realm = get_user_profile_by_email(to_email).realm
        attempted_subdomain = get_subdomain(getattr(self, 'request'))
        context['attempted_realm'] = False
        if not check_subdomain(user_realm.subdomain, attempted_subdomain):
            context['attempted_realm'] = get_realm(attempted_subdomain)

        super(ZulipPasswordResetForm, self).send_mail(
            subject_template_name,
            email_template_name,
            context,
            from_email,
            to_email,
            html_email_template_name=html_email_template_name
        )
示例#4
0
    def authenticate(self, username=None, password=None, realm_subdomain=None, return_data=None):
        # type: (Optional[Text], Optional[str], Optional[Text], Optional[Dict[str, Any]]) -> Optional[UserProfile]
        """ Authenticate a user based on email address as the user name. """
        if username is None or password is None:
            # Return immediately.  Otherwise we will look for a SQL row with
            # NULL username.  While that's probably harmless, it's needless
            # exposure.
            return None

        user_profile = common_get_active_user_by_email(username, return_data=return_data)
        if user_profile is None:
            return None
        if not password_auth_enabled(user_profile.realm):
            if return_data is not None:
                return_data['password_auth_disabled'] = True
            return None
        if not email_auth_enabled(user_profile.realm):
            if return_data is not None:
                return_data['email_auth_disabled'] = True
            return None
        if user_profile.check_password(password):
            if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
                if return_data is not None:
                    return_data["invalid_subdomain"] = True
                return None
            return user_profile
        return None
示例#5
0
    def clean_username(self):
        # type: () -> str
        email = self.cleaned_data['username']
        try:
            user_profile = get_user_profile_by_email(email)
        except UserProfile.DoesNotExist:
            return email

        if user_profile.realm.deactivated:
            error_msg = u"""Sorry for the trouble, but %s has been deactivated.

Please contact %s to reactivate this group.""" % (user_profile.realm.name,
                                                  FromAddress.SUPPORT)
            raise ValidationError(mark_safe(error_msg))

        if not user_profile.is_active and not user_profile.is_mirror_dummy:
            error_msg = (u"Sorry for the trouble, but your account has been "
                         u"deactivated. Please contact %s to reactivate "
                         u"it.") % (FromAddress.SUPPORT, )
            raise ValidationError(mark_safe(error_msg))

        if not check_subdomain(get_subdomain(self.request),
                               user_profile.realm.subdomain):
            logging.warning(
                "User %s attempted to password login to wrong subdomain %s" %
                (user_profile.email, get_subdomain(self.request)))
            raise ValidationError(mark_safe(WRONG_SUBDOMAIN_ERROR))
        return email
示例#6
0
    def send_mail(self,
                  subject_template_name,
                  email_template_name,
                  context,
                  from_email,
                  to_email,
                  html_email_template_name=None):
        # type: (str, str, Dict[str, Any], str, str, str) -> None
        """
        Currently we don't support accounts in multiple subdomains using
        a single email address. We override this function so that we do
        not send a reset link to an email address if the reset attempt is
        done on the subdomain which does not match user.realm.subdomain.

        Once we start supporting accounts with the same email in
        multiple subdomains, we may be able to refactor this function.

        A second reason we override this function is so that we can send
        the mail through the functions in zerver.lib.send_email, to match
        how we send all other mail in the codebase.
        """
        user_realm = get_user_profile_by_email(to_email).realm
        attempted_subdomain = get_subdomain(getattr(self, 'request'))
        context['attempted_realm'] = False
        if not check_subdomain(user_realm.subdomain, attempted_subdomain):
            context['attempted_realm'] = get_realm(attempted_subdomain)

        send_email('zerver/emails/password_reset', to_email, context=context)
示例#7
0
    def authenticate(self, google_oauth2_token=None, realm_subdomain=None, return_data=None):
        # type: (Optional[str], Optional[Text], Optional[Dict[str, Any]]) -> Optional[UserProfile]
        if return_data is None:
            return_data = {}

        try:
            token_payload = googleapiclient.verify_id_token(google_oauth2_token, settings.GOOGLE_CLIENT_ID)
        except AppIdentityError:
            return None
        if token_payload["email_verified"] in (True, "true"):
            try:
                user_profile = get_user_profile_by_email(token_payload["email"])
            except UserProfile.DoesNotExist:
                return_data["valid_attestation"] = True
                return None
            if not user_profile.is_active:
                return_data["inactive_user"] = True
                return None
            if user_profile.realm.deactivated:
                return_data["inactive_realm"] = True
                return None
            if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
                return_data["invalid_subdomain"] = True
                return None
            if not google_auth_enabled(realm=user_profile.realm):
                return_data["google_auth_disabled"] = True
                return None
            return user_profile
        else:
            return_data["valid_attestation"] = False
            return None
示例#8
0
文件: forms.py 项目: yhl-python/zulip
    def send_mail(self, subject_template_name, email_template_name,
                  context, from_email, to_email, html_email_template_name=None):
        # type: (str, str, Dict[str, Any], str, str, str) -> None
        """
        Currently we don't support accounts in multiple subdomains using
        a single email address. We override this function so that we do
        not send a reset link to an email address if the reset attempt is
        done on the subdomain which does not match user.realm.subdomain.

        Once we start supporting accounts with the same email in
        multiple subdomains, we may be able to refactor this function.

        A second reason we override this function is so that we can send
        the mail through the functions in zerver.lib.send_email, to match
        how we send all other mail in the codebase.
        """
        user = get_user_profile_by_email(to_email)
        attempted_subdomain = get_subdomain(getattr(self, 'request'))
        context['attempted_realm'] = False
        if not check_subdomain(user.realm.subdomain, attempted_subdomain):
            context['attempted_realm'] = get_realm(attempted_subdomain)

        send_email('zerver/emails/password_reset', to_user_id=user.id,
                   from_name="Zulip Account Security",
                   from_address=FromAddress.NOREPLY, context=context)
示例#9
0
文件: forms.py 项目: yhl-python/zulip
    def clean_username(self):
        # type: () -> str
        email = self.cleaned_data['username']
        try:
            user_profile = get_user_profile_by_email(email)
        except UserProfile.DoesNotExist:
            return email

        if user_profile.realm.deactivated:
            error_msg = u"""Sorry for the trouble, but %s has been deactivated.

Please contact %s to reactivate this group.""" % (
                user_profile.realm.name,
                FromAddress.SUPPORT)
            raise ValidationError(mark_safe(error_msg))

        if not user_profile.is_active and not user_profile.is_mirror_dummy:
            error_msg = (u"Sorry for the trouble, but your account has been "
                         u"deactivated. Please contact %s to reactivate "
                         u"it.") % (FromAddress.SUPPORT,)
            raise ValidationError(mark_safe(error_msg))

        if not check_subdomain(get_subdomain(self.request), user_profile.realm.subdomain):
            logging.warning("User %s attempted to password login to wrong subdomain %s" %
                            (user_profile.email, get_subdomain(self.request)))
            raise ValidationError(mark_safe(WRONG_SUBDOMAIN_ERROR))
        return email
示例#10
0
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
示例#11
0
        def _wrapped_func_arguments(request, api_key=REQ(), *args, **kwargs):
            # type: (HttpRequest, Text, *Any, **Any) -> HttpResponse
            try:
                user_profile = UserProfile.objects.get(api_key=api_key)
            except UserProfile.DoesNotExist:
                raise JsonableError(_("Invalid API key"))
            if not user_profile.is_active:
                raise JsonableError(_("Account not active"))
            if user_profile.realm.deactivated:
                raise JsonableError(
                    _("Realm for account has been deactivated"))
            if not check_subdomain(get_subdomain(request),
                                   user_profile.realm.subdomain):
                logging.warning(
                    "User %s attempted to access webhook API on wrong subdomain %s"
                    % (user_profile.email, get_subdomain(request)))
                raise JsonableError(
                    _("Account is not associated with this subdomain"))

            request.user = user_profile
            request._email = user_profile.email
            webhook_client_name = "Zulip{}Webhook".format(client_name)
            process_client(request,
                           user_profile,
                           client_name=webhook_client_name)
            if settings.RATE_LIMITING:
                rate_limit_user(request, user_profile, domain='all')
            return view_func(request, user_profile, request.client, *args,
                             **kwargs)
示例#12
0
    def authenticate(self,
                     username=None,
                     password=None,
                     realm_subdomain=None,
                     return_data=None):
        # type: (Optional[Text], Optional[str], Optional[Text], Optional[Dict[str, Any]]) -> Optional[UserProfile]
        """ Authenticate a user based on email address as the user name. """
        if username is None or password is None:
            # Return immediately.  Otherwise we will look for a SQL row with
            # NULL username.  While that's probably harmless, it's needless
            # exposure.
            return None

        user_profile = common_get_active_user_by_email(username,
                                                       return_data=return_data)
        if user_profile is None:
            return None
        if not password_auth_enabled(user_profile.realm):
            if return_data is not None:
                return_data['password_auth_disabled'] = True
            return None
        if not email_auth_enabled(user_profile.realm):
            if return_data is not None:
                return_data['email_auth_disabled'] = True
            return None
        if user_profile.check_password(password):
            if not check_subdomain(realm_subdomain,
                                   user_profile.realm.subdomain):
                if return_data is not None:
                    return_data["invalid_subdomain"] = True
                return None
            return user_profile
        return None
示例#13
0
文件: backends.py 项目: umkay/zulip
    def authenticate(self, *args, **kwargs):
        # type: (*Any, **Any) -> Optional[UserProfile]
        return_data = kwargs.get('return_data', {})

        email_address = self.get_email_address(*args, **kwargs)
        if not email_address:
            return None

        try:
            user_profile = get_user_profile_by_email(email_address)
        except UserProfile.DoesNotExist:
            return_data["valid_attestation"] = True
            return None

        if not user_profile.is_active:
            return_data["inactive_user"] = True
            return None

        if user_profile.realm.deactivated:
            return_data["inactive_realm"] = True
            return None

        if not check_subdomain(kwargs.get("realm_subdomain"),
                               user_profile.realm.subdomain):
            return_data["invalid_subdomain"] = True
            return None

        return user_profile
示例#14
0
def authenticate_log_and_execute_json(request, view_func, *args, **kwargs):
    # type: (HttpRequest, Callable[..., HttpResponse], *Any, **Any) -> HttpResponse
    if not request.user.is_authenticated():
        return json_error(_("Not logged in"), status=401)
    user_profile = request.user
    if not user_profile.is_active:
        raise JsonableError(_("Account not active"))
    if user_profile.realm.deactivated:
        raise JsonableError(_("Realm for account has been deactivated"))
    if user_profile.is_incoming_webhook:
        raise JsonableError(_("Webhook bots can only access webhooks"))
    if (not check_subdomain(get_subdomain(request),
                            user_profile.realm.subdomain) and
            # Exclude the SOCKET requests from this filter; they were
            # checked when the original websocket request reached Tornado
            not (request.method == "SOCKET"
                 and request.META['SERVER_NAME'] == "127.0.0.1")):
        logging.warning(
            "User %s attempted to access JSON API on wrong subdomain %s" %
            (user_profile.email, get_subdomain(request)))
        raise JsonableError(_("Account is not associated with this subdomain"))

    process_client(request, user_profile, True)
    request._email = user_profile.email
    return rate_limit()(view_func)(request, user_profile, *args, **kwargs)
示例#15
0
    def authenticate(self, google_oauth2_token=None, realm_subdomain=None, return_data=None):
        # type: (Optional[str], Optional[Text], Optional[Dict[str, Any]]) -> Optional[UserProfile]
        if return_data is None:
            return_data = {}

        try:
            token_payload = googleapiclient.verify_id_token(google_oauth2_token, settings.GOOGLE_CLIENT_ID)
        except AppIdentityError:
            return None
        if token_payload["email_verified"] in (True, "true"):
            try:
                user_profile = get_user_profile_by_email(token_payload["email"])
            except UserProfile.DoesNotExist:
                return_data["valid_attestation"] = True
                return None
            if not user_profile.is_active:
                return_data["inactive_user"] = True
                return None
            if user_profile.realm.deactivated:
                return_data["inactive_realm"] = True
                return None
            if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
                return_data["invalid_subdomain"] = True
                return None
            if not google_auth_enabled(realm=user_profile.realm):
                return_data["google_auth_disabled"] = True
                return None
            return user_profile
        else:
            return_data["valid_attestation"] = False
            return None
示例#16
0
    def _common_authenticate(self, *args, **kwargs):
        # type: (*Any, **Any) -> Optional[UserProfile]
        return_data = kwargs.get('return_data', {})

        email_address = self.get_email_address(*args, **kwargs)
        if not email_address:
            return_data['invalid_email'] = True
            return None

        try:
            user_profile = get_user_profile_by_email(email_address)
        except UserProfile.DoesNotExist:
            return_data["valid_attestation"] = True
            return None

        if not user_profile.is_active:
            return_data["inactive_user"] = True
            return None

        if user_profile.realm.deactivated:
            return_data["inactive_realm"] = True
            return None

        if not check_subdomain(kwargs.get("realm_subdomain"),
                               user_profile.realm.subdomain):
            return_data["invalid_subdomain"] = True
            return None

        if not auth_enabled_helper([self.auth_backend_name],
                                   user_profile.realm):
            return_data["auth_backend_disabled"] = True
            return None

        return user_profile
示例#17
0
    def send_mail(self,
                  subject_template_name,
                  email_template_name,
                  context,
                  from_email,
                  to_email,
                  html_email_template_name=None):
        # type: (str, str, Dict[str, Any], str, str, str) -> None
        """
        Currently we don't support accounts in multiple subdomains using
        a single email addresss. We override this function so that we do
        not send a reset link to an email address if the reset attempt is
        done on the subdomain which does not match user.realm.subdomain.

        Once we start supporting accounts with the same email in
        multiple subdomains, we may be able to delete or refactor this
        function.
        """
        user_realm = get_user_profile_by_email(to_email).realm
        attempted_subdomain = get_subdomain(getattr(self, 'request'))
        context['attempted_realm'] = False
        if not check_subdomain(user_realm.subdomain, attempted_subdomain):
            context['attempted_realm'] = get_realm(attempted_subdomain)

        super(ZulipPasswordResetForm, self).send_mail(
            subject_template_name,
            email_template_name,
            context,
            from_email,
            to_email,
            html_email_template_name=html_email_template_name)
示例#18
0
文件: decorator.py 项目: zulip/zulip
def authenticate_log_and_execute_json(request, view_func, *args, **kwargs):
    # type: (HttpRequest, Callable[..., HttpResponse], *Any, **Any) -> HttpResponse
    if not request.user.is_authenticated():
        return json_error(_("Not logged in"), status=401)
    user_profile = request.user
    if not user_profile.is_active:
        raise JsonableError(_("Account not active"))
    if user_profile.realm.deactivated:
        raise JsonableError(_("Realm for account has been deactivated"))
    if user_profile.is_incoming_webhook:
        raise JsonableError(_("Webhook bots can only access webhooks"))
    if (
        not check_subdomain(get_subdomain(request), user_profile.realm.subdomain)
        and
        # Exclude the SOCKET requests from this filter; they were
        # checked when the original websocket request reached Tornado
        not (request.method == "SOCKET" and request.META["SERVER_NAME"] == "127.0.0.1")
    ):
        logging.warning(
            "User %s attempted to access JSON API on wrong subdomain %s" % (user_profile.email, get_subdomain(request))
        )
        raise JsonableError(_("Account is not associated with this subdomain"))

    process_client(request, user_profile, True)
    request._email = user_profile.email
    return view_func(request, user_profile, *args, **kwargs)
示例#19
0
def logged_in_and_active(request):
    # type: (HttpRequest) -> bool
    if not request.user.is_authenticated:
        return False
    if not request.user.is_active:
        return False
    if request.user.realm.deactivated:
        return False
    return check_subdomain(get_subdomain(request), request.user.realm.subdomain)
示例#20
0
def logged_in_and_active(request):
    # type: (HttpRequest) -> bool
    if not request.user.is_authenticated():
        return False
    if not request.user.is_active:
        return False
    if request.user.realm.deactivated:
        return False
    return check_subdomain(get_subdomain(request), request.user.realm.subdomain)
示例#21
0
        def _wrapped_func_arguments(request, api_key=REQ(), *args, **kwargs):
            # type: (HttpRequest, Text, *Any, **Any) -> HttpResponse
            try:
                user_profile = UserProfile.objects.get(api_key=api_key)
            except UserProfile.DoesNotExist:
                raise JsonableError(_("Invalid API key"))
            if not user_profile.is_active:
                raise JsonableError(_("Account not active"))
            if user_profile.realm.deactivated:
                raise JsonableError(
                    _("Realm for account has been deactivated"))
            if not check_subdomain(get_subdomain(request),
                                   user_profile.realm.subdomain):
                logging.warning(
                    "User %s attempted to access webhook API on wrong subdomain %s"
                    % (user_profile.email, get_subdomain(request)))
                raise JsonableError(
                    _("Account is not associated with this subdomain"))

            request.user = user_profile
            request._email = user_profile.email
            webhook_client_name = "Zulip{}Webhook".format(client_name)
            process_client(request,
                           user_profile,
                           client_name=webhook_client_name)
            if settings.RATE_LIMITING:
                rate_limit_user(request, user_profile, domain='all')
            try:
                return view_func(request, user_profile, *args, **kwargs)
            except Exception as err:
                if request.content_type == 'application/json':
                    try:
                        request_body = ujson.dumps(ujson.loads(request.body),
                                                   indent=4)
                    except ValueError:
                        request_body = str(request.body)
                else:
                    request_body = str(request.body)
                message = """
user: {email} ({realm})
client: {client_name}
URL: {path_info}
content_type: {content_type}
body:

{body}
                """.format(
                    email=user_profile.email,
                    realm=user_profile.realm.string_id,
                    client_name=webhook_client_name,
                    body=request_body,
                    path_info=request.META.get('PATH_INFO', None),
                    content_type=request.content_type,
                )
                webhook_logger.exception(message)
                raise err
示例#22
0
文件: backends.py 项目: umkay/zulip
    def authenticate(self, remote_user, realm_subdomain=None):
        # type: (str, Optional[text_type]) -> Optional[UserProfile]
        if not remote_user:
            return None

        email = remote_user_to_email(remote_user)
        user = common_get_active_user_by_email(email)
        if user is not None and check_subdomain(realm_subdomain, user.realm.subdomain):
            return user
        return None
示例#23
0
    def authenticate(self, remote_user, realm_subdomain=None):
        # type: (str, Optional[text_type]) -> Optional[UserProfile]
        if not remote_user:
            return None

        email = remote_user_to_email(remote_user)
        user = common_get_active_user_by_email(email)
        if user is not None and check_subdomain(realm_subdomain, user.realm.subdomain):
            return user
        return None
示例#24
0
文件: backends.py 项目: zulip/zulip
 def authenticate(self, username=None, realm_subdomain=None, use_dummy_backend=False, return_data=None):
     # type: (Optional[Text], Optional[Text], bool, Optional[Dict[str, Any]]) -> Optional[UserProfile]
     if use_dummy_backend:
         user_profile = common_get_active_user_by_email(username)
         if user_profile is None:
             return None
         if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
             return_data["invalid_subdomain"] = True
             return None
         return user_profile
     return None
示例#25
0
 def authenticate(self, username=None, realm_subdomain=None, use_dummy_backend=False,
                  return_data=None):
     # type: (Optional[text_type], Optional[text_type], bool, Optional[Dict[str, Any]]) -> Optional[UserProfile]
     if use_dummy_backend:
         user_profile = common_get_active_user_by_email(username)
         if user_profile is None:
             return None
         if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
             return_data["invalid_subdomain"] = True
             return None
         return user_profile
     return None
示例#26
0
        def _wrapped_func_arguments(request, api_key=REQ(),
                                    *args, **kwargs):
            # type: (HttpRequest, Text, *Any, **Any) -> HttpResponse
            try:
                user_profile = UserProfile.objects.get(api_key=api_key)
            except UserProfile.DoesNotExist:
                raise JsonableError(_("Invalid API key"))
            if not user_profile.is_active:
                raise JsonableError(_("Account not active"))
            if user_profile.realm.deactivated:
                raise JsonableError(_("Realm for account has been deactivated"))
            if not check_subdomain(get_subdomain(request), user_profile.realm.subdomain):
                logging.warning("User %s attempted to access webhook API on wrong subdomain %s" % (
                    user_profile.email, get_subdomain(request)))
                raise JsonableError(_("Account is not associated with this subdomain"))

            request.user = user_profile
            request._email = user_profile.email
            webhook_client_name = "Zulip{}Webhook".format(client_name)
            process_client(request, user_profile, client_name=webhook_client_name)
            if settings.RATE_LIMITING:
                rate_limit_user(request, user_profile, domain='all')
            try:
                return view_func(request, user_profile, *args, **kwargs)
            except Exception as err:
                if request.content_type == 'application/json':
                    try:
                        request_body = ujson.dumps(ujson.loads(request.body), indent=4)
                    except ValueError:
                        request_body = str(request.body)
                else:
                    request_body = str(request.body)
                message = """
user: {email} ({realm})
client: {client_name}
URL: {path_info}
content_type: {content_type}
body:

{body}
                """.format(
                    email=user_profile.email,
                    realm=user_profile.realm.string_id,
                    client_name=webhook_client_name,
                    body=request_body,
                    path_info=request.META.get('PATH_INFO', None),
                    content_type=request.content_type,
                )
                webhook_logger.exception(message)
                raise err
示例#27
0
 def authenticate(self, username, password, realm_subdomain=None, return_data=None):
     # type: (text_type, str, Optional[text_type], Optional[Dict[str, Any]]) -> Optional[UserProfile]
     try:
         username = self.django_to_ldap_username(username)
         user_profile = ZulipLDAPAuthBackendBase.authenticate(self, username, password)
         if user_profile is None:
             return None
         if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
             return None
         return user_profile
     except Realm.DoesNotExist:
         return None
     except ZulipLDAPException:
         return None
示例#28
0
    def authenticate(self, remote_user, realm_subdomain=None):
        # type: (str, Optional[Text]) -> Optional[UserProfile]
        if not remote_user:
            return None

        email = remote_user_to_email(remote_user)
        user_profile = common_get_active_user_by_email(email)
        if user_profile is None:
            return None
        if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
            return None
        if not auth_enabled_helper([u"RemoteUser"], user_profile.realm):
            return None
        return user_profile
示例#29
0
    def authenticate(self, remote_user, realm_subdomain=None):
        # type: (Optional[str], Optional[Text]) -> Optional[UserProfile]
        if not remote_user:
            return None

        email = remote_user_to_email(remote_user)
        user_profile = common_get_active_user_by_email(email)
        if user_profile is None:
            return None
        if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
            return None
        if not auth_enabled_helper([u"RemoteUser"], user_profile.realm):
            return None
        return user_profile
示例#30
0
文件: backends.py 项目: umkay/zulip
 def authenticate(self, username, password, realm_subdomain=None, return_data=None):
     # type: (text_type, str, Optional[text_type], Optional[Dict[str, Any]]) -> Optional[str]
     try:
         username = self.django_to_ldap_username(username)
         user_profile = ZulipLDAPAuthBackendBase.authenticate(self, username, password)
         if user_profile is None:
             return None
         if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
             return None
         return user_profile
     except Realm.DoesNotExist:
         return None
     except ZulipLDAPException:
         return None
示例#31
0
 def authenticate(self, username, password, realm_subdomain=None, return_data=None):
     # type: (Text, str, Optional[Text], Optional[Dict[str, Any]]) -> Optional[UserProfile]
     try:
         self._realm = get_realm(realm_subdomain)
         username = self.django_to_ldap_username(username)
         user_profile = ZulipLDAPAuthBackendBase.authenticate(self,
                                                              username=username,
                                                              password=password)
         if user_profile is None:
             return None
         if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
             return None
         return user_profile
     except Realm.DoesNotExist:
         return None  # nocoverage # TODO: this may no longer be possible
     except ZulipLDAPException:
         return None  # nocoverage # TODO: this may no longer be possible
示例#32
0
 def authenticate(self, username, password, realm_subdomain=None, return_data=None):
     # type: (Text, str, Optional[Text], Optional[Dict[str, Any]]) -> Optional[UserProfile]
     try:
         if settings.REALMS_HAVE_SUBDOMAINS:
             self._realm = get_realm(realm_subdomain)
         else:
             self._realm = get_realm_by_email_domain(username)
         username = self.django_to_ldap_username(username)
         user_profile = ZulipLDAPAuthBackendBase.authenticate(self, username, password)
         if user_profile is None:
             return None
         if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
             return None
         return user_profile
     except Realm.DoesNotExist:
         return None
     except ZulipLDAPException:
         return None
示例#33
0
 def authenticate(self, username, password, realm_subdomain=None, return_data=None):
     # type: (Text, str, Optional[Text], Optional[Dict[str, Any]]) -> Optional[UserProfile]
     try:
         if settings.REALMS_HAVE_SUBDOMAINS:
             self._realm = get_realm(realm_subdomain)
         else:
             self._realm = get_realm_by_email_domain(username)
         username = self.django_to_ldap_username(username)
         user_profile = ZulipLDAPAuthBackendBase.authenticate(self, username, password)
         if user_profile is None:
             return None
         if not check_subdomain(realm_subdomain, user_profile.realm.subdomain):
             return None
         return user_profile
     except Realm.DoesNotExist:
         return None
     except ZulipLDAPException:
         return None
示例#34
0
文件: decorator.py 项目: zulip/zulip
def validate_api_key(request, role, api_key, is_webhook=False):
    # type: (HttpRequest, text_type, text_type, bool) -> Union[UserProfile, Deployment]
    # Remove whitespace to protect users from trivial errors.
    role, api_key = role.strip(), api_key.strip()

    try:
        profile = get_deployment_or_userprofile(role)
    except UserProfile.DoesNotExist:
        raise JsonableError(_("Invalid user: %s") % (role,))
    except Deployment.DoesNotExist:
        raise JsonableError(_("Invalid deployment: %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,))
    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"))
    try:
        if profile.realm.deactivated:
            raise JsonableError(_("Realm for account has been deactivated"))
    except AttributeError:
        # Deployment objects don't have realms
        pass
    if (
        not check_subdomain(get_subdomain(request), profile.realm.subdomain)
        # Allow access to localhost for Tornado
        and 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
示例#35
0
def validate_api_key(request, role, api_key, is_webhook=False):
    # type: (HttpRequest, Text, Text, bool) -> Union[UserProfile, Deployment]
    # Remove whitespace to protect users from trivial errors.
    role, api_key = role.strip(), api_key.strip()

    try:
        profile = get_deployment_or_userprofile(role)
    except UserProfile.DoesNotExist:
        raise JsonableError(_("Invalid user: %s") % (role, ))
    except Deployment.DoesNotExist:
        raise JsonableError(_("Invalid deployment: %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, ))
    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"))
    try:
        if profile.realm.deactivated:
            raise JsonableError(_("Realm for account has been deactivated"))
    except AttributeError:
        # Deployment objects don't have realms
        pass
    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
示例#36
0
    def clean_username(self):
        # type: () -> str
        email = self.cleaned_data['username']
        try:
            user_profile = get_user_profile_by_email(email)
        except UserProfile.DoesNotExist:
            return email

        if user_profile.realm.deactivated:
            error_msg = u"""Sorry for the trouble, but %s has been deactivated.

Please contact %s to reactivate this group.""" % (
                user_profile.realm.name,
                settings.ZULIP_ADMINISTRATOR)
            raise ValidationError(mark_safe(error_msg))

        if not check_subdomain(get_subdomain(self.request), user_profile.realm.subdomain):
            logging.warning("User %s attempted to password login to wrong subdomain %s" %
                            (user_profile.email, get_subdomain(self.request)))
            raise ValidationError(mark_safe(WRONG_SUBDOMAIN_ERROR))
        return email
示例#37
0
def validate_account_and_subdomain(request, user_profile):
    # type: (HttpRequest, UserProfile) -> None
    if not user_profile.is_active:
        raise JsonableError(_("Account not active"))

    if user_profile.realm.deactivated:
        raise JsonableError(_("Realm for account has been deactivated"))

    # Either the subdomain matches, or processing a websockets message
    # in the message_sender worker (which will have already had the
    # subdomain validated), or we're accessing Tornado from and to
    # localhost (aka spoofing a request as the user).
    if (not check_subdomain(get_subdomain(request), user_profile.realm.subdomain) and
        not (request.method == "SOCKET" and
             request.META['SERVER_NAME'] == "127.0.0.1") and
        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" % (
            user_profile.email, get_subdomain(request)))
        raise JsonableError(_("Account is not associated with this subdomain"))
示例#38
0
文件: forms.py 项目: Jianchun1/zulip
    def clean_username(self):
        # type: () -> str
        email = self.cleaned_data['username']
        try:
            user_profile = get_user_profile_by_email(email)
        except UserProfile.DoesNotExist:
            return email

        if user_profile.realm.deactivated:
            error_msg = u"""Sorry for the trouble, but %s has been deactivated.

Please contact %s to reactivate this group.""" % (
                user_profile.realm.name,
                settings.ZULIP_ADMINISTRATOR)
            raise ValidationError(mark_safe(error_msg))

        if not check_subdomain(get_subdomain(self.request), user_profile.realm.subdomain):
            logging.warning("User %s attempted to password login to wrong subdomain %s" %
                            (user_profile.email, get_subdomain(self.request)))
            raise ValidationError(mark_safe(WRONG_SUBDOMAIN_ERROR))
        return email
示例#39
0
        def _wrapped_func_arguments(request, api_key=REQ(),
                                    *args, **kwargs):
            # type: (HttpRequest, text_type, *Any, **Any) -> HttpResponse
            try:
                user_profile = UserProfile.objects.get(api_key=api_key)
            except UserProfile.DoesNotExist:
                raise JsonableError(_("Invalid API key"))
            if not user_profile.is_active:
                raise JsonableError(_("Account not active"))
            if user_profile.realm.deactivated:
                raise JsonableError(_("Realm for account has been deactivated"))
            if not check_subdomain(get_subdomain(request), user_profile.realm.subdomain):
                logging.warning("User %s attempted to access webhook API on wrong subdomain %s" % (
                    user_profile.email, get_subdomain(request)))
                raise JsonableError(_("Account is not associated with this subdomain"))

            request.user = user_profile
            request._email = user_profile.email
            webhook_client_name = "Zulip{}Webhook".format(client_name)
            process_client(request, user_profile, client_name=webhook_client_name)
            if settings.RATE_LIMITING:
                rate_limit_user(request, user_profile, domain='all')
            return view_func(request, user_profile, request.client, *args, **kwargs)