def get_access_token(self):
        if (not hasattr(current_app, "token")):
            client_credential = (
                "%s:%s" %
                (self.soovii.consumer_key, self.soovii.consumer_secret))
            headers = {
                "Authorization":
                "Basic " +
                to_unicode(base64.encodestring(
                    to_bytes(client_credential))).replace("\n", "")
            }
            body = self.api_client.prepare_request_body(
                get_syscfg_val(8),
                get_syscfg_val(9))  # 对于网址类型的型的项目用户名密码,随意填写,如"soovii", "soovii"

            resp, content = self.soovii.http_request(
                self.soovii.access_token_url,
                headers,
                to_bytes(body),
                method="POST")
            if resp.code not in (200, 201):
                logger.info('Invalid response')
            else:
                dic = json.loads(to_unicode(content))
                current_app.token = dic
                return dic
        else:
            return current_app.token
Example #2
0
    def handle_oauth2_response_discord(self, args):
        """Handles an oauth2 authorization response."""

        client = self.make_client()
        remote_args = {
            "client_id": self.consumer_key,
            "client_secret": self.consumer_secret,
            "code": args.get("code"),
            "redirect_uri": session.get("%s_oauthredir" % self.name),
            "scope": "identify",
        }
        log.debug("Prepare oauth2 remote args %r", remote_args)
        remote_args.update(self.access_token_params)
        headers = copy(self._access_token_headers)
        if self.access_token_method == "POST":
            headers.update(
                {"Content-Type": "application/x-www-form-urlencoded"})
            body = client.prepare_request_body(**remote_args)
            response = requests.request(
                self.access_token_method,
                self.expand_url(self.access_token_url),
                headers=headers,
                data=to_bytes(body, self.encoding),
            )
            if response.status_code not in (200, 201):
                raise OAuthException(
                    "Invalid response from %s" % self.name,
                    type="invalid_response",
                    data=to_bytes(body, self.encoding),
                )
            return jsonify(response.text.encode("utf8"))
        elif self.access_token_method == "GET":
            qs = client.prepare_request_body(**remote_args)
            url = self.expand_url(self.access_token_url)
            url += ("?" in url and "&" or "?") + qs
            response = requests.request(self.access_token_method,
                                        url,
                                        headers=headers)
            if response.status_code not in (200, 201):
                raise OAuthException(
                    "Invalid response from %s" % self.name,
                    type="invalid_response",
                    data=to_bytes(body, self.encoding),
                )
            return jsonify(response.text.encode("utf8"))
        else:
            raise OAuthException("Unsupported access_token_method: %s" %
                                 self.access_token_method)
Example #3
0
 def validate_title(self, field):
     data = u'%s%s' % (field.data, self.content.data)
     key = hashlib.md5(to_bytes(data)).hexdigest()
     if cache.get(key):
         raise StopValidation("Duplicate requesting")
     # avoid duplicate requesting
     cache.set(key, 1, 100)
Example #4
0
 def validate_title(self, field):
     data = u'%s%s' % (field.data, self.content.data)
     key = hashlib.md5(to_bytes(data)).hexdigest()
     if cache.get(key):
         raise StopValidation("Duplicate requesting")
     # avoid duplicate requesting
     cache.set(key, 1, 100)
Example #5
0
    def test_get_authorize(self):
        rv = self.client.get('/oauth/authorize')
        assert 'Missing+client_id+parameter' in rv.location

        client = self.client
        rv = client.get('/oauth/authorize?client_id=ios&response_type=code')
        assert rv.status_code == 200

        user = self.login()

        rv = client.get('/oauth/authorize?client_id=ios&response_type=code')
        assert rv.status_code == 200
        assert to_bytes(user.username) in rv.data

        oauth_client = OAuthClient.query.first()

        rv = client.get('/oauth/authorize?%s' % url_encode({
            'client_id': oauth_client.client_id,
            'response_type': 'code',
            'scope': 'user',
        }))
        assert b'user:email' in rv.data
        assert b'user:write' in rv.data

        rv = client.get('/oauth/authorize?%s' % url_encode({
            'client_id': oauth_client.client_id,
            'response_type': 'code',
            'scope': 'user:email',
        }))
        assert b'user:email' in rv.data
        assert b'user:write' not in rv.data
