Example #1
0
    def _request_authorize_code(self, application):
        oauth2 = self.OAUTH2_PARAMETER
        oauth2["client_id"] = application.app_key
        oauth2["redirect_uri"] = application.redirect_uri
        oauth2["userId"] = self._username
        oauth2["passwd"] = self._password

        curl = _Curl()
        curl.set_option(pycurl.FOLLOWLOCATION, False)  # don't follow redirect
        curl.set_option(pycurl.REFERER, self.AUTHORIZE_URL)  # required for auth
        try:
            curl.post(self.AUTHORIZE_URL, oauth2)
        except pycurl.error:
            raise NetworkError

        # After post the OAUTH2 information, if success,
        # Sina will return "302 Moved Temporarily", the target is "http://redirect_uri/?code=xxxxxx",
        # xxxxxx is the authorize code.
        redirect_url = curl.get_info(pycurl.REDIRECT_URL)
        if not redirect_url:
            raise AuthorizeFailed("Invalid Application() or wrong username/password.")

        authorize_code = redirect_url.split("=")[1]
        self.authorize_code = authorize_code
        return authorize_code
Example #2
0
    def __request(self, action, api, kwargs, privileged=True):
        if not self._access_token:
            raise NotAuthorized

        # hack for https://github.com/WeCase/WeCase/issues/119
        if (
            privileged
            and api in self.PRIVILEGED_APIS
            and self._authorize_code
            and (
                not self.PRIVILEGED_APIS[api]["identifier_required"]
                or (
                    self.PRIVILEGED_APIS[api]["identifier_required"]
                    and (("uid" in kwargs) or ("screen_name" in kwargs))
                )
            )
        ):
            if "uid" in kwargs and "screen_name" not in kwargs:
                screen_name = self.__request(self.HTTP_GET, "users/show", {"uid": kwargs["uid"]}, privileged=False).get(
                    "screen_name"
                )
                kwargs["screen_name"] = screen_name
                del kwargs["uid"]
            kwargs["source"] = self.application.app_key
            kwargs["access_token"] = self._authorize_code
        else:
            kwargs["access_token"] = self._access_token

        request_url = self.API % api

        curl = _Curl()
        if action == self.HTTP_GET:
            result = curl.get(request_url, kwargs)
        elif action == self.HTTP_POST:
            result = curl.post(request_url, kwargs)
        elif action == self.HTTP_UPLOAD:
            image = kwargs.pop("pic")
            kwargs["pic"] = image.read()
            image.close()
            result = curl.post_binary(request_url, kwargs)

        status_code = curl.get_info(pycurl.RESPONSE_CODE)
        try:
            result_json = json.loads(result, object_hook=getable_dict)
            if not isinstance(result_json, dict):
                return result_json
            if "error_code" in result_json.keys():
                raise APIError(result_json["error_code"], result_json["error"])
            return getable_dict(result_json)
        except (TypeError, ValueError):
            if status_code != 200:
                raise APIError(status_code, "Unknown Error")
            raise ResultCorrupted
Example #3
0
    def __request(self, action, api, kwargs, privileged=True):
        if not self._access_token:
            raise NotAuthorized

        # hack for https://github.com/WeCase/WeCase/issues/119
        if (privileged and api in self.PRIVILEGED_APIS and self._authorize_code
                and (not self.PRIVILEGED_APIS[api]["identifier_required"] or
                     (self.PRIVILEGED_APIS[api]["identifier_required"] and
                      (("uid" in kwargs) or ("screen_name" in kwargs))))):
            if "uid" in kwargs and "screen_name" not in kwargs:
                screen_name = self.__request(
                    self.HTTP_GET,
                    "users/show", {
                        "uid": kwargs["uid"]
                    },
                    privileged=False).get("screen_name")
                kwargs["screen_name"] = screen_name
                del kwargs["uid"]
            kwargs["source"] = self.application.app_key
            kwargs["access_token"] = self._authorize_code
        else:
            kwargs["access_token"] = self._access_token

        request_url = self.API % api

        curl = _Curl()
        if action == self.HTTP_GET:
            result = curl.get(request_url, kwargs)
        elif action == self.HTTP_POST:
            result = curl.post(request_url, kwargs)
        elif action == self.HTTP_UPLOAD:
            image = kwargs.pop("pic")
            kwargs["pic"] = image.read()
            image.close()
            result = curl.post_binary(request_url, kwargs)

        status_code = curl.get_info(pycurl.RESPONSE_CODE)
        try:
            result_json = json.loads(result, object_hook=getable_dict)
            if not isinstance(result_json, dict):
                return result_json
            if "error_code" in result_json.keys():
                raise APIError(result_json["error_code"], result_json["error"])
            return getable_dict(result_json)
        except (TypeError, ValueError):
            if status_code != 200:
                raise APIError(status_code, "Unknown Error")
            raise ResultCorrupted
