Skip to content

Instantly share code, notes, and snippets.

@Jc2k
Created June 8, 2012 00:46
Show Gist options
  • Save Jc2k/2892709 to your computer and use it in GitHub Desktop.
Save Jc2k/2892709 to your computer and use it in GitHub Desktop.
isotoma.buildout.basicauth
class Unauthorized(Exception):
def __init__(self, code):
self.code = code
class BaseAdaptor(object):
retries = 10
adapts = None
param = "url"
def __init__(self, credentials):
self.credentials = credentials
def raise_buildout_error(self, message):
raise UserError(message)
def raise_http_error(self, code):
raise NotImplementedError
def call_wrapped(self, *args, **kwargs):
raise NotImplementedError
def call(self, *args, **kwargs):
for i in range(self.retries):
try:
return self.call_wrapped(*args, **kwargs)
except Unauthorized:
raise
except as e:
logger.critical('Attempt %d failed, retrying' % i)
logger.debug(e)
def __call__(self, *args, **kwargs):
# In general, the url we want to download is the first parameter - but this lets us be flexible
params, args, kwargs = inspect.getargspec(self.adapts)
if not self.param in params:
self.raise_buildout_error("Your buildout is really broken")
paramidx = params.find(self.param)
url = args[paramidx]
logger.debug('Downloading URL %s' % strip_auth(url))
for username, password, cache in self.credentials.search(url):
new_url = _inject_credentials(url, username, password)
try:
args[paramidx] = new_url
res = self.call(*args, **kwargs)
except Unauthorized as e:
logger.critical('Could not authenticate %s. (%d)' % (url, e.code))
self.raise_unauthorized(e.code)
except:
logger.critical('Cannot fetch %s (%r)' % (url, code))
logger.debug(e)
raise
else:
self.credentials.success(url, username, password, cache)
return res
self.raise_unauthorized(401)
class OpenWithAuth(BaseAdaptor):
adapts = setuptools.package_index.open_with_auth
def raise_http_error(self, code):
raise HTTPError(url, code, "HTTP error", {}, None)
def call(self, *args, **kwargs):
try:
self.adapts(*args, **kwargs):
except HTTPError as e:
if e.code in (401, 403):
raise Unauthorized(e.code)
raise
class UrlRetrieve(BaseAdaptor):
adapts = urllib.urlretrieve
def raise_http_error(self, code):
raise IOError('http error', code, "HTTP error", {})
def call(self, *args, **kwargs):
try:
self.adapts(*args, **kwargs):
except IOError as e:
if e.args[0] == "http error" and e.args[1] in (401, 403):
raise Unauthorized(a.args[1])
raise
setuptools.package_index.open_with_auth = OpenWithAuth(credentials)
urllib.urlretrieve = UrlRetrieve(credentials)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment