From python-checkins at python.org Mon Sep 5 03:36:47 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 03:36:47 +0200 (CEST) Subject: [Pypi-checkins] r968 - in trunk/pypi: . templates tools Message-ID: <3RsYZ74DwLzNgq@mail.python.org> Author: richard Date: Mon Sep 5 03:36:47 2011 New Revision: 968 Added: trunk/pypi/templates/openid_decide.pt trunk/pypi/templates/openid_notloggedin.pt trunk/pypi/tools/sql-migrate-20110905.sql Modified: trunk/pypi/pkgbase_schema.sql trunk/pypi/store.py trunk/pypi/webui.py Log: openid provider support; thanks Mark Rees Modified: trunk/pypi/pkgbase_schema.sql ============================================================================== --- trunk/pypi/pkgbase_schema.sql (original) +++ trunk/pypi/pkgbase_schema.sql Mon Sep 5 03:36:47 2011 @@ -285,5 +285,12 @@ PRIMARY KEY(name) ); +CREATE TABLE openid_whitelist +( + "name" text NOT NULL, + trust_root text NOT null, + created timestamp without time zone, + CONSTRAINT openid_whitelist__pkey PRIMARY KEY (name, trust_root) +); commit; Modified: trunk/pypi/store.py ============================================================================== --- trunk/pypi/store.py (original) +++ trunk/pypi/store.py Mon Sep 5 03:36:47 2011 @@ -1932,6 +1932,28 @@ cursor = self.get_cursor() safe_execute(cursor, 'delete from openids where id=%s', (openid,)) + def set_openid_trustedroot(self, username, trusted_root): + now = datetime.datetime.now() + cursor = self.get_cursor() + safe_execute(cursor, '''select * from openid_whitelist + where name=%s and trust_root=%s''', + (username, trusted_root)) + if not cursor.fetchone(): + safe_execute(cursor, '''insert into openid_whitelist( + name, trust_root, created) values(%s,%s,%s)''', + (username, trusted_root, now)) + + def check_openid_trustedroot(self, username, trusted_root): + """Check trusted_root is in user's whitelist""" + cursor = self.get_cursor() + safe_execute(cursor, '''select * from openid_whitelist + where name=%s and trust_root=%s''', + (username, trusted_root)) + if cursor.fetchone(): + return True + else: + return False + def log_keyrotate(self): cursor = self.get_cursor() date = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime()) Added: trunk/pypi/templates/openid_decide.pt ============================================================================== --- (empty file) +++ trunk/pypi/templates/openid_decide.pt Mon Sep 5 03:36:47 2011 @@ -0,0 +1,20 @@ + + + + + +
+

The site is asking for confirmation that + is your identity id.

+ + + +
+ +
+
+ +
+ \ No newline at end of file Added: trunk/pypi/templates/openid_notloggedin.pt ============================================================================== --- (empty file) +++ trunk/pypi/templates/openid_notloggedin.pt Mon Sep 5 03:36:47 2011 @@ -0,0 +1,11 @@ + + + + + +

You need to login to this site before trying OpenId authentication again.

