Ejemplo n.º 1
0
    def process_do_auth(self, user_profile, *args, **kwargs):
        # type: (UserProfile, *Any, **Any) -> Optional[HttpResponse]
        # This function needs to be imported from here due to the cyclic
        # dependency.
        from zerver.views.auth import login_or_register_remote_user, redirect_to_subdomain_login_url
        from zerver.views import redirect_and_log_into_subdomain

        return_data = kwargs.get("return_data", {})

        inactive_user = return_data.get("inactive_user")
        inactive_realm = return_data.get("inactive_realm")
        invalid_subdomain = return_data.get("invalid_subdomain")

        if inactive_user or inactive_realm:
            return None

        strategy = self.strategy  # type: ignore # This comes from Python Social Auth.
        request = strategy.request
        email_address = self.get_email_address(*args, **kwargs)
        full_name = self.get_full_name(*args, **kwargs)

        subdomain = strategy.session_get("subdomain")

        if not subdomain:
            return login_or_register_remote_user(
                request, email_address, user_profile, full_name, bool(invalid_subdomain)
            )
        try:
            realm = Realm.objects.get(string_id=subdomain)
        except Realm.DoesNotExist:
            return redirect_to_subdomain_login_url()

        return redirect_and_log_into_subdomain(realm, full_name, email_address)
Ejemplo n.º 2
0
    def process_do_auth(self, user_profile, *args, **kwargs):
        # type: (UserProfile, *Any, **Any) -> Optional[HttpResponse]
        # This function needs to be imported from here due to the cyclic
        # dependency.
        from zerver.views.auth import (login_or_register_remote_user,
                                       redirect_to_subdomain_login_url)
        from zerver.views import redirect_and_log_into_subdomain

        return_data = kwargs.get('return_data', {})

        inactive_user = return_data.get('inactive_user')
        inactive_realm = return_data.get('inactive_realm')
        invalid_subdomain = return_data.get('invalid_subdomain')

        if inactive_user or inactive_realm:
            return None

        strategy = self.strategy  # type: ignore # This comes from Python Social Auth.
        request = strategy.request
        email_address = self.get_email_address(*args, **kwargs)
        full_name = self.get_full_name(*args, **kwargs)

        subdomain = strategy.session_get('subdomain')

        if not subdomain:
            return login_or_register_remote_user(request, email_address,
                                                 user_profile, full_name,
                                                 bool(invalid_subdomain))
        try:
            realm = Realm.objects.get(string_id=subdomain)
        except Realm.DoesNotExist:
            return redirect_to_subdomain_login_url()

        return redirect_and_log_into_subdomain(realm, full_name, email_address)
Ejemplo n.º 3
0
def finish_google_oauth2(request):
    # type: (HttpRequest) -> HttpResponse
    error = request.GET.get('error')
    if error == 'access_denied':
        return redirect('/')
    elif error is not None:
        logging.warning('Error from google oauth2 login: %s' % (request.GET.get("error"),))
        return HttpResponse(status=400)

    csrf_state = request.GET.get('state')
    if csrf_state is None or len(csrf_state.split(':')) != 3:
        logging.warning('Missing Google oauth2 CSRF state')
        return HttpResponse(status=400)

    value, hmac_value, subdomain = csrf_state.split(':')
    if hmac_value != google_oauth2_csrf(request, value + subdomain):
        logging.warning('Google oauth2 CSRF error')
        return HttpResponse(status=400)

    resp = requests.post(
        'https://www.googleapis.com/oauth2/v3/token',
        data={
            'code': request.GET.get('code'),
            'client_id': settings.GOOGLE_OAUTH2_CLIENT_ID,
            'client_secret': settings.GOOGLE_OAUTH2_CLIENT_SECRET,
            'redirect_uri': ''.join((
                settings.EXTERNAL_URI_SCHEME,
                settings.EXTERNAL_HOST,
                reverse('zerver.views.auth.finish_google_oauth2'),
            )),
            'grant_type': 'authorization_code',
        },
    )
    if resp.status_code == 400:
        logging.warning('User error converting Google oauth2 login to token: %s' % (resp.text,))
        return HttpResponse(status=400)
    elif resp.status_code != 200:
        logging.error('Could not convert google oauth2 code to access_token: %s' % (resp.text,))
        return HttpResponse(status=400)
    access_token = resp.json()['access_token']

    resp = requests.get(
        'https://www.googleapis.com/plus/v1/people/me',
        params={'access_token': access_token}
    )
    if resp.status_code == 400:
        logging.warning('Google login failed making info API call: %s' % (resp.text,))
        return HttpResponse(status=400)
    elif resp.status_code != 200:
        logging.error('Google login failed making API call: %s' % (resp.text,))
        return HttpResponse(status=400)
    body = resp.json()

    try:
        full_name = body['name']['formatted']
    except KeyError:
        # Only google+ users have a formated name. I am ignoring i18n here.
        full_name = u'{} {}'.format(
            body['name']['givenName'], body['name']['familyName']
        )
    for email in body['emails']:
        if email['type'] == 'account':
            break
    else:
        logging.error('Google oauth2 account email not found: %s' % (body,))
        return HttpResponse(status=400)

    email_address = email['value']
    if not subdomain:
        # When request was not initiated from subdomain.
        user_profile, return_data = authenticate_remote_user(request, email_address)
        invalid_subdomain = bool(return_data.get('invalid_subdomain'))
        return login_or_register_remote_user(request, email_address, user_profile,
                                             full_name, invalid_subdomain)

    try:
        realm = Realm.objects.get(string_id=subdomain)
    except Realm.DoesNotExist:
        return redirect_to_subdomain_login_url()

    return redirect_and_log_into_subdomain(realm, full_name, email_address)