Example #6
0
    def handle_oauth2_response(self):
        """Handles an oauth2 authorization response.

        This method overrides the one provided by OAuthRemoteApp in order to
        support Basic HTTP Authentication.
        """
        if self.access_token_method != 'POST':
            raise OAuthException(
                ('Unsupported access_token_method: {}. '
                 'Only POST is supported.').format(self.access_token_method)
            )

        client = self.make_client()
        remote_args = {
            'code': request.args.get('code'),
            'client_secret': self.consumer_secret,
            'redirect_uri': (
                session.get('%s_oauthredir' % self.name) or
                url_for('invenio_oauthclient.authorized',
                        remote_app=self.name, _external=True)
            ),
        }
        remote_args.update(self.access_token_params)
        # build the Basic HTTP Authentication code
        b2access_basic_auth = base64.encodestring(bytes('{0}:{1}'.format(
            self.consumer_key, self.consumer_secret),
            'utf-8')).decode('ascii').replace('\n', '')
        body = client.prepare_request_body(**remote_args)
        resp, content = self.http_request(
            self.expand_url(self.access_token_url),
            # set the Authentication header
            headers={
                'Authorization': 'Basic {}'.format(b2access_basic_auth),
            },
            data=to_bytes(body, self.encoding),
            method=self.access_token_method,
        )

        data = parse_response(resp, content, content_type=self.content_type)
        if resp.code not in (200, 201):
            raise OAuthException(
                'Invalid response from %s' % self.name,
                type='invalid_response', data=data
            )
        return data
Example #7
0
    def handle_oauth2_response(self):
        """Handles an oauth2 authorization response.

        This method overrides the one provided by OAuthRemoteApp in order to
        support Basic HTTP Authentication.
        """
        if self.access_token_method != 'POST':
            raise OAuthException(
                ('Unsupported access_token_method: {}. '
                 'Only POST is supported.').format(self.access_token_method))

        client = self.make_client()
        remote_args = {
            'code':
            request.args.get('code'),
            'client_secret':
            self.consumer_secret,
            'redirect_uri': (session.get('%s_oauthredir' % self.name)
                             or url_for('invenio_oauthclient.authorized',
                                        remote_app=self.name,
                                        _external=True)),
        }
        remote_args.update(self.access_token_params)
        # build the Basic HTTP Authentication code
        b2access_basic_auth = base64.encodestring(
            bytes('{0}:{1}'.format(self.consumer_key, self.consumer_secret),
                  'utf-8')).decode('ascii').replace('\n', '')
        body = client.prepare_request_body(**remote_args)
        resp, content = self.http_request(
            self.expand_url(self.access_token_url),
            # set the Authentication header
            headers={
                'Authorization': 'Basic {}'.format(b2access_basic_auth),
            },
            data=to_bytes(body, self.encoding),
            method=self.access_token_method,
        )

        data = parse_response(resp, content, content_type=self.content_type)
        if resp.code not in (200, 201):
            raise OAuthException('Invalid response from %s' % self.name,
                                 type='invalid_response',
                                 data=data)
        return data
Example #8
0
    def handle_oauth2_response_spotify(self, args):
        """Handles an oauth2 authorization response."""

        client = self.make_client()
        remote_args = {
            "code": args.get("code"),
            "redirect_uri": session.get("%s_oauthredir" % self.name),
        }
        log.debug("Prepare oauth2 remote args %r", remote_args)
        remote_args.update(self.access_token_params)
        data = f"{self._consumer_key}:{self._consumer_secret}"
        encoded = str(base64.b64encode(data.encode("utf-8")), "utf-8")
        headers = {"Authorization": f"Basic {encoded}"}
        if self.access_token_method == "POST":
            headers.update(
                {"Content-Type": "application/x-www-form-urlencoded"})
            body = client.prepare_request_body(**remote_args)
            resp, content = self.http_request(
                self.expand_url(self.access_token_url),
                headers=headers,
                data=to_bytes(body, self.encoding),
                method=self.access_token_method,
            )
        elif self.access_token_method == "GET":
            qs = client.prepare_request_body(**remote_args)
            url = self.expand_url(self.access_token_url)
            url += ("?" in url and "&" or "?") + qs
            resp, content = self.http_request(url,
                                              headers=headers,
                                              method=self.access_token_method)
        else:
            raise OAuthException("Unsupported access_token_method: %s" %
                                 self.access_token_method)

        data = OAuth.parse_response(resp,
                                    content,
                                    content_type=self.content_type)
        if resp.code not in (200, 201):
            raise OAuthException(
                "Invalid response from %s" % self.name,
                type="invalid_response",
                data=data,
            )
        return data
Example #9
0
    def handle_oauth2_response(self):
        if self.access_token_method != 'POST':
            raise OAuthException('Unsupported access_token_method: %s' %
                                 self.access_token_method)

        client = self.make_client()
        remote_args = {
            'code': request.args.get('code'),
            'client_secret': self.consumer_secret,
            'redirect_uri': session.get('%s_oauthredir' % self.name)
        }
        remote_args.update(self.access_token_params)

        reddit_basic_auth = base64.encodestring(
            '%s:%s' % (REDDIT_APP_ID, REDDIT_APP_SECRET)).replace('\n', '')
        body = client.prepare_request_body(**remote_args)
        while True:
            resp, content = self.http_request(
                self.expand_url(self.access_token_url),
                headers={
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Authorization': 'Basic %s' % reddit_basic_auth,
                    'User-Agent': REDDIT_USER_AGENT
                },
                data=to_bytes(body, self.encoding),
                method=self.access_token_method,
            )
            # Reddit API is rate-limited, so if we get 429, we need to retry
            if resp.code != 429:
                break
            time.sleep(1)

        data = parse_response(resp, content, content_type=self.content_type)
        if resp.code not in (200, 201):
            raise OAuthException('Invalid response from %s' % self.name,
                                 type='invalid_response',
                                 data=data)
        return data