Example #4
0
    def _request_access_token(self, application, authorize_code):
        access_token_parameter = {
            'client_id': application.app_key,
            'client_secret': application.app_secret,
            'grant_type': 'authorization_code',
            'code': authorize_code,
            'redirect_uri': application.redirect_uri
        }

        curl = _Curl()
        try:
            result = curl.post(self.ACCESS_TOKEN_URL, access_token_parameter)
            status_code = curl.get_info(pycurl.RESPONSE_CODE)
            if status_code != 200:
                result_json = json.loads(result, object_hook=getable_dict)
                raise AuthorizeFailed(result_json)
        except pycurl.error:
            raise NetworkError
        finally:
            curl.close()

        return json.loads(result)["access_token"]
    def _request_authorize_code(self, application):
        # Encode the username to a URL-encoded string.
        # Then, calculate its base64, we need it later
        username_encoded = urllib.parse.quote(self._username)
        username_encoded = username_encoded.encode("UTF-8")  # convert to UTF-8-encoded byte string
        username_encoded = base64.b64encode(username_encoded)

        # First, we need to request prelogin.php for some necessary parameters.
        prelogin = self.PRELOGIN_PARAMETER
        prelogin['su'] = username_encoded

        curl = _Curl()
        try:
            prelogin_result = curl.get(self.PRELOGIN_URL, prelogin)
        except pycurl.error:
            raise NetworkError

        # The result is a piece of JavaScript code, in the format of
        # sinaSSOController.preloginCallBack({json here})
        prelogin_json = prelogin_result.replace("sinaSSOController.preloginCallBack(", "")[0:-1]
        prelogin_json = json.loads(prelogin_json)

        # Second, we request login.php to request for a authenticate ticket
        login = self.LOGIN_PARAMETER
        login['su'] = username_encoded
        login['servertime'] = prelogin_json['servertime']
        login['nonce'] = prelogin_json['nonce']
        login['rsakv'] = prelogin_json['rsakv']

        # One more thing, we need to encrypt the password with extra token
        # using RSA-1024 public key which the server has sent us.
        rsa_pubkey_bignum = int(prelogin_json['pubkey'], 16)  # the public key is a big number in Hex
        rsa_pubkey = rsa.PublicKey(rsa_pubkey_bignum, 65537)  # RFC requires e == 65537 for RSA algorithm

        plain_msg = "%s\t%s\n%s" % (prelogin_json['servertime'], prelogin_json['nonce'], self._password)
        plain_msg = plain_msg.encode('UTF-8')  # to byte string
        cipher_msg = rsa.encrypt(plain_msg, rsa_pubkey)
        cipher_msg = base64.b16encode(cipher_msg)  # to Hex

        login['sp'] = cipher_msg

        curl = _Curl()
        try:
            login_result = curl.post(self.LOGIN_URL % "ssologin.js(v1.4.15)", login)
        except pycurl.error:
            raise NetworkError

        # the result is a JSON string
        # if success, Sina will give us a ticket for this authorized session
        login_json = json.loads(login_result)
        if "ticket" not in login_json:
            raise AuthorizeFailed(str(login_json))

        oauth2 = self.OAUTH2_PARAMETER
        oauth2['ticket'] = login_json['ticket']  # it's what all we need
        oauth2['client_id'] = application.app_key
        oauth2['redirect_uri'] = application.redirect_uri

        curl = _Curl()
        curl.set_option(pycurl.FOLLOWLOCATION, False)  # don't follow redirect
        curl.set_option(pycurl.REFERER, self.AUTHORIZE_URL)  # required for auth
        try:
            curl.post(self.AUTHORIZE_URL, oauth2)
        except pycurl.error:
            raise NetworkError

        # After post the OAuth2 information, if success,
        # Sina will return "302 Moved Temporarily", the target is "http://redirect_uri/?code=xxxxxx",
        # xxxxxx is the authorize code.
        redirect_url = curl.get_info(pycurl.REDIRECT_URL)
        if not redirect_url:
            raise AuthorizeFailed("Invalid Application() or wrong username/password.")

        authorize_code = redirect_url.split("=")[1]
        self.authorize_code = authorize_code
        return authorize_code
