Beispiel #1
0
def social_associate_user_helper(backend: BaseAuth, return_data: Dict[str, Any],
                                 *args: Any, **kwargs: Any) -> Optional[UserProfile]:
    """Responsible for doing the Zulip-account lookup and validation parts
    of the Zulip Social auth pipeline (similar to the authenticate()
    methods in most other auth backends in this file).
    """
    subdomain = backend.strategy.session_get('subdomain')
    realm = get_realm(subdomain)
    if realm is None:
        return_data["invalid_realm"] = True
        return None
    return_data["realm"] = realm

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

    if 'auth_failed_reason' in kwargs.get('response', {}):
        return_data["social_auth_failed_reason"] = kwargs['response']["auth_failed_reason"]
        return None
    elif hasattr(backend, 'get_validated_email'):
        # Some social backends, like GitHubAuthBackend, don't guarantee that
        # the `details` data is validated.
        validated_email = backend.get_validated_email(*args, **kwargs)
    else:  # nocoverage
        # This code path isn't used by GitHubAuthBackend
        validated_email = kwargs["details"].get("email")

    if not validated_email:  # nocoverage
        # This code path isn't used with GitHubAuthBackend, but may be relevant for other
        # social auth backends.
        return_data['invalid_email'] = True
        return None
    try:
        validate_email(validated_email)
    except ValidationError:
        return_data['invalid_email'] = True
        return None

    return_data["valid_attestation"] = True
    return_data['validated_email'] = validated_email
    user_profile = common_get_active_user(validated_email, realm, return_data)

    if 'fullname' in kwargs["details"]:
        return_data["full_name"] = kwargs["details"]["fullname"]
    else:
        # If we add support for any of the social auth backends that
        # don't provide this feature, we'll need to add code here.
        raise AssertionError("Social auth backend doesn't provide fullname")

    return user_profile
Beispiel #2
0
def social_associate_user_helper(backend: BaseAuth, return_data: Dict[str, Any],
                                 *args: Any, **kwargs: Any) -> Optional[UserProfile]:
    """Responsible for doing the Zulip-account lookup and validation parts
    of the Zulip Social auth pipeline (similar to the authenticate()
    methods in most other auth backends in this file).

    Returns a UserProfile object for successful authentication, and None otherwise.
    """
    subdomain = backend.strategy.session_get('subdomain')
    realm = get_realm(subdomain)
    if realm is None:
        return_data["invalid_realm"] = True
        return None
    return_data["realm_id"] = realm.id

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

    if 'auth_failed_reason' in kwargs.get('response', {}):
        return_data["social_auth_failed_reason"] = kwargs['response']["auth_failed_reason"]
        return None
    elif hasattr(backend, 'get_verified_emails'):
        # Some social backends, like GitHubAuthBackend, don't
        # guarantee that the `details` data is validated (i.e., it's
        # possible users can put any string they want in the "email"
        # field of the `details` object).  For those backends, we have
        # custom per-backend code to properly fetch only verified
        # email addresses from the appropriate third-party API.
        verified_emails = backend.get_verified_emails(*args, **kwargs)
        if len(verified_emails) == 0:
            # TODO: Provide a nice error message screen to the user
            # for this case, rather than just logging a warning.
            logging.warning("Social auth (%s) failed because user has no verified emails" %
                            (backend.auth_backend_name,))
            return_data["email_not_verified"] = True
            return None
        # TODO: ideally, we'd prompt the user for which email they
        # want to use with another pipeline stage here.
        validated_email = verified_emails[0]
    else:  # nocoverage
        # This code path isn't used by GitHubAuthBackend
        validated_email = kwargs["details"].get("email")

    if not validated_email:  # nocoverage
        # This code path isn't used with GitHubAuthBackend, but may be relevant for other
        # social auth backends.
        return_data['invalid_email'] = True
        return None
    try:
        validate_email(validated_email)
    except ValidationError:
        return_data['invalid_email'] = True
        return None

    return_data["valid_attestation"] = True
    return_data['validated_email'] = validated_email
    user_profile = common_get_active_user(validated_email, realm, return_data)

    if 'fullname' in kwargs["details"]:
        return_data["full_name"] = kwargs["details"]["fullname"]
    else:
        # If we add support for any of the social auth backends that
        # don't provide this feature, we'll need to add code here.
        raise AssertionError("Social auth backend doesn't provide fullname")

    return user_profile