+ +
+ \ No newline at end of file Added: trunk/pypi/tools/sql-migrate-20110905.sql ============================================================================== --- (empty file) +++ trunk/pypi/tools/sql-migrate-20110905.sql Mon Sep 5 03:36:47 2011 @@ -0,0 +1,8 @@ +CREATE TABLE openid_whitelist +( + "name" text NOT NULL, + trust_root text NOT null, + created timestamp without time zone, + CONSTRAINT openid_whitelist__pkey PRIMARY KEY (name, trust_root) +); +ALTER TABLE openid_whitelist OWNER TO pgs_rw; Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Mon Sep 5 03:36:47 2011 @@ -26,6 +26,12 @@ from M2Crypto import EVP, DSA urllib.URLopener.open_https = orig +# OpenId provider imports +OPENID_FILESTORE = '/tmp/openid-filestore' + +from openid.store.filestore import FileOpenIDStore +from openid.server import server as OpenIDServer + # local imports import store, config, versionpredicate, verify_filetype, rpc import MailingLogger, openid2rp, gae @@ -50,10 +56,14 @@ pass class Redirect(Exception): pass +class RedirectFound(Exception):# 302 + pass class RedirectTemporary(Exception): # 307 pass class FormError(Exception): pass +class OpenIDError(Exception): + pass class MultipleReleases(Exception): def __init__(self, releases): @@ -208,6 +218,8 @@ self.loggedin = False # was a valid cookie sent? self.usercookie = None self.failed = None # error message if initialization already produced a failure + self.op_endpoint = "%s?:action=openid_endpoint" % (self.config.url,) + self.oid_server = OpenIDServer.Server(FileOpenIDStore(OPENID_FILESTORE), op_endpoint=self.op_endpoint) # XMLRPC request or not? if self.env.get('CONTENT_TYPE') != 'text/xml': @@ -275,6 +287,10 @@ self.handler.send_response(301, 'Moved Permanently') self.handler.send_header('Location', e.args[0]) self.handler.end_headers() + except RedirectFound, e: + self.handler.send_response(302, 'Found') + self.handler.send_header('Location', e.args[0]) + self.handler.end_headers() except RedirectTemporary, e: # ask browser not to cache this redirect self.handler.send_response(307, 'Temporary Redirect') @@ -283,6 +299,9 @@ except FormError, message: message = str(message) self.fail(message, code=400, heading='Error processing form') + except OpenIDError, message: + message = str(message) + self.fail(message, code=400, heading='Error processing OpenID request') except IOError, error: # ignore broken pipe errors (client vanished on us) if error.errno != 32: raise @@ -543,7 +562,8 @@ password_reset role role_form list_classifiers login logout files file_upload show_md5 doc_upload claim openid openid_return dropid clear_auth addkey delkey lasthour json gae_file about delete_user - rss_regen'''.split(): + rss_regen openid_discovery openid_endpoint openid_decide_post + openid_user'''.split(): getattr(self, action)() else: #raise NotFound, 'Unknown action %s' % action @@ -1328,7 +1348,7 @@ 'platform bugtrack_url').split() release = {'description_html': ''} - bugtrack_url ='' + bugtrack_url ='' for column in columns: value = info[column] if not info[column]: continue @@ -1351,8 +1371,8 @@ elif column.startswith('cheesecake_'): column = column[:-3] value = self.store.get_cheesecake_index(int(value)) - elif column == 'bugtrack_url': - bugtrack_url = value + elif column == 'bugtrack_url': + bugtrack_url = value value = info[column] release[column] = value @@ -2918,3 +2938,164 @@ if p.returncode != 0: raise FormError, "Key processing failed. Please contact the administrator. Detail: "+stdout + def openid_discovery(self): + """Return an XRDS document containing an OpenID provider endpoint URL.""" + payload = ''' + + + http://specs.openid.net/auth/2.0/server + http://specs.openid.net/auth/2.0/signon + %s + + + + ''' % (self.config.url+'?:action=openid_endpoint') + self.handler.send_response(200) + self.handler.send_header("Content-type", 'application/xrds+xml') + self.handler.send_header("Content-length", str(len(payload))) + self.handler.end_headers() + self.handler.wfile.write(payload) + + def openid_user(self): + """Return an XRDS document containing an OpenID provider endpoint URL.""" + payload = ''' + + + http://specs.openid.net/auth/2.0/signon + %s + + + + ''' % (self.config.url+'?:action=openid_endpoint') + self.handler.send_response(200) + self.handler.send_header("Content-type", 'application/xrds+xml') + self.handler.send_header("Content-length", str(len(payload))) + self.handler.end_headers() + self.handler.wfile.write(payload) + + def openid_endpoint(self): + """Handle OpenID requests""" + orequest = self.oid_server.decodeRequest(self.form) + if not orequest or orequest is None: + payload='''This is an OpenID server''' + self.handler.send_response(200) + self.handler.send_header("Content-type", 'text/plain') + self.handler.send_header("Content-length", str(len(payload))) + self.handler.end_headers() + self.handler.wfile.write(payload) + return + if orequest.mode in ['checkid_immediate', 'checkid_setup']: + if self.openid_is_authorized(orequest): + return self.openid_response(orequest.answer(True)) + elif orequest.immediate: + return self.openid_response(orequest.answer(False)) + else: + self.openid_decide_page(orequest) + elif orequest.mode in ['associate', 'check_authentication']: + self.openid_response(self.oid_server.handleRequest(orequest)) + else: + raise OpenIDError, "Unknown mode: %s" % orequest.mode + + + def openid_decide_page(self, orequest): + """ + The page that asks the user if they really want to trust this trust_root + If they are NOT logged intp PyPI, show the landing page so the user + understands why it has failed and they need to login to PyPI before + attempting again. This is done rather than presenting PyPI login page + to reduce chance of phishing. + """ + if not self.authenticated: + self.write_template('openid_notloggedin.pt', + title="OpenId landing page") + return + + if orequest.identity == "http://specs.openid.net/auth/2.0/identifier_select": + pending_id = self.openid_user_url() + else: + pending_id = orequest.identity + + orequest_args=orequest.message.toPostArgs() + del orequest_args[':action'] + # They are logged in - ask if they want to trust this root + self.write_template('openid_decide.pt', title="Trust this site?", + url_path="%s/?:action=openid_decide_post" % self.config.url, + orequest=orequest_args, + mode=orequest.mode, + identity=self.username, + return_to=orequest.return_to, + trust_root=orequest.trust_root, + pending_id = pending_id) + + def openid_decide_post(self): + """Handle POST request from decide form""" + if self.env['REQUEST_METHOD'] != "POST": + raise OpenIDError, "OpenID request must be a POST" + + from openid.message import Message + message = Message.fromPostArgs(self.form) + orequest = OpenIDServer.CheckIDRequest.fromMessage(message, self.oid_server.op_endpoint) + + if self.form.has_key('allow'): + answer = orequest.answer(True, + identity=self.openid_user_url()) + return self.openid_response(answer) + elif self.form.has_key('allow_always'): + answer = orequest.answer(True, + identity=self.openid_user_url()) + self.store.set_openid_trustedroot(self.username, orequest.trust_root) + self.store.commit() + return self.openid_response(answer) + elif self.form.has_key('no_thanks'): + answer = orequest.answer(False) + return self.openid_response(answer) + else: + raise OpenIDError, "OpenID post request failure" + + def openid_response(self, oresponse): + """Convert a webresponse from the OpenID library into a + WebUI http response""" + webresponse = self.oid_server.encodeResponse(oresponse) + if webresponse.code == 301: + raise Redirect, str(webresponse.headers['location']) + elif webresponse.code == 302: + raise RedirectFound, str(webresponse.headers['location']) + + self.handler.send_response(webresponse.code) + for key, value in webresponse.headers.items(): + self.handler.send_header(key, str(value)) + self.handler.end_headers() + self.handler.wfile.write(webresponse.body) + + def openid_is_authorized(self, orequest): + """ + This should check that they own the given identity, + and that the trust_root is in their whitelist of trusted sites. + """ + identity = orequest.identity + if not self.authenticated: + return False + if identity == 'http://specs.openid.net/auth/2.0/identifier_select': + return False + qs = urlparse.urlparse(identity).query + if urlparse.parse_qs(qs).get("username",[None])[0] == self.username: + if self.store.check_openid_trustedroot(self.username, + orequest.trust_root): + return True + else: + return False + # identity is not owned by user so decline the request + answer = orequest.answer(False) + self.openid_response(answer) + + def openid_user_url(self): + if self.authenticated: + return "%s?:action=openid_user&username=%s" % (self.config.url, + self.username) + else: + return None + From python-checkins at python.org Mon Sep 5 04:15:18 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 04:15:18 +0200 (CEST) Subject: [Pypi-checkins] r969 - trunk/pypi Message-ID: <3RsZQZ52KrzNhD@mail.python.org> Author: richard Date: Mon Sep 5 04:15:12 2011 New Revision: 969 Modified: trunk/pypi/webui.py Log: simplification and also remove double response Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Mon Sep 5 04:15:12 2011 @@ -3000,7 +3000,6 @@ else: raise OpenIDError, "Unknown mode: %s" % orequest.mode - def openid_decide_page(self, orequest): """ The page that asks the user if they really want to trust this trust_root @@ -3082,16 +3081,12 @@ if identity == 'http://specs.openid.net/auth/2.0/identifier_select': return False qs = urlparse.urlparse(identity).query - if urlparse.parse_qs(qs).get("username",[None])[0] == self.username: - if self.store.check_openid_trustedroot(self.username, - orequest.trust_root): - return True - else: - return False - # identity is not owned by user so decline the request - answer = orequest.answer(False) - self.openid_response(answer) - + if urlparse.parse_qs(qs).get("username",[None])[0] != self.username: + # identity is not owned by user so decline the request + False + + return self.store.check_openid_trustedroot(self.username, orequest.trust_root) + def openid_user_url(self): if self.authenticated: return "%s?:action=openid_user&username=%s" % (self.config.url, From python-checkins at python.org Mon Sep 5 05:22:15 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 05:22:15 +0200 (CEST) Subject: [Pypi-checkins] r970 - trunk/pypi/tools Message-ID: <3Rsbvq2w3fzNh2@mail.python.org> Author: richard Date: Mon Sep 5 05:22:15 2011 New Revision: 970 Modified: trunk/pypi/tools/sql-migrate-20110905.sql Log: sorry, thought I'd removed that before commit Modified: trunk/pypi/tools/sql-migrate-20110905.sql ============================================================================== --- trunk/pypi/tools/sql-migrate-20110905.sql (original) +++ trunk/pypi/tools/sql-migrate-20110905.sql Mon Sep 5 05:22:15 2011 @@ -5,4 +5,3 @@ created timestamp without time zone, CONSTRAINT openid_whitelist__pkey PRIMARY KEY (name, trust_root) ); -ALTER TABLE openid_whitelist OWNER TO pgs_rw; From python-checkins at python.org Mon Sep 5 05:50:11 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 05:50:11 +0200 (CEST) Subject: [Pypi-checkins] r971 - trunk/pypi Message-ID: <3RscX31MD6zNhs@mail.python.org> Author: richard Date: Mon Sep 5 05:50:11 2011 New Revision: 971 Modified: trunk/pypi/webui.py Log: making the openid URLs nicer Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Mon Sep 5 05:50:11 2011 @@ -463,6 +463,14 @@ return self.mirrors() if script_name == '/daytime': return self.daytime() + if script_name == '/id': + action = 'openid_discovery' + elif script_name.startswith('/id/'): + # the username argument is ignored... + action = 'openid_user' + else: + action = '' + # see if the user has provided a username/password auth = self.env.get('HTTP_CGI_AUTHORIZATION', '').strip() if auth: @@ -521,6 +529,9 @@ # now handle the request path = self.env.get('PATH_INFO', '') + if action: + # we've already been set an action + pass if self.form.has_key(':action'): action = self.form[':action'] if isinstance(action, list): From python-checkins at python.org Mon Sep 5 05:57:48 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 05:57:48 +0200 (CEST) Subject: [Pypi-checkins] r972 - trunk/pypi Message-ID: <3Rschr6ZMPzNhL@mail.python.org> Author: richard Date: Mon Sep 5 05:57:48 2011 New Revision: 972 Modified: trunk/pypi/webui.py Log: fix action subs stuff for openid, also fix openid user url config Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Mon Sep 5 05:57:48 2011 @@ -532,7 +532,7 @@ if action: # we've already been set an action pass - if self.form.has_key(':action'): + elif self.form.has_key(':action'): action = self.form[':action'] if isinstance(action, list): raise RuntimeError("Multiple actions: %r" % action) @@ -3051,12 +3051,10 @@ orequest = OpenIDServer.CheckIDRequest.fromMessage(message, self.oid_server.op_endpoint) if self.form.has_key('allow'): - answer = orequest.answer(True, - identity=self.openid_user_url()) + answer = orequest.answer(True, identity=self.openid_user_url()) return self.openid_response(answer) elif self.form.has_key('allow_always'): - answer = orequest.answer(True, - identity=self.openid_user_url()) + answer = orequest.answer(True, identity=self.openid_user_url()) self.store.set_openid_trustedroot(self.username, orequest.trust_root) self.store.commit() return self.openid_response(answer) @@ -3100,8 +3098,7 @@ def openid_user_url(self): if self.authenticated: - return "%s?:action=openid_user&username=%s" % (self.config.url, - self.username) + return "%s/%s" % (self.config.openid_url, self.username) else: return None From python-checkins at python.org Mon Sep 5 05:58:55 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 05:58:55 +0200 (CEST) Subject: [Pypi-checkins] r973 - trunk/pypi Message-ID: <3Rsck70CzWzNhL@mail.python.org> Author: richard Date: Mon Sep 5 05:58:54 2011 New Revision: 973 Modified: trunk/pypi/config.py Log: add here too Modified: trunk/pypi/config.py ============================================================================== --- trunk/pypi/config.py (original) +++ trunk/pypi/config.py Mon Sep 5 05:58:54 2011 @@ -26,6 +26,7 @@ self.adminemail = c.get('webui', 'adminemail') self.replyto = c.get('webui', 'replyto') self.url = c.get('webui', 'url') + self.openid_url = c.get('webui', 'openid_url') self.orig_pydotorg = self.pydotorg = c.get('webui', 'pydotorg') self.simple_script = c.get('webui', 'simple_script') self.files_url = c.get('webui', 'files_url') From python-checkins at python.org Mon Sep 5 06:00:04 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 06:00:04 +0200 (CEST) Subject: [Pypi-checkins] r974 - trunk/pypi/templates Message-ID: <3RsclS5zztzNhL@mail.python.org> Author: richard Date: Mon Sep 5 06:00:04 2011 New Revision: 974 Modified: trunk/pypi/templates/openid_decide.pt Log: better Modified: trunk/pypi/templates/openid_decide.pt ============================================================================== --- trunk/pypi/templates/openid_decide.pt (original) +++ trunk/pypi/templates/openid_decide.pt Mon Sep 5 06:00:04 2011 @@ -6,8 +6,8 @@
-

