def _http_opener(self, req, headers=None, auth=True): """ Configure a HTTP opener for API operations @param req: the Request @param headers: array of HTTP headers @param auth: False - do not add Authorization "Basic" - add Auth header using username+password "Token" - add Auth header using access token any tru-ish value - add a 401-handler with username+password @returns: OpenerDirector instance """ # Configure opener headers addheaders = [] if headers: addheaders.extend(headers) # Configure opener handlers handlers = [] # Proxy handling proxy = self.proxy if proxy and self.use_proxy: protocol = req.get_type() if PY2 else req.type proxy_handler = urllib2.ProxyHandler({protocol: proxy}) handlers.append(proxy_handler) # Authentication handling username = self.username password = self.password if auth == "Basic": if username and password: import base64 base64string = base64.b64encode( ('%s:%s' % (username, password)).encode("utf-8")) addheaders.append( ("Authorization", "Basic %s" % s3_str(base64string))) elif auth == "Token": token = self.access_token token_type = self.token_type or "Bearer" expiry_date = self.token_expiry_date if not token or \ expiry_date and expiry_date <= current.request.utcnow: try: token = self.get_access_token() except NotImplementedError: token = None if token: addheaders.append( ("Authorization", "%s %s" % (token_type, token))) else: # No pre-emptive auth pass if auth and username and password: # Add a HTTP-401-handler as fallback in case pre-emptive auth fails passwd_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() passwd_manager.add_password( realm=None, uri=req.get_full_url(), user=username, passwd=password, ) auth_handler = urllib2.HTTPBasicAuthHandler(passwd_manager) handlers.append(auth_handler) # Create the opener and add headers opener = urllib2.build_opener(*handlers) if addheaders: opener.addheaders = addheaders return opener
def _send_request(self, method="GET", **args): repository = self.repository config = repository.config # Authentication args = Storage(args) if hasattr(self, "PHPSESSID") and self.PHPSESSID: args["PHPSESSID"] = self.PHPSESSID if hasattr(self, "api_key") and self.api_key: args["api_key"] = self.api_key if repository.site_key: args["key"] = repository.site_key # Create the request url = repository.url + "?" + urlencode(args) req = urllib2.Request(url=url) handlers = [] # Proxy handling proxy = repository.proxy or config.proxy or None if proxy: # Figure out the protocol from the URL url_split = url.split("://", 1) if len(url_split) == 2: protocol = url_split[0] else: protocol = "http" current.log.debug("using proxy=%s", proxy) proxy_handler = urllib2.ProxyHandler({protocol: proxy}) handlers.append(proxy_handler) # Install all handlers if handlers: opener = urllib2.build_opener(*handlers) urllib2.install_opener(opener) # Execute the request response = None message = None try: if method == "POST": f = urlopen(req, data="") else: f = urlopen(req) except HTTPError as e: message = "HTTP %s: %s" % (e.code, e.reason) else: # Parse the response tree = current.xml.parse(f) root = tree.getroot() is_error = root.xpath("//ResultSet[1]/Result[1]/is_error") if len(is_error) and int(is_error[0].text): error = root.xpath("//ResultSet[1]/Result[1]/error_message") if len(error): message = error[0].text else: message = "Unknown error" else: response = tree return response, message
def _send_request(self, method="GET", path=None, args=None, data=None, auth=False): """ Send a request to the CommandBridge API @param method: the HTTP method @param path: the path relative to the repository URL @param data: the data to send @param auth: this is an authorization request """ xml = current.xml repository = self.repository # Request URL url = repository.url.rstrip("/") if path: url = "/".join((url, path.lstrip("/"))) if args: url = "?".join((url, urlencode(args))) # Create the request req = urllib2.Request(url=url) handlers = [] site_key = repository.site_key if not site_key: message = "CommandBridge Authorization failed: no access token (site key)" current.log.error(message) return None, message req.add_header("Authorization-Token", "%s" % site_key) # Request Data request_data = data if data is not None else "" if request_data: req.add_header("Content-Type", "application/xml") # Indicate that we expect XML response req.add_header("Accept", "application/xml") # Proxy handling config = repository.config proxy = repository.proxy or config.proxy or None if proxy: current.log.debug("using proxy=%s" % proxy) proxy_handler = urllib2.ProxyHandler({"https": proxy}) handlers.append(proxy_handler) # Install all handlers if handlers: opener = urllib2.build_opener(*handlers) urllib2.install_opener(opener) # Execute the request response = None message = None try: if method == "POST": f = urlopen(req, data=request_data) else: f = urlopen(req) except HTTPError as e: message = "HTTP %s: %s" % (e.code, e.reason) # More details may be in the response body error_response = xml.parse(e) if error_response: error_messages = error_response.findall("Message") details = " / ".join(item.text for item in error_messages) message = "%s (%s)" % (message, details) else: response = xml.parse(f) if response is None: if method == "POST": response = True elif xml.error: message = xml.error return response, message
def _send_request(self, method="GET", path=None, args=None, data=None, auth=False): """ Send a request to the Wrike API @param method: the HTTP method @param path: the path relative to the repository URL @param data: the data to send @param auth: this is an authorization request """ repository = self.repository # Request URL api = "oauth2/token" if auth else "api/v3" url = "/".join((repository.url.rstrip("/"), api)) if path: url = "/".join((url, path.lstrip("/"))) if args: url = "?".join((url, urlencode(args))) # Create the request req = urllib2.Request(url=url) handlers = [] if not auth: # Install access token header access_token = self.access_token if not access_token: message = "Authorization failed: no access token" current.log.error(message) return None, message req.add_header("Authorization", "%s %s" % (self.token_type, access_token)) # JSONify request data request_data = json.dumps(data) if data else "" if request_data: req.add_header("Content-Type", "application/json") else: # URL-encode request data for auth request_data = urlencode(data) if data else "" # Indicate that we expect JSON response req.add_header("Accept", "application/json") # Proxy handling config = repository.config proxy = repository.proxy or config.proxy or None if proxy: current.log.debug("using proxy=%s" % proxy) proxy_handler = urllib2.ProxyHandler({"https": proxy}) handlers.append(proxy_handler) # Install all handlers if handlers: opener = urllib2.build_opener(*handlers) urllib2.install_opener(opener) # Execute the request response = None message = None try: if method == "POST": f = urlopen(req, data=request_data) else: f = urlopen(req) except HTTPError as e: message = "HTTP %s: %s" % (e.code, e.reason) else: # Parse the response try: response = json.load(f) except ValueError as e: message = sys.exc_info()[1] return response, message
def _http_opener(self, url, headers=None, auth=True): """ Configure a HTTP opener for sync operations @param url: the target URL """ repository = self.repository config = repository.config # Configure opener headers addheaders = [] if headers: addheaders.extend(headers) # Configure opener handlers handlers = [] # Proxy handling proxy = repository.proxy or config.proxy or None if proxy: # Figure out the protocol from the URL url_split = url.split("://", 1) if len(url_split) == 2: protocol = url_split[0] else: protocol = "http" proxy_handler = urllib2.ProxyHandler({protocol: proxy}) handlers.append(proxy_handler) # Authentication handling if auth: username = repository.username password = repository.password if username and password: # Add a 401 handler (in case Auth header is not accepted) passwd_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() passwd_manager.add_password( realm=None, uri=url, user=username, passwd=password, ) auth_handler = urllib2.HTTPBasicAuthHandler(passwd_manager) handlers.append(auth_handler) # Create the opener opener = urllib2.build_opener(*handlers) if auth and username and password: # Send credentials unsolicitedly to force login - otherwise # the request would be treated as anonymous if login is not # required (i.e. no 401 triggered), but we want to login in # any case: import base64 base64string = base64.encodestring('%s:%s' % (username, password))[:-1] addheaders.append(("Authorization", "Basic %s" % base64string)) if addheaders: opener.addheaders = addheaders return opener