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

Proposed by Simon Fels on 2017-03-03
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 2017-03-03 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 on 2017-03-03

Add missing import for base64 package

Unmerged revisions

134. By Simon Fels on 2017-03-03

Add missing import for base64 package

133. By Simon Fels on 2017-03-03

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

Subscribers

People subscribed via source and target branches

to all changes: