Ejemplo n.º 1
0
def oauth_redirect_to_root(request: HttpRequest, url: str,
                           sso_type: str, is_signup: bool=False,
                           extra_url_params: Dict[str, str]={}) -> HttpResponse:
    main_site_uri = settings.ROOT_DOMAIN_URI + url
    if settings.SOCIAL_AUTH_SUBDOMAIN is not None and sso_type == 'social':
        main_site_uri = (settings.EXTERNAL_URI_SCHEME +
                         settings.SOCIAL_AUTH_SUBDOMAIN +
                         "." +
                         settings.EXTERNAL_HOST) + url

    params = {
        'subdomain': get_subdomain(request),
        'is_signup': '1' if is_signup else '0',
    }

    params['multiuse_object_key'] = request.GET.get('multiuse_object_key', '')

    # mobile_flow_otp is a one-time pad provided by the app that we
    # can use to encrypt the API key when passing back to the app.
    mobile_flow_otp = request.GET.get('mobile_flow_otp')
    desktop_flow_otp = request.GET.get('desktop_flow_otp')

    validate_otp_params(mobile_flow_otp, desktop_flow_otp)
    if mobile_flow_otp is not None:
        params['mobile_flow_otp'] = mobile_flow_otp
    if desktop_flow_otp is not None:
        params['desktop_flow_otp'] = desktop_flow_otp

    next = request.GET.get('next')
    if next:
        params['next'] = next

    params = {**params, **extra_url_params}

    return redirect(main_site_uri + '?' + urllib.parse.urlencode(params))
Ejemplo n.º 2
0
def remote_user_sso(
        request: HttpRequest,
        mobile_flow_otp: Optional[str] = REQ(default=None),
        desktop_flow_otp: Optional[str] = REQ(default=None),
        next: str = REQ(default="/"),
) -> HttpResponse:
    subdomain = get_subdomain(request)
    try:
        realm: Optional[Realm] = get_realm(subdomain)
    except Realm.DoesNotExist:
        realm = None

    if not auth_enabled_helper([ZulipRemoteUserBackend.auth_backend_name],
                               realm):
        return config_error(request, "remote_user_backend_disabled")

    try:
        remote_user = request.META["REMOTE_USER"]
    except KeyError:
        return config_error(request, "remote_user_header_missing")

    # Django invokes authenticate methods by matching arguments, and this
    # authentication flow will not invoke LDAP authentication because of
    # this condition of Django so no need to check if LDAP backend is
    # enabled.
    validate_login_email(remote_user_to_email(remote_user))

    # Here we support the mobile and desktop flow for REMOTE_USER_BACKEND; we
    # validate the data format and then pass it through to
    # login_or_register_remote_user if appropriate.
    validate_otp_params(mobile_flow_otp, desktop_flow_otp)

    if realm is None:
        user_profile = None
    else:
        user_profile = authenticate(remote_user=remote_user, realm=realm)
    if user_profile is not None:
        assert isinstance(user_profile, UserProfile)

    email = remote_user_to_email(remote_user)
    data_dict = ExternalAuthDataDict(
        email=email,
        mobile_flow_otp=mobile_flow_otp,
        desktop_flow_otp=desktop_flow_otp,
        redirect_to=next,
    )
    if realm:
        data_dict["subdomain"] = realm.subdomain
    else:
        data_dict["subdomain"] = ""  # realm creation happens on root subdomain
    result = ExternalAuthResult(user_profile=user_profile, data_dict=data_dict)
    return login_or_register_remote_user(request, result)
Ejemplo n.º 3
0
def remote_user_sso(
    request: HttpRequest,
    mobile_flow_otp: Optional[str] = REQ(default=None),
    desktop_flow_otp: Optional[str] = REQ(default=None)
) -> HttpResponse:
    subdomain = get_subdomain(request)
    try:
        realm = get_realm(subdomain)  # type: Optional[Realm]
    except Realm.DoesNotExist:
        realm = None

    if not auth_enabled_helper([ZulipRemoteUserBackend.auth_backend_name],
                               realm):
        return redirect_to_config_error("remoteuser/backend_disabled")

    try:
        remote_user = request.META["REMOTE_USER"]
    except KeyError:
        return redirect_to_config_error(
            "remoteuser/remote_user_header_missing")

    # Django invokes authenticate methods by matching arguments, and this
    # authentication flow will not invoke LDAP authentication because of
    # this condition of Django so no need to check if LDAP backend is
    # enabled.
    validate_login_email(remote_user_to_email(remote_user))

    # Here we support the mobile and desktop flow for REMOTE_USER_BACKEND; we
    # validate the data format and then pass it through to
    # login_or_register_remote_user if appropriate.
    validate_otp_params(mobile_flow_otp, desktop_flow_otp)

    subdomain = get_subdomain(request)
    if realm is None:
        user_profile = None
    else:
        user_profile = authenticate(remote_user=remote_user, realm=realm)

    redirect_to = request.GET.get('next', '')

    return login_or_register_remote_user(request,
                                         remote_user,
                                         user_profile,
                                         mobile_flow_otp=mobile_flow_otp,
                                         desktop_flow_otp=desktop_flow_otp,
                                         realm=realm,
                                         redirect_to=redirect_to)
Ejemplo n.º 4
0
def oauth_redirect_to_root(
    request: HttpRequest,
    url: str,
    sso_type: str,
    is_signup: bool = False,
    extra_url_params: Dict[str, str] = {},
    next: Optional[str] = REQ(default=None),
) -> HttpResponse:
    main_site_uri = settings.ROOT_DOMAIN_URI + url
    if settings.SOCIAL_AUTH_SUBDOMAIN is not None and sso_type == "social":
        main_site_uri = (
            settings.EXTERNAL_URI_SCHEME
            + settings.SOCIAL_AUTH_SUBDOMAIN
            + "."
            + settings.EXTERNAL_HOST
        ) + url

    params = {
        "subdomain": get_subdomain(request),
        "is_signup": "1" if is_signup else "0",
    }

    params["multiuse_object_key"] = request.GET.get("multiuse_object_key", "")

    # mobile_flow_otp is a one-time pad provided by the app that we
    # can use to encrypt the API key when passing back to the app.
    mobile_flow_otp = request.GET.get("mobile_flow_otp")
    desktop_flow_otp = request.GET.get("desktop_flow_otp")

    validate_otp_params(mobile_flow_otp, desktop_flow_otp)
    if mobile_flow_otp is not None:
        params["mobile_flow_otp"] = mobile_flow_otp
    if desktop_flow_otp is not None:
        params["desktop_flow_otp"] = desktop_flow_otp

    if next:
        params["next"] = next

    params = {**params, **extra_url_params}

    return redirect(add_query_to_redirect_url(main_site_uri, urllib.parse.urlencode(params)))