Beispiel #3
0
def social_associate_user_helper(backend: BaseAuth,
                                 return_data: Dict[str, Any], *args: Any,
                                 **kwargs: Any) -> Optional[UserProfile]:
    """Responsible for doing the Zulip-account lookup and validation parts
    of the Zulip Social auth pipeline (similar to the authenticate()
    methods in most other auth backends in this file).
    """
    subdomain = backend.strategy.session_get('subdomain')
    realm = get_realm(subdomain)
    if realm is None:
        return_data["invalid_realm"] = True
        return None
    return_data["realm_id"] = realm.id

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

    if 'auth_failed_reason' in kwargs.get('response', {}):
        return_data["social_auth_failed_reason"] = kwargs['response'][
            "auth_failed_reason"]
        return None
    elif hasattr(backend, 'get_verified_emails'):
        # Some social backends, like GitHubAuthBackend, don't guarantee that
        # the `details` data is validated.
        verified_emails = backend.get_verified_emails(*args, **kwargs)
        if len(verified_emails) == 0:
            # TODO: Provide a nice error message screen to the user
            # for this case, rather than just logging a warning.
            logging.warning(
                "Social auth (%s) failed because user has no verified emails" %
                (backend.auth_backend_name, ))
            return_data["email_not_verified"] = True
            return None
        # TODO: ideally, we'd prompt the user for which email they
        # want to use with another pipeline stage here.
        validated_email = verified_emails[0]
    else:  # nocoverage
        # This code path isn't used by GitHubAuthBackend
        validated_email = kwargs["details"].get("email")

    if not validated_email:  # nocoverage
        # This code path isn't used with GitHubAuthBackend, but may be relevant for other
        # social auth backends.
        return_data['invalid_email'] = True
        return None
    try:
        validate_email(validated_email)
    except ValidationError:
        return_data['invalid_email'] = True
        return None

    return_data["valid_attestation"] = True
    return_data['validated_email'] = validated_email
    user_profile = common_get_active_user(validated_email, realm, return_data)

    if 'fullname' in kwargs["details"]:
        return_data["full_name"] = kwargs["details"]["fullname"]
    else:
        # If we add support for any of the social auth backends that
        # don't provide this feature, we'll need to add code here.
        raise AssertionError("Social auth backend doesn't provide fullname")

    return user_profile
Beispiel #4
0
def social_associate_user_helper(backend: BaseAuth, return_data: Dict[str, Any],
                                 *args: Any, **kwargs: Any) -> Optional[UserProfile]:
    """Responsible for doing the Zulip-account lookup and validation parts
    of the Zulip Social auth pipeline (similar to the authenticate()
    methods in most other auth backends in this file).

    Returns a UserProfile object for successful authentication, and None otherwise.
    """
    subdomain = backend.strategy.session_get('subdomain')
    try:
        realm = get_realm(subdomain)
    except Realm.DoesNotExist:
        return_data["invalid_realm"] = True
        return None
    return_data["realm_id"] = realm.id

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

    if 'auth_failed_reason' in kwargs.get('response', {}):
        return_data["social_auth_failed_reason"] = kwargs['response']["auth_failed_reason"]
        return None
    elif hasattr(backend, 'get_verified_emails'):
        # Some social backends, like GitHubAuthBackend, don't
        # guarantee that the `details` data is validated (i.e., it's
        # possible users can put any string they want in the "email"
        # field of the `details` object).  For those backends, we have
        # custom per-backend code to properly fetch only verified
        # email addresses from the appropriate third-party API.
        verified_emails = backend.get_verified_emails(*args, **kwargs)
        verified_emails_length = len(verified_emails)
        if verified_emails_length == 0:
            # TODO: Provide a nice error message screen to the user
            # for this case, rather than just logging a warning.
            logging.warning("Social auth (%s) failed because user has no verified emails" %
                            (backend.auth_backend_name,))
            return_data["email_not_verified"] = True
            return None

        if verified_emails_length == 1:
            chosen_email = verified_emails[0]
        else:
            chosen_email = backend.strategy.request_data().get('email')

        if not chosen_email:
            return render(backend.strategy.request, 'zerver/social_auth_select_email.html', context = {
                'primary_email': verified_emails[0],
                'verified_non_primary_emails': verified_emails[1:],
                'backend': 'github'
            })

        try:
            validate_email(chosen_email)
        except ValidationError:
            return_data['invalid_email'] = True
            return None

        if chosen_email not in verified_emails:
            # If a user edits the submit value for the choose email form, we might
            # end up with a wrong email associated with the account. The below code
            # takes care of that.
            logging.warning("Social auth (%s) failed because user has no verified"
                            " emails associated with the account" %
                            (backend.auth_backend_name,))
            return_data["email_not_associated"] = True
            return None

        validated_email = chosen_email
    else:  # nocoverage
        # This code path isn't used by GitHubAuthBackend
        validated_email = kwargs["details"].get("email")

    if not validated_email:  # nocoverage
        # This code path isn't used with GitHubAuthBackend, but may be relevant for other
        # social auth backends.
        return_data['invalid_email'] = True
        return None

    return_data["valid_attestation"] = True
    return_data['validated_email'] = validated_email
    user_profile = common_get_active_user(validated_email, realm, return_data)

    if 'fullname' in kwargs["details"]:
        return_data["full_name"] = kwargs["details"]["fullname"]
    else:
        # If we add support for any of the social auth backends that
        # don't provide this feature, we'll need to add code here.
        raise AssertionError("Social auth backend doesn't provide fullname")

    return user_profile