Exemple #1
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 deactivated. "
                u"Please contact your organization administrator to reactivate it. "
                u"If you're not sure who that is, try contacting %s.") % (
                    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
Exemple #2
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 InvalidZulipServerError(role)
        if api_key != remote_server.api_key:
            raise InvalidZulipServerKeyError(role)

        if not check_subdomain(get_subdomain(request), ""):
            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
Exemple #3
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
Exemple #4
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 = 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)
Exemple #5
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
Exemple #6
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
Exemple #7
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)
Exemple #8
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
Exemple #9
0
 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]
     assert username is not None
     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):
             if return_data is not None:
                 return_data["invalid_subdomain"] = True
             return None
         return user_profile
     return None
Exemple #10
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
Exemple #11
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 (%s) attempted to access API on wrong subdomain (%s)" % (
            user_profile.email, user_profile.realm.subdomain, get_subdomain(request)))
        raise JsonableError(_("Account is not associated with this subdomain"))