Beispiel #1
0
def _check_errors(response):
    try:
        data = response.json()
    except ValueError:  # JSONDecodeError on py3
        raise OAuth2Error("Invalid JSON from Battle.net API: %r" %
                          (response.text))

    if response.status_code >= 400 or "error" in data:
        # For errors, we expect the following format:
        # {"error": "error_name", "error_description": "Oops!"}
        # For example, if the token is not valid, we will get:
        # {
        #   "error": "invalid_token",
        #   "error_description": "Invalid access token: abcdef123456"
        # }
        # For the profile API, this may also look like the following:
        # {"code": 403, "type": "Forbidden", "detail": "Account Inactive"}
        error = data.get("error", "") or data.get("type", "")
        desc = data.get("error_description", "") or data.get("detail", "")

        raise OAuth2Error("Battle.net error: %s (%s)" % (error, desc))

    # The expected output from the API follows this format:
    # {"id": 12345, "battletag": "Example#12345"}
    # The battletag is optional.
    if "id" not in data:
        # If the id is not present, the output is not usable (no UID)
        raise OAuth2Error("Invalid data from Battle.net API: %r" % (data))

    return data
Beispiel #2
0
def _check_errors(response):
    #  403 error's are presented as user-facing errors
    if response.status_code == 403:
        msg = response.content
        raise OAuth2Error("Invalid data from GitLab API: %r" % (msg))

    try:
        data = response.json()
    except ValueError:  # JSONDecodeError on py3
        raise OAuth2Error("Invalid JSON from GitLab API: %r" % (response.text))

    if response.status_code >= 400 or "error" in data:
        # For errors, we expect the following format:
        # {"error": "error_name", "error_description": "Oops!"}
        # For example, if the token is not valid, we will get:
        # {"message": "status_code - message"}
        error = data.get("error", "") or response.status_code
        desc = data.get("error_description", "") or data.get("message", "")

        raise OAuth2Error("GitLab error: %s (%s)" % (error, desc))

    # The expected output from the API follows this format:
    # {"id": 12345, ...}
    if "id" not in data:
        # If the id is not present, the output is not usable (no UID)
        raise OAuth2Error("Invalid data from GitLab API: %r" % (data))

    return data
Beispiel #3
0
    def complete_login(self, request, app, token, **kwargs):
        params = {"oauth_token": token.token, "client_id": app.client_id}
        response = requests.get(self.profile_url, params=params)

        data = response.json()
        if response.status_code >= 400:
            error = data.get("error", "")
            message = data.get("message", "")
            raise OAuth2Error("Twitch API Error: %s (%s)" % (error, message))

        if "_id" not in data:
            raise OAuth2Error("Invalid data from Twitch API: %r" % (data))

        return self.get_provider().sociallogin_from_response(request, data)
Beispiel #4
0
def _check_errors(response):
    try:
        data = response.json()
    except json.decoder.JSONDecodeError:
        raise OAuth2Error("Invalid JSON from Microsoft Graph API: {}".format(
            response.text))

    if "id" not in data:
        error_message = "Error retrieving Microsoft profile"
        microsoft_error_message = data.get("error", {}).get("message")
        if microsoft_error_message:
            error_message = ": ".join((error_message, microsoft_error_message))
        raise OAuth2Error(error_message)

    return data
Beispiel #5
0
 def complete_login(self, request, app, token, **kwargs):
     resp = requests.get(self.profile_url,
                         params={
                             'access_token': token.token,
                             'alt': 'json'
                         })
     resp.raise_for_status()
     extra_data = resp.json()
     try:
         login = self.get_provider() \
             .sociallogin_from_response(request,
                                        extra_data)
     except Exception as e:
         logger.error(
             f'GoogleOAuth2Adapter.complete_login: error in provider.sociallogin_from_response(): {e}'
         )
         raise
     login.user.origin = User.USER_ORIGIN_SOCIAL
     if 'name' in extra_data:
         login.user.name = extra_data['name'] or login.user.name
     if not email_follows_pattern(login.user.email):
         msg = 'Email domain is not allowed'
         logger.error(f'GoogleOAuth2Adapter.complete_login: {msg}')
         raise OAuth2Error(msg)
     return login
Beispiel #6
0
 def get_access_token(self, code):
     data = {
         "grant_type": "authorization_code",
         "code": code,
         "app_access_token": self.app_access_token(),
     }
     params = None
     self._strip_empty_keys(data)
     url = self.access_token_url
     if self.access_token_method == "GET":
         params = data
         data = None
     # TODO: Proper exception handling
     resp = requests.request(
         self.access_token_method,
         url,
         params=params,
         data=json.dumps(data),
         headers={"Content-Type": "application/json"},
     )
     resp.raise_for_status()
     access_token = resp.json()
     if (
         not access_token
         or "data" not in access_token
         or "access_token" not in access_token["data"]
     ):
         raise OAuth2Error("Error retrieving access token: %s" % resp.content)
     return access_token["data"]
Beispiel #7
0
 def get_access_token(self, code):
     url = self.access_token_url
     client_secret = self.generate_client_secret()
     data = {
         'client_id': self.consumer_key,
         'code': code,
         'grant_type': 'authorization_code',
         'redirect_uri': self.callback_url,
         'client_secret': client_secret
     }
     self._strip_empty_keys(data)
     resp = requests.request(self.access_token_method,
                             url,
                             data=data,
                             headers=self.headers)
     access_token = None
     if resp.status_code in [200, 201]:
         if (resp.headers['content-type'].split(';')[0]
                 == 'application/json' or resp.text[:2] == '{"'):
             access_token = resp.json()
         else:
             access_token = dict(parse_qsl(resp.text))
     if not access_token or 'access_token' not in access_token:
         raise OAuth2Error('Error retrieving access token: %s' %
                           resp.content)
     return access_token
Beispiel #8
0
 def get_access_token(self, code):
     url = self.access_token_url
     client_secret = self.generate_client_secret()
     data = {
         "client_id": self.get_client_id(),
         "code": code,
         "grant_type": "authorization_code",
         "redirect_uri": self.callback_url,
         "client_secret": client_secret,
     }
     self._strip_empty_keys(data)
     logger.debug(f'[django-allauth] Token request:'
                  f'{self.access_token_method} {url},'
                  f' data: {data},'
                  f' headers: {self.headers}')
     resp = requests.request(self.access_token_method,
                             url,
                             data=data,
                             headers=self.headers)
     access_token = None
     if resp.status_code in [200, 201]:
         try:
             access_token = resp.json()
         except ValueError:
             access_token = dict(parse_qsl(resp.text))
     if not access_token or "access_token" not in access_token:
         raise OAuth2Error("Error retrieving access token: %s" %
                           resp.content)
     return access_token
Beispiel #9
0
 def get_access_token(self, code):
     data = {
         "appid": self.consumer_key,
         "redirect_uri": self.callback_url,
         "grant_type": "authorization_code",
         "secret": self.consumer_secret,
         "scope": self.scope,
         "code": code,
     }
     params = None
     self._strip_empty_keys(data)
     url = self.access_token_url
     if self.access_token_method == "GET":
         params = data
         data = None
     # TODO: Proper exception handling
     resp = requests.request(self.access_token_method,
                             url,
                             params=params,
                             data=data)
     access_token = None
     if resp.status_code == 200:
         access_token = resp.json()
     if not access_token or "access_token" not in access_token:
         raise OAuth2Error("Error retrieving access token: %s" %
                           resp.content)
     return access_token
Beispiel #10
0
    def parse_token(self, data, app=None):
        # parse token header and get relevant public key
        unverified_header, unverified_claims = jwt.process_jwt(
            data['id_token'])
        public_key = self.get_public_key(unverified_header.get('kid'))

        # verify signature, iat, exp
        header, claims = jwt.verify_jwt(data['id_token'],
                                        public_key, ['RS256'],
                                        timedelta(minutes=1),
                                        checks_optional=True)

        # Verify we are the intended audience for the token
        intended_audiences = [self.intended_aud]
        if app is not None:
            intended_audiences.append(app.client_id)
        if claims.get('aud') is not None and claims.get(
                'aud') not in intended_audiences:
            raise OAuth2Error(
                "JWT aud {} does not match intended audience {}".format(
                    claims.get('aud'), self.intended_aud))

        social_token = SocialToken(token=data['id_token'])
        social_token.expires_at = datetime.fromtimestamp(claims['iat'],
                                                         tz=timezone.utc)
        return social_token
Beispiel #11
0
 def get_access_token(self, code):
     data = {
         "client_id": self.consumer_key,
         "redirect_url": self.callback_url,
         "grant_type": "authorization_code",
         "response_type": "code",
         "client_secret": self.consumer_secret,
         "code": code,
     }
     params = None
     self._strip_empty_keys(data)
     url = self.access_token_url
     if self.access_token_method == "GET":
         params = data
         data = None
     # Allow custom User Agent to comply with Untappd API
     settings = app_settings.PROVIDERS.get(UntappdProvider.id, {})
     headers = {"User-Agent": settings.get("USER_AGENT", "django-allauth")}
     # TODO: Proper exception handling
     resp = requests.request(
         self.access_token_method,
         url,
         params=params,
         data=data,
         headers=headers,
     )
     access_token = None
     if resp.status_code == 200:
         access_token = resp.json()["response"]
     if not access_token or "access_token" not in access_token:
         raise OAuth2Error("Error retrieving access token: %s" %
                           resp.content)
     return access_token
Beispiel #12
0
 def get_access_token(self, code):
     url = self.access_token_url
     client_secret = self.generate_client_secret()
     data = {
         'client_id': self.get_client_id(),
         'code': code,
         'grant_type': 'authorization_code',
         'redirect_uri': self.callback_url,
         'client_secret': client_secret,
     }
     self._strip_empty_keys(data)
     resp = requests.request(self.access_token_method,
                             url,
                             data=data,
                             headers=self.headers)
     access_token = None
     if resp.status_code in [200, 201]:
         try:
             access_token = resp.json()
         except ValueError:
             access_token = dict(parse_qsl(resp.text))
     if not access_token or 'access_token' not in access_token:
         raise OAuth2Error('Error retrieving access token: %s' %
                           resp.content)
     return access_token
Beispiel #13
0
 def get_access_token(self, code):
     data = {'client_id': self.consumer_key,
             'redirect_url': self.callback_url,
             'grant_type': 'authorization_code',
             'response_type': 'code',
             'client_secret': self.consumer_secret,
             'code': code}
     params = None
     self._strip_empty_keys(data)
     url = self.access_token_url
     if self.access_token_method == 'GET':
         params = data
         data = None
     # TODO: Proper exception handling
     resp = requests.request(self.access_token_method,
                             url,
                             params=params,
                             data=data)
     access_token = None
     if resp.status_code == 200:
         access_token = resp.json()['response']
     if not access_token or 'access_token' not in access_token:
         raise OAuth2Error('Error retrieving access token: %s'
                           % resp.content)
     return access_token
Beispiel #14
0
    def get_data(self, token):
        # Verify the user first
        resp = requests.get(
            self.identity_url,
            params={'token': token}
        )
        resp = resp.json()

        if not resp.get('ok'):
            raise OAuth2Error()

        # Fill in their generic info
        info = {
            'name': resp.get('user'),
            'user': {
                'name': resp.get('user'),
                'id': resp.get('user_id')
            },
            'team': {
                'name': resp.get('team'),
                'id': resp.get('team_id')
            }
        }

        return info
Beispiel #15
0
    def _get_cert(self):
        """Get the UWUM certificate."""
        cert = UWUMProvider.settings.get('CERT')

        if not path.exists(cert):
            raise OAuth2Error('UWUM certificate not found')

        return cert
Beispiel #16
0
    def get_data(self, token):
        # Verify the user first
        resp = requests.get(self.identity_url, params={'token': token})
        resp = resp.json()

        if not resp.get('ok'):
            raise OAuth2Error()

        return resp
Beispiel #17
0
def _check_errors(data):
    # The expected output from the Battle.net API follows this format:
    # {"id": 12345, "battletag": "Example#12345"}
    # The battletag is optional.
    if "error" in data:
        # For errors, we expect the following format:
        # {"error": "error_name", "error_description": "Oops!"}
        # For example, if the token is not valid, we will get:
        # {
        #   "error": "invalid_token",
        #   "error_description": "Invalid access token: abcdef123456"
        # }
        error = data["error"]
        desc = data.get("error_description", "")
        raise OAuth2Error("Battle.net error: %s (%s)" % (error, desc))
    elif "id" not in data:
        # If the id is not present, the output is not usable (no UID)
        raise OAuth2Error("Invalid data from Battle.net API: %r" % (data))
Beispiel #18
0
    def get_data(self, token):
        # Verify the user first
        hed = {"Authorization": "Bearer " + token}
        resp = requests.get(self.identity_url, headers=hed)
        resp = resp.json()

        if not resp.get("ok"):
            raise OAuth2Error()

        return resp
Beispiel #19
0
    def get_data(self, token):
        # Verify the user first
        resp = requests.get(
            self.identity_url,
            params={'token': token}
        )
        resp = resp.json()

        if not resp.get('ok'):
            raise OAuth2Error(f'UserInfo Exception: {resp.get("error")}')

        userid = resp.get('user', {}).get('id')
        user_info = requests.get(
            self.user_detail_url,
            params={'token': settings.SLACK_BOT_TOKEN, 'user': userid}
        )
        user_info = user_info.json()

        if not user_info.get('ok'):
            raise OAuth2Error(f'UserInfo Exception: {user_info.get("error")}')

        user_info = user_info.get('user', {})
        display_name = user_info.get('profile',
                                     {}).get('display_name_normalized')
        teamid = resp.get('team').get('id')
        if not resp.get('user', {}).get('email'):
            resp['user']['email'] = user_info.get('email')
        resp['user']['display_name'] = display_name
        resp['user']['username'] = f'{userid}_{teamid}'
        resp['user']['full_name'] = user_info.get('profile',
                                                  {}).get('real_name')
        resp['user']['first_name'] = user_info.get('profile',
                                                   {}).get('first_name')
        resp['user']['last_name'] = user_info.get('profile',
                                                  {}).get('last_name')
        # This key is not present in the response if the user has not
        # uploaded an image and the field cannot be None
        resp['user']['image_original'] = (user_info.get(
            'profile', {}).get('image_original') or '')
        resp['user']['title'] = user_info.get('profile',
                                              {}).get('title')
        resp['user']['timezone'] = user_info.get('tz')
        return resp
Beispiel #20
0
    def _get_apple_public_key(self, kid):
        response = requests.get(self.public_key_url)
        response.raise_for_status()
        try:
            data = response.json()
        except json.JSONDecodeError as e:
            raise OAuth2Error("Error retrieving apple public key.") from e

        for d in data["keys"]:
            if d["kid"] == kid:
                return d
Beispiel #21
0
    def complete_login(self, request, app, token, **kwargs):
        headers = {'Authorization': 'Bearer {}'.format(token.token)}
        response = requests.get(self.profile_url, headers=headers)

        data = response.json()
        if response.status_code >= 400:
            error = data.get("error", "")
            message = data.get("message", "")
            raise OAuth2Error("Twitch API Error: %s (%s)" % (error, message))

        try:
            user_info = data.get('data', [])[0]
        except IndexError:
            raise OAuth2Error("Invalid data from Twitch API: %s" % (data))

        if "id" not in user_info:
            raise OAuth2Error("Invalid data from Twitch API: %s" % (user_info))

        return self.get_provider().sociallogin_from_response(
            request, user_info)
    def get_verified_identity_data(self, id_token):
        provider = self.get_provider()
        allowed_auds = self.get_client_id(provider)

        try:
            public_key = self.get_public_key(id_token)
            identity_data = jwt.decode(id_token, '', verify=False)
            return identity_data

        except jwt.PyJWTError as e:
            raise OAuth2Error("Invalid id_token") from e
Beispiel #23
0
 def get_data(self, token):
     resp = requests.get(
         self.identity_url,
         headers={'Authorization': 'Bearer {}'.format(token)})
     resp = resp.json()
     if not resp.get('ok'):
         raise OAuth2Error()
     info = {
         'user': resp.get('user'),
     }
     return info
Beispiel #24
0
    def pre_social_login(self, request, sociallogin):
        if sociallogin.is_existing:
            return

        if not sociallogin.user.email:
            raise OAuth2Error(
                'Для авторицации необходимо дать доступ к электронному адресу')
        try:
            user = User.objects.get(email__iexact=sociallogin.user.email)
            sociallogin.connect(request, user)
        except User.DoesNotExist:
            sociallogin.state['next'] = reverse('profile:edit')