Example #10
0
    def handle_oauth2_response(self):
        if self.access_token_method != 'POST':
            raise OAuthException(
                'Unsupported access_token_method: %s' %
                self.access_token_method
            )

        client = self.make_client()
        remote_args = {
            'code': request.args.get('code'),
            'client_secret': self.consumer_secret,
            'redirect_uri': session.get('%s_oauthredir' % self.name)
        }
        remote_args.update(self.access_token_params)

        reddit_basic_auth = base64.encodestring('%s:%s' % (REDDIT_APP_ID, REDDIT_APP_SECRET)).replace('\n', '')
        body = client.prepare_request_body(**remote_args)
        while True:
            resp, content = self.http_request(
                self.expand_url(self.access_token_url),
                headers={'Content-Type': 'application/x-www-form-urlencoded',
                         'Authorization': 'Basic %s' % reddit_basic_auth,
                         'User-Agent': REDDIT_USER_AGENT},
                data=to_bytes(body, self.encoding),
                method=self.access_token_method,
            )
            # Reddit API is rate-limited, so if we get 429, we need to retry
            if resp.code != 429:
                break
            time.sleep(1)

        data = parse_response(resp, content, content_type=self.content_type)
        if resp.code not in (200, 201):
            raise OAuthException(
                'Invalid response from %s' % self.name,
                type='invalid_response', data=data
            )
        return data
Example #11
0
 def test_get_api_index(self):
     rv = self.client.get('/api/')
     assert to_bytes(API_VERSION) in rv.data
Example #12
0
 def validate_content(self, field):
     key = hashlib.md5(to_bytes(field.data)).hexdigest()
     if cache.get(key):
         raise StopValidation("Duplicate requesting")
     # avoid duplicate requesting
     cache.set(key, 1, 100)
Example #13
0
def encode_base64(text):
    text = to_bytes(text)
    return to_unicode(base64.b64encode(text))
Example #14
0
 def validate_content(self, field):
     key = hashlib.md5(to_bytes(field.data)).hexdigest()
     if cache.get(key):
         raise StopValidation("Duplicate requesting")
     # avoid duplicate requesting
     cache.set(key, 1, 100)
Example #15
0
    def request(
        self,
        url,
        data=None,
        headers=None,
        format="urlencoded",
        method="GET",
        content_type=None,
        token=None,
        discord=False,
    ):
        """
        Sends a request to the remote server with OAuth tokens attached.

        :param data: the data to be sent to the server.
        :param headers: an optional dictionary of headers.
        :param format: the format for the `data`. Can be `urlencoded` for
                       URL encoded data or `json` for JSON.
        :param method: the HTTP request method to use.
        :param content_type: an optional content type. If a content type
                             is provided, the data is passed as it, and
                             the `format` is ignored.
        :param token: an optional token to pass, if it is None, token will
                      be generated by tokengetter.
        """

        headers = dict(headers or {})
        if token is None:
            token = self.get_request_token()

        client = self.make_client(token)
        url = self.expand_url(url)
        if method == "GET":
            assert format == "urlencoded"
            if data:
                url = add_params_to_uri(url, data)
                data = None
        else:
            if content_type is None:
                data, content_type = OAuth.encode_request_data(data, format)
            if content_type is not None:
                headers["Content-Type"] = content_type

        if self.request_token_url:
            # oauth1
            uri, headers, body = client.sign(url,
                                             http_method=method,
                                             body=data,
                                             headers=headers)
        else:
            # oauth2
            uri, headers, body = client.add_token(url,
                                                  http_method=method,
                                                  body=data,
                                                  headers=headers)

        if hasattr(self, "pre_request"):
            # This is designed for some rubbish services like weibo.
            # Since they don't follow the standards, we need to
            # change the uri, headers, or body.
            uri, headers, body = self.pre_request(uri, headers, body)

        if body:
            data = to_bytes(body, self.encoding)
        else:
            data = None
        if discord:
            response = requests.request(method,
                                        uri,
                                        headers=headers,
                                        data=to_bytes(body, self.encoding))
            if response.status_code not in (200, 201):
                raise OAuthException("Invalid response from %s" % self.name,
                                     type="invalid_response",
                                     data=data)
            return jsonify(response.text.encode("utf8"))

        resp, content = self.http_request(uri,
                                          headers,
                                          data=to_bytes(body, self.encoding),
                                          method=method)
        return OAuthResponse(resp, content, self.content_type)
Example #16
0
def encode_base64(text):
    text = to_bytes(text)
    return to_unicode(base64.b64encode(text))