The site is asking for confirmation that - is your identity id.

+

The site is asking for confirmation that + is your identity.

@@ -17,4 +17,4 @@
- \ No newline at end of file + From python-checkins at python.org Mon Sep 5 06:25:10 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 06:25:10 +0200 (CEST) Subject: [Pypi-checkins] r975 - trunk/pypi Message-ID: <3RsdJQ6qw9zNg9@mail.python.org> Author: richard Date: Mon Sep 5 06:25:10 2011 New Revision: 975 Modified: trunk/pypi/webui.py Log: fix identity extraction based on remapped url Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Mon Sep 5 06:25:10 2011 @@ -2949,6 +2949,9 @@ if p.returncode != 0: raise FormError, "Key processing failed. Please contact the administrator. Detail: "+stdout + # + # OpenID Provider + # def openid_discovery(self): """Return an XRDS document containing an OpenID provider endpoint URL.""" payload = ''' Author: richard Date: Mon Sep 5 06:27:44 2011 New Revision: 976 Modified: trunk/pypi/webui.py Log: duh Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Mon Sep 5 06:27:44 2011 @@ -1694,7 +1694,7 @@ submission. ''' if self.form.get('CSRFToken') != self.store.get_token(self.username): - self.FormError, "Form Failure; reset form submission" + raise FormError, "Form Failure; reset form submission" def submit_pkg_info(self): ''' Handle the submission of distro metadata as a PKG-INFO file. From python-checkins at python.org Mon Sep 5 07:39:14 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 07:39:14 +0200 (CEST) Subject: [Pypi-checkins] r977 - trunk/pypi Message-ID: <3Rsfxt2KCBzNbG@mail.python.org> Author: richard Date: Mon Sep 5 07:39:14 2011 New Revision: 977 Modified: trunk/pypi/webui.py Log: argh the /id* URLs are not authenticated so break... must have /pypi URLs... reverting to further test Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Mon Sep 5 07:39:14 2011 @@ -218,8 +218,8 @@ self.loggedin = False # was a valid cookie sent? self.usercookie = None self.failed = None # error message if initialization already produced a failure - self.op_endpoint = "%s?:action=openid_endpoint" % (self.config.url,) - self.oid_server = OpenIDServer.Server(FileOpenIDStore(OPENID_FILESTORE), op_endpoint=self.op_endpoint) + op_endpoint = "%s?:action=openid_endpoint" % (self.config.url,) + self.oid_server = OpenIDServer.Server(FileOpenIDStore(OPENID_FILESTORE), op_endpoint=op_endpoint) # XMLRPC request or not? if self.env.get('CONTENT_TYPE') != 'text/xml': @@ -463,13 +463,6 @@ return self.mirrors() if script_name == '/daytime': return self.daytime() - if script_name == '/id': - action = 'openid_discovery' - elif script_name.startswith('/id/'): - # the username argument is ignored... - action = 'openid_user' - else: - action = '' # see if the user has provided a username/password auth = self.env.get('HTTP_CGI_AUTHORIZATION', '').strip() @@ -529,10 +522,7 @@ # now handle the request path = self.env.get('PATH_INFO', '') - if action: - # we've already been set an action - pass - elif self.form.has_key(':action'): + if self.form.has_key(':action'): action = self.form[':action'] if isinstance(action, list): raise RuntimeError("Multiple actions: %r" % action) @@ -1976,7 +1966,8 @@ raise Unauthorised, \ "You must be identified to edit package information" - self.csrf_check() + # this is used to render the form as well as edit it... UGH + #self.csrf_check() name = self.form['name'] @@ -3050,6 +3041,7 @@ raise OpenIDError, "OpenID request must be a POST" from openid.message import Message + del self.form[':action'] message = Message.fromPostArgs(self.form) orequest = OpenIDServer.CheckIDRequest.fromMessage(message, self.oid_server.op_endpoint) @@ -3092,7 +3084,8 @@ return False if identity == 'http://specs.openid.net/auth/2.0/identifier_select': return False - username = urlparse.urlparse(identity).path.split('/')[-1] + qs = urlparse.urlparse(identity).query + username = urlparse.parse_qs(qs).get("username",[None])[0] if username != self.username: # identity is not owned by user so decline the request False @@ -3101,7 +3094,7 @@ def openid_user_url(self): if self.authenticated: - return "%s/%s" % (self.config.openid_url, self.username) + return "%s?:action=openid_user&username=%s" % (self.config.url, self.username) else: return None - + From python-checkins at python.org Mon Sep 5 07:52:52 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 07:52:52 +0200 (CEST) Subject: [Pypi-checkins] r978 - trunk/pypi Message-ID: <3RsgFc6MFwzNYw@mail.python.org> Author: richard Date: Mon Sep 5 07:52:52 2011 New Revision: 978 Modified: trunk/pypi/webui.py Log: protocol tweak undo Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Mon Sep 5 07:52:52 2011 @@ -3086,11 +3086,14 @@ return False qs = urlparse.urlparse(identity).query username = urlparse.parse_qs(qs).get("username",[None])[0] - if username != self.username: - # identity is not owned by user so decline the request - False - - return self.store.check_openid_trustedroot(self.username, orequest.trust_root) + if username == self.username: + if self.store.check_openid_trustedroot(self.username, orequest.trust_root): + return True + else: + return False + # identity is not owned by user so decline the request + answer = orequest.answer(False) + self.openid_response(answer) def openid_user_url(self): if self.authenticated: From python-checkins at python.org Mon Sep 5 08:07:19 2011 From: python-checkins at python.org (richard) Date: Mon, 5 Sep 2011 08:07:19 +0200 (CEST) Subject: [Pypi-checkins] r979 - trunk/pypi Message-ID: <3RsgZH01KTzNh6@mail.python.org> Author: richard Date: Mon Sep 5 08:07:18 2011 New Revision: 979 Modified: trunk/pypi/config.py Log: remove unnecessary new config Modified: trunk/pypi/config.py ============================================================================== --- trunk/pypi/config.py (original) +++ trunk/pypi/config.py Mon Sep 5 08:07:18 2011 @@ -26,7 +26,6 @@ self.adminemail = c.get('webui', 'adminemail') self.replyto = c.get('webui', 'replyto') self.url = c.get('webui', 'url') - self.openid_url = c.get('webui', 'openid_url') self.orig_pydotorg = self.pydotorg = c.get('webui', 'pydotorg') self.simple_script = c.get('webui', 'simple_script') self.files_url = c.get('webui', 'files_url') From python-checkins at python.org Thu Sep 15 22:48:32 2011 From: python-checkins at python.org (martin.von.loewis) Date: Thu, 15 Sep 2011 22:48:32 +0200 (CEST) Subject: [Pypi-checkins] r980 - trunk/pypi Message-ID: <3S0BfS2XHHzNmv@mail.python.org> Author: martin.von.loewis Date: Thu Sep 15 22:48:31 2011 New Revision: 980 Modified: trunk/pypi/config.py trunk/pypi/standalone.py trunk/pypi/webui.py Log: Enable /id URLs. Modified: trunk/pypi/config.py ============================================================================== --- trunk/pypi/config.py (original) +++ trunk/pypi/config.py Thu Sep 15 22:48:31 2011 @@ -1,4 +1,5 @@ import ConfigParser +from urlparse import urlsplit, urlunsplit class Config: ''' Read in the config and set up the vars with the correct type. @@ -26,6 +27,7 @@ self.adminemail = c.get('webui', 'adminemail') self.replyto = c.get('webui', 'replyto') self.url = c.get('webui', 'url') + self.scheme_host = urlunsplit(urlsplit(self.url)[:2]+('','','')) self.orig_pydotorg = self.pydotorg = c.get('webui', 'pydotorg') self.simple_script = c.get('webui', 'simple_script') self.files_url = c.get('webui', 'files_url') Modified: trunk/pypi/standalone.py ============================================================================== --- trunk/pypi/standalone.py (original) +++ trunk/pypi/standalone.py Thu Sep 15 22:48:31 2011 @@ -13,7 +13,8 @@ self.send_response(301) self.send_header('Location', '/pypi') return - for scriptname in ('/mirrors', '/simple', '/pypi', '/serversig', '/daytime'): + for scriptname in ('/mirrors', '/simple', '/pypi', + '/serversig', '/daytime', '/id'): if self.path.startswith(scriptname): rest = self.path[len(scriptname):] break @@ -119,7 +120,7 @@ elif opt in ('-p', '--port'): port = int(val) if port: - httpd = BaseHTTPServer.HTTPServer(('',8000), RequestHandler) + httpd = BaseHTTPServer.HTTPServer(('',port), RequestHandler) httpd.serve_forever() else: StdinoutHandler(remote_user) Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Thu Sep 15 22:48:31 2011 @@ -463,6 +463,8 @@ return self.mirrors() if script_name == '/daytime': return self.daytime() + if script_name == '/id': + return self.run_id() # see if the user has provided a username/password auth = self.env.get('HTTP_CGI_AUTHORIZATION', '').strip() @@ -563,8 +565,7 @@ password_reset role role_form list_classifiers login logout files file_upload show_md5 doc_upload claim openid openid_return dropid clear_auth addkey delkey lasthour json gae_file about delete_user - rss_regen openid_discovery openid_endpoint openid_decide_post - openid_user'''.split(): + rss_regen openid_endpoint openid_decide_post'''.split(): getattr(self, action)() else: #raise NotFound, 'Unknown action %s' % action @@ -710,6 +711,13 @@ self.handler.end_headers() self.wfile.write(sig) + def run_id(self): + path = self.env.get('PATH_INFO') + if not path: + return self.openid_discovery() + else: + return self.openid_user(path) + def home(self, nav_current='home'): self.write_template('home.pt', title='PyPI - the Python Package Index') @@ -2963,7 +2971,7 @@ self.handler.end_headers() self.handler.wfile.write(payload) - def openid_user(self): + def openid_user(self, user): """Return an XRDS document containing an OpenID provider endpoint URL.""" payload = ''' Author: martin.von.loewis Date: Thu Sep 15 22:49:06 2011 New Revision: 981 Modified: trunk/pypi/templates/openid_notloggedin.pt Log: Elaborate rationale for not logging user in directly. Modified: trunk/pypi/templates/openid_notloggedin.pt ============================================================================== --- trunk/pypi/templates/openid_notloggedin.pt (original) +++ trunk/pypi/templates/openid_notloggedin.pt Thu Sep 15 22:49:06 2011 @@ -5,7 +5,12 @@ metal:use-macro="standard_template/macros/page"> -

You need to login to this site before trying OpenId authentication again.

+

If you want to use your PyPI credentials to log into + another site, you need to log into PyPI first. If logging + into some other site ever brings up a PyPI password window, + it probably is a phishing attempt; don't enter your password. + If you follow the login link to the right, make sure it really + belongs to the Python Package Index.

\ No newline at end of file From python-checkins at python.org Tue Sep 27 08:39:57 2011 From: python-checkins at python.org (richard) Date: Tue, 27 Sep 2011 08:39:57 +0200 (CEST) Subject: [Pypi-checkins] r982 - trunk/pypi Message-ID: <3S7CFn4kwczNwv@mail.python.org> Author: richard Date: Tue Sep 27 08:39:57 2011 New Revision: 982 Modified: trunk/pypi/webui.py Log: don't double-escape this information Modified: trunk/pypi/webui.py ============================================================================== --- trunk/pypi/webui.py (original) +++ trunk/pypi/webui.py Tue Sep 27 08:39:57 2011 @@ -1391,7 +1391,7 @@ def values(col): l = self.store.get_release_relationships(name, version, col) - return [ cgi.escape(x['specifier']) for x in l] + return [x['specifier'] for x in l] categories = [] is_py3k = False