Example #6
0
    def _request_authorize_code(self, application):
        # Encode the username to a URL-encoded string.
        # Then, calculate its base64, we need it later
        username_encoded = urllib.parse.quote(self._username)
        username_encoded = username_encoded.encode(
            "UTF-8")  # convert to UTF-8-encoded byte string
        username_encoded = base64.b64encode(username_encoded)

        # First, we need to request prelogin.php for some necessary parameters.
        prelogin = self.PRELOGIN_PARAMETER
        prelogin['su'] = username_encoded

        curl = _Curl()
        try:
            prelogin_result = curl.get(self.PRELOGIN_URL, prelogin)
        except pycurl.error:
            raise NetworkError

        # The result is a piece of JavaScript code, in the format of
        # sinaSSOController.preloginCallBack({json here})
        prelogin_json = prelogin_result.replace(
            "sinaSSOController.preloginCallBack(", "")[0:-1]
        prelogin_json = json.loads(prelogin_json)

        # Second, we request login.php to request for a authenticate ticket
        login = self.LOGIN_PARAMETER
        login['su'] = username_encoded
        login['servertime'] = prelogin_json['servertime']
        login['nonce'] = prelogin_json['nonce']
        login['rsakv'] = prelogin_json['rsakv']

        # One more thing, we need to encrypt the password with extra token
        # using RSA-1024 public key which the server has sent us.
        rsa_pubkey_bignum = int(prelogin_json['pubkey'],
                                16)  # the public key is a big number in Hex
        rsa_pubkey = rsa.PublicKey(
            rsa_pubkey_bignum,
            65537)  # RFC requires e == 65537 for RSA algorithm

        plain_msg = "%s\t%s\n%s" % (prelogin_json['servertime'],
                                    prelogin_json['nonce'], self._password)
        plain_msg = plain_msg.encode('UTF-8')  # to byte string
        cipher_msg = rsa.encrypt(plain_msg, rsa_pubkey)
        cipher_msg = base64.b16encode(cipher_msg)  # to Hex

        login['sp'] = cipher_msg

        curl = _Curl()
        try:
            login_result = curl.post(self.LOGIN_URL % "ssologin.js(v1.4.15)",
                                     login)
        except pycurl.error:
            raise NetworkError

        # the result is a JSON string
        # if success, Sina will give us a ticket for this authorized session
        login_json = json.loads(login_result)
        if "ticket" not in login_json:
            raise AuthorizeFailed(str(login_json))

        oauth2 = self.OAUTH2_PARAMETER
        oauth2['ticket'] = login_json['ticket']  # it's what all we need
        oauth2['client_id'] = application.app_key
        oauth2['redirect_uri'] = application.redirect_uri

        curl = _Curl()
        curl.set_option(pycurl.FOLLOWLOCATION, False)  # don't follow redirect
        curl.set_option(pycurl.REFERER,
                        self.AUTHORIZE_URL)  # required for auth
        try:
            curl.post(self.AUTHORIZE_URL, oauth2)
        except pycurl.error:
            raise NetworkError

        # After post the OAuth2 information, if success,
        # Sina will return "302 Moved Temporarily", the target is "http://redirect_uri/?code=xxxxxx",
        # xxxxxx is the authorize code.
        redirect_url = curl.get_info(pycurl.REDIRECT_URL)
        if not redirect_url:
            raise AuthorizeFailed(
                "Invalid Application() or wrong username/password.")

        authorize_code = redirect_url.split("=")[1]
        self.authorize_code = authorize_code
        return authorize_code