Ejemplo n.º 4
0
def finish_google_oauth2(request):
    # type: (HttpRequest) -> HttpResponse
    error = request.GET.get('error')
    if error == 'access_denied':
        return redirect('/')
    elif error is not None:
        logging.warning('Error from google oauth2 login: %s' %
                        (request.GET.get("error"), ))
        return HttpResponse(status=400)

    csrf_state = request.GET.get('state')
    if csrf_state is None or len(csrf_state.split(':')) != 3:
        logging.warning('Missing Google oauth2 CSRF state')
        return HttpResponse(status=400)

    value, hmac_value, subdomain = csrf_state.split(':')
    if hmac_value != google_oauth2_csrf(request, value + subdomain):
        logging.warning('Google oauth2 CSRF error')
        return HttpResponse(status=400)

    resp = requests.post(
        'https://www.googleapis.com/oauth2/v3/token',
        data={
            'code':
            request.GET.get('code'),
            'client_id':
            settings.GOOGLE_OAUTH2_CLIENT_ID,
            'client_secret':
            settings.GOOGLE_OAUTH2_CLIENT_SECRET,
            'redirect_uri':
            ''.join((
                settings.EXTERNAL_URI_SCHEME,
                settings.EXTERNAL_HOST,
                reverse('zerver.views.auth.finish_google_oauth2'),
            )),
            'grant_type':
            'authorization_code',
        },
    )
    if resp.status_code == 400:
        logging.warning(
            'User error converting Google oauth2 login to token: %s' %
            (resp.text, ))
        return HttpResponse(status=400)
    elif resp.status_code != 200:
        logging.error(
            'Could not convert google oauth2 code to access_token: %s' %
            (resp.text, ))
        return HttpResponse(status=400)
    access_token = resp.json()['access_token']

    resp = requests.get('https://www.googleapis.com/plus/v1/people/me',
                        params={'access_token': access_token})
    if resp.status_code == 400:
        logging.warning('Google login failed making info API call: %s' %
                        (resp.text, ))
        return HttpResponse(status=400)
    elif resp.status_code != 200:
        logging.error('Google login failed making API call: %s' %
                      (resp.text, ))
        return HttpResponse(status=400)
    body = resp.json()

    try:
        full_name = body['name']['formatted']
    except KeyError:
        # Only google+ users have a formated name. I am ignoring i18n here.
        full_name = u'{} {}'.format(body['name']['givenName'],
                                    body['name']['familyName'])
    for email in body['emails']:
        if email['type'] == 'account':
            break
    else:
        logging.error('Google oauth2 account email not found: %s' % (body, ))
        return HttpResponse(status=400)

    email_address = email['value']
    if not subdomain:
        # When request was not initiated from subdomain.
        user_profile, return_data = authenticate_remote_user(
            request, email_address)
        invalid_subdomain = bool(return_data.get('invalid_subdomain'))
        return login_or_register_remote_user(request, email_address,
                                             user_profile, full_name,
                                             invalid_subdomain)

    try:
        realm = Realm.objects.get(string_id=subdomain)
    except Realm.DoesNotExist:
        return redirect_to_subdomain_login_url()

    return redirect_and_log_into_subdomain(realm, full_name, email_address)