Beispiel #25
0
    def get_data(self, token):
        # Verify the user first
        resp = requests.get(self.identity_url, params={"token": token})
        resp = resp.json()

        print('resp ', resp)

        if not resp.get("ok"):
            print('identity error')
            raise OAuth2Error()

        return resp
Beispiel #26
0
    def get_access_token(self, code):
        """
        This whole method is unchanged except for the
        `params = {"realm": "/individu"}` hack.
        Original code:
        https://github.com/pennersr/django-allauth/blob/6a6d3c618ab018234dde8701173093274710ee0a/allauth/socialaccount/providers/oauth2/client.py#L44
        """
        data = {
            "redirect_uri": self.callback_url,
            "grant_type": "authorization_code",
            "code": code
        }
        if self.basic_auth:
            auth = requests.auth.HTTPBasicAuth(self.consumer_key,
                                               self.consumer_secret)
        else:
            auth = None
            data.update({
                "client_id": self.consumer_key,
                "client_secret": self.consumer_secret
            })
        params = {"realm": "/individu"}
        self._strip_empty_keys(data)
        url = self.access_token_url
        if self.access_token_method == "GET":
            params = data
            data = None
        resp = requests.request(
            self.access_token_method,
            url,
            params=params,
            data=data,
            headers=self.headers,
            auth=auth,
            timeout=settings.REQUESTS_TIMEOUT,
        )

        access_token = None
        if resp.status_code in [200, 201]:
            # Weibo sends json via 'text/plain;charset=UTF-8'
            if resp.headers["content-type"].split(
                    ";")[0] == "application/json" or resp.text[:2] == '{"':
                access_token = resp.json()
            else:
                access_token = dict(parse_qsl(resp.text))
        if not access_token or "access_token" not in access_token:
            raise OAuth2Error("Error retrieving access token: %s" %
                              resp.content)
        return access_token
Beispiel #27
0
 def complete_login(self, request, app, token, **kwargs):
     resp = requests.post(self.profile_url,
                          json={},
                          headers={'Authorization': f'Bearer {token.token}'})
     resp.raise_for_status()
     extra_data = resp.json()
     login = self.get_provider() \
         .sociallogin_from_response(request,
                                    extra_data)
     login.user.origin = User.USER_ORIGIN_SOCIAL
     if 'name' in extra_data:
         login.user.name = extra_data['name'] or login.user.name
     if not email_follows_pattern(login.user.email):
         raise OAuth2Error(f'Email domain is not allowed')
     return login
Beispiel #28
0
    def complete_login(self, request, app, token, **kwargs):
        resp = requests.get(
            self.user_info_url,
            headers={
                'Content-Type': 'application/json',
                'Authorization': f'Bearer {token}',
            },
        )
        resp.raise_for_status()
        extra_data = resp.json()
        if extra_data['code'] != 0:
            raise OAuth2Error("Error retrieving code: %s" % resp.content)
        extra_data = extra_data['data']

        return self.get_provider().sociallogin_from_response(
            request, extra_data)
Beispiel #29
0
    def complete_login(self, request, app, token, **kwargs):
        resp = requests.get(
            self.user_info_url,
            headers={
                "Content-Type": "application/json",
                "Authorization": "Bearer " + token.token,
            },
        )
        resp.raise_for_status()
        extra_data = resp.json()
        if extra_data["code"] != 0:
            raise OAuth2Error("Error retrieving code: %s" % resp.content)
        extra_data = extra_data["data"]

        return self.get_provider().sociallogin_from_response(
            request, extra_data)
Beispiel #30
0
def test_custom_500_view__ip_restricted_error(render):
    try:
        # raise this to populate info for
        # call to sys.exec_info() in the view
        raise OAuth2Error(
            'Error retrieving access token: b\'{"error":"invalid_grant","error_description":"ip restricted"}\''
        )
    except OAuth2Error:
        allow_list = "0.0.0.1, 0.0.0.2, 0.0.0.3"
        with mock.patch("metadeploy.views.IP_RESTRICTED_MESSAGE", allow_list):
            factory = RequestFactory()
            request = factory.get("/accounts/salesforce/login/callback/")
            request.user = AnonymousUser()
            custom_500_view(request)

    assert allow_list == render.call_args[1]["context"]["JS_CONTEXT"]["error_message"]