Merge lp:~morphis/jenkins-launchpad-plugin/preemptive-auth-handler into lp:jenkins-launchpad-plugin

Proposed by Simon Fels
Status: Needs review
Proposed branch: lp:~morphis/jenkins-launchpad-plugin/preemptive-auth-handler
Merge into: lp:jenkins-launchpad-plugin
Diff against target: 40 lines (+23/-2)
1 file modified
jlp/jsonjenkins.py (+23/-2)
To merge this branch: bzr merge lp:~morphis/jenkins-launchpad-plugin/preemptive-auth-handler
Reviewer Review Type Date Requested Status
Jenkaas Hackers Pending
Review via email: mp+318871@code.launchpad.net

Commit message

Use PreemptiveBasicAuthHandler authentication handler to make sure we
sent authentication headers with every request and not as urllib2 would
do when we receive a HTTP 403 error code.

Description of the change

Jenkins doesn't return a 401 HTTP error code to tell the client to retry with authentication details as urllib2 by default expects but sents a 403 error code straight away. See https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients and https://stackoverflow.com/questions/16907684/fetching-a-url-from-a-basic-auth-protected-jenkins-server-with-urllib2 for details on this.

To post a comment you must log in.
134. By Simon Fels

Add missing import for base64 package

Unmerged revisions

134. By Simon Fels

Add missing import for base64 package

133. By Simon Fels

Use PreemptiveBasicAuthHandler authentication handler to make sure we
sent authentication headers with every request and not as urllib2 would
do when we receive a HTTP 403 error code.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'jlp/jsonjenkins.py'
--- jlp/jsonjenkins.py 2015-12-14 15:31:54 +0000
+++ jlp/jsonjenkins.py 2017-03-03 07:10:17 +0000
@@ -1,6 +1,27 @@
1import json1import json
2import urllib22import urllib2
33import base64
4
5# Taken from https://stackoverflow.com/questions/16907684/
6class PreemptiveBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
7 '''Preemptive basic auth.
8
9 Instead of waiting for a 403 to then retry with the credentials,
10 send the credentials if the url is handled by the password manager.
11 Note: please use realm=None when calling add_password.'''
12 def http_request(self, req):
13 url = req.get_full_url()
14 realm = None
15 # this is very similar to the code from retry_http_basic_auth()
16 # but returns a request object.
17 user, pw = self.passwd.find_user_password(realm, url)
18 if pw:
19 raw = "%s:%s" % (user, pw)
20 auth = 'Basic %s' % base64.b64encode(raw).strip()
21 req.add_unredirected_header(self.auth_header, auth)
22 return req
23
24 https_request = http_request
425
5class JSONJenkins():26class JSONJenkins():
6 urllib_opener = None27 urllib_opener = None
@@ -11,7 +32,7 @@
1132
12 passman = urllib2.HTTPPasswordMgrWithDefaultRealm()33 passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
13 passman.add_password(None, jenkins_url, username, password)34 passman.add_password(None, jenkins_url, username, password)
14 authhandler = urllib2.HTTPBasicAuthHandler(passman)35 authhandler = PreemptiveBasicAuthHandler(passman)
15 self.urllib_opener = urllib2.build_opener(authhandler)36 self.urllib_opener = urllib2.build_opener(authhandler)
16 urllib2.install_opener(self.urllib_opener)37 urllib2.install_opener(self.urllib_opener)
1738

Subscribers

People subscribed via source and target branches

